Library NbSteps.nb_steps

Author: Jean-François Monin, Verimag, Université Grenoble Alpes
Graph free version of an example developed with Dominique Larchey-Wendling in the chapter book on the Braga method

Require Import Utf8 Extraction.

Target : nb of g steps to get some condition b
      let rec  ns x = match b x with true => 0 | false => S (ns (g x))
Algorithm using an accumulator
    let rec nsa x n = match b x with true => n | false => nsa (g x) (S n)
We prove that ns computes the same result as nsa.

Section ns_nsa.

Variable (X : Type) (g : X X) (b : X bool).

Unset Elimination Schemes.

Fact true_false {x} : x = true x = false False.
Proof. intros et. rewrite et. intros e; discriminate e. Qed.

The custom inductive domain of ns and nsa

This definition with x as an indice corresponds to the rules of the Braga paper
Inductive 𝔻ns : X Prop :=
  | 𝔻ns_tt : x, b x = true 𝔻ns x
  | 𝔻ns_ff : x, b x = false 𝔻ns (g x) 𝔻ns x
.

Small inversion (unused but good warming up)
Trick for dealing with this LISP-style definition: destruct (b x) before destruct D. The Coq tactic inversion D is unusable
Lemma 𝔻ns_inv {x} (D : 𝔻ns x) :
  match b x return 𝔻ns x Prop with
  | trueis_𝔻ns_tt x
  | falseis_𝔻ns_ff x
  end D.
Proof.
  destruct (b x) eqn:ebx; destruct D as [x e | x e D]; try constructor.
  - destruct (true_false ebx e).
  - destruct (true_false e ebx).
Qed.

The projection of constructor 𝔻ns_ff
Definition π_𝔻ns {x} (D : 𝔻ns x) : b x = false 𝔻ns (g x) :=
  match D with
  | 𝔻ns_tt x Eλ G, match true_false E G with end
  | 𝔻ns_ff x E Dgxλ _, Dgx
  end.

Smaller inversion (crucial step for 𝔻ns_rect)
Inductive is_𝔻ns_ff_π {x} (D : 𝔻ns x) : 𝔻ns x Prop :=
| is_𝔻ns_ff_π_intro e : is_𝔻ns_ff_π D (𝔻ns_ff x e (π_𝔻ns D e)).

Lemma 𝔻ns_π_inv {x} (D : 𝔻ns x) :
  match b x as bx return 𝔻ns x 𝔻ns x Prop with
  | trueλ _, is_𝔻ns_tt x
  | falseis_𝔻ns_ff_π
  end D D.
Proof.
inversion D is unusable
  destruct (b x) eqn:ebx; destruct D as [x e | x e D]; try constructor.
  - destruct (true_false ebx e).
  - destruct (true_false e ebx).
Qed.

Set Elimination Schemes.

Definition of ns/nsa as structural fixpoints on the domain predicate


Fixpoint ns x (D : 𝔻ns x) : nat :=
  match b x as bx return b x = bx _ with
  | trueλ _, 0
  | falseλ G, S (ns (g x) (π_𝔻ns D G))
  end eq_refl.

Fixpoint nsa x (n : nat) (D : 𝔻ns x) : nat :=
  match b x as bx return b x = bx _ with
  | trueλ _, n
  | falseλ G, nsa (g x) (S n) (π_𝔻ns D G)
  end eq_refl.

Fixpoint equations are for free! Example
Example ns_fix_ff x E D : ns x (𝔻ns_ff x E D) = S (ns (g x) D).
Proof. simpl; now rewrite E. Qed.

We can show the next equality by structural recursion on D

Lemma nsa_ns_n_direct : x n D, nsa x n D = ns x D + n.
Proof.
  refine (fix loop x n D { struct D } := _).
  destruct D as [ x E | x E D ]; simpl.
  - now rewrite E.
  - now rewrite loop, E, <- plus_n_Sm.
Qed.

Corollary nsa_ns_direct : x (D: 𝔻ns x), nsa x 0 D = ns x D.
Proof. intros; now rewrite nsa_ns_n_direct, plus_n_O. Qed.

An eliminator for 𝔻ns which follows the program scheme of ns and nsa

Theorem 𝔻ns_rect
        (P : x, 𝔻ns x Type)
        (Ptt : x E, P _ (𝔻ns_tt x E))
        (Pff : x E D, P _ D P _ (𝔻ns_ff x E D)) :
   x D, P x D.
Proof.
  refine (
      fix loop x D {struct D} :=
        match b x as bx return b x = bx _ with
        | trueλ E D, _
        | falseλ E D, _
        end eq_refl D);
    generalize (𝔻ns_π_inv D); rewrite E; intros [].
  - apply Ptt.
  - apply Pff, loop.
Qed.

Application: Equality by dependent induction on D
Lemma nsa_ns_n x n D : nsa x n D = ns x D + n.
Proof.
  revert n.
  induction D as [ x e | x e D HD ] using 𝔻ns_rect;
    intro n; cbn; rewrite e.
  - reflexivity.
  - cbn. rewrite HD, plus_n_Sm. reflexivity.
Qed.

End ns_nsa.

Extract Inductive bool ⇒ "bool" [ "true" "false" ].

Recursive Extraction ns nsa.