From Equations Require Import Equations.

Require Import List Program.Syntax Arith Lia.

Equations div2 (n : nat) : nat :=
  div2 0 := 0;
  div2 1 := 0;
  div2 (S (S n)) := S (div2 n).

Lemma div2_le : x, div2 xx.
Proof. intros x. funelim (div2 x); auto with arith. Defined.

Transparent div2.
Equations log_iter (fn : natnat) (n : nat) : nat :=
  log_iter fn 0 := 0;
  log_iter fn 1 := 0;
  log_iter fn n := S (fn (div2 n)).
Transparent log_iter.
Equations iter {A} (n : nat) (f : AA) : AA :=
  iter 0 f x := x;
  iter (S n) f x := f (iter n f x).
Transparent iter.
Definition f_terminates {A} {B : AType} (fn : ( x : A, B x) → ( x : A, B x)) :=
   x : A, { y : B x | ( p, k, p < k g : x : A, B x,
                                  iter k fn g x = y) }.

Lemma log_terminates : f_terminates log_iter.
Proof.
  intro.
  Subterm.rec_wf_rel IH x lt.
  destruct x. 0. 0. intros. inversion H. simpl. reflexivity.
  simpl. reflexivity.
  destruct x. 0. 0. intros. inversion H; simpl; reflexivity.
  specialize (IH (div2 (S (S x)))). forward IH. simpl. auto using div2_le with arith.
  destruct IH as [y Hy].
   (S y). destruct Hy as [p Hp]. (S p). intros.
  destruct k. inversion H.
  simpl. rewrite Hp. auto. auto with arith.
Defined.

Definition log x := proj1_sig (log_terminates x).

Eval compute in log 109.

Equations? log' (n : nat) : nat by wf n lt :=
 log' 0 := 0;
 log' 1 := 0;
 log' n := S (log' (div2 n)).
Proof. subst n. simpl. auto using div2_le with arith. Defined.


This page has been generated by coqdoc