(**************************************************************)
(* Copyright Dominique Larchey-Wendling * *)
(* *)
(* * Affiliation LORIA -- CNRS *)
(**************************************************************)
(* This file is distributed under the terms of the *)
(* CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT *)
(**************************************************************)
Require Import Arith Lia.
Set Implicit Arguments.
Set Default Proof Using "Type".
Section nat_rev_ind.
(* A reverse recursion principle *)
Variables (P : nat -> Prop)
(HP : forall n, P (S n) -> P n).
Theorem nat_rev_ind x y : x <= y -> P y -> P x.
Proof using HP. induction 1; auto. Qed.
End nat_rev_ind.
Section nat_rev_ind'.
(* A reverse recursion principle *)
Variables (P : nat -> Prop) (k : nat)
(HP : forall n, n < k -> P (S n) -> P n).
Theorem nat_rev_ind' x y : x <= y <= k -> P y -> P x.
Proof using HP.
intros H1 H2.
set (Q n := n <= k /\ P n).
assert (forall x y, x <= y -> Q y -> Q x) as H.
apply nat_rev_ind.
intros n (H3 & H4); split.
lia.
revert H4; apply HP, H3.
apply (H x y).
lia.
split; auto; lia.
Qed.
End nat_rev_ind'.
Section minimizer_pred.
Variable (P : nat -> Prop)
(HP : forall p: { n | P n \/ ~ P n }, { P (proj1_sig p) } + { ~ P (proj1_sig p) }).
Definition minimizer n := P n /\ forall i, i < n -> ~ P i.
Inductive bar n : Prop :=
| in_bar_0 : P n -> bar n
| in_bar_1 : ~ P n -> bar (S n) -> bar n.
Let bar_ex n : bar n -> P n \/ ~ P n.
Proof. induction 1; auto. Qed.
Let loop : forall n, bar n -> { k | P k /\ forall i, n <= i < k -> ~ P i }.
Proof.
refine (fix loop n Hn { struct Hn } := match HP (exist _ n (bar_ex Hn)) with
| left H => exist _ n _
| right H => match loop (S n) _ with
| exist _ k Hk => exist _ k _
end
end).
* split; auto; intros; lia.
* destruct Hn; [ destruct H | ]; assumption.
* destruct Hk as (H1 & H2).
split; trivial; intros i Hi.
destruct (eq_nat_dec i n).
- subst; trivial.
- apply H2; lia.
Qed.
Hypothesis Hmin : ex minimizer.
Let bar_0 : bar 0.
Proof.
destruct Hmin as (k & H1 & H2).
apply in_bar_0 in H1.
clear HP.
revert H1.
apply nat_rev_ind' with (k := k).
intros i H3.
apply in_bar_1, H2; trivial.
lia.
Qed.
Definition minimizer_pred : sig minimizer.
Proof using Hmin loop.
destruct (loop bar_0) as (k & H1 & H2).
exists k; split; auto.
intros; apply H2; lia.
Defined.
End minimizer_pred.
(* Check minimizer_pred. *)
(* Print Assumptions minimizer_pred. *)
(* (* Let P be a computable predicate: *)
(* - whenever P n has a value (P n or not P n) then that value can be computed *)
(* Then minimizer P is computable as well: *)
(* - whenever minimizer P holds for some n, then such an n can be computed *)
(* *) *)
(* Corollary minimizer_alt (P : nat -> Prop) : *)
(* (forall n, P n \/ ~ P n -> { P n } + { ~ P n }) -> ex (minimizer P) -> sig (minimizer P). *)
(* Proof. *)
(* intro H; apply minimizer_pred. *)
(* intros (n & Hn); apply H, Hn. *)
(* Defined. *)
(* Check minimizer_alt. *)
(* Print Assumptions minimizer_alt. *)
(* Section minimizer. *)
(* Variable (R : nat -> nat -> Prop) *)
(* (Rfun : forall n u v, R n u -> R n v -> u = v) *)
(* (HR : forall n, ex (R n) -> sig (R n)). *)
(* Definition minimizer' n := R n 0 /\ forall i, i < n -> exists u, R i (S u). *)
(* Fact minimizer_fun n m : minimizer' n -> minimizer' m -> n = m. *)
(* Proof. *)
(* intros (H1 & H2) (H3 & H4). *)
(* destruct (lt_eq_lt_dec n m) as [ H | ] | H ; auto; *)
(* apply H4 in H | apply H2 in H ; destruct H as (u & Hu); *)
(* generalize (Rfun H1 Hu) | generalize (Rfun H3 Hu) ; discriminate. *)
(* Qed. *)
(* Inductive bar n : Prop := *)
(* | in_bar_0 : R n 0 -> bar n *)
(* | in_bar_1 : (exists u, R n (S u)) -> bar (S n) -> bar n. *)
(* Let bar_ex n : bar n -> ex (R n). *)
(* Proof. *)
(* induction 1 as n Hn | n (k & Hk) _ _ . *)
(* exists 0; auto. *)
(* exists (S k); trivial. *)
(* Qed. *)
(* Let loop : forall n, bar n -> { k | R k 0 /\ forall i, n <= i < k -> exists u, R i (S u) }. *)
(* Proof. *)
(* refine (fix loop n Hn { struct Hn } := match HR (bar_ex Hn) with *)
(* | exist _ u Hu => match u as m return R _ m -> _ with *)
(* | 0 => fun H => exist _ n _ *)
(* | S v => fun H => match loop (S n) _ with *)
(* | exist _ k Hk => exist _ k _ *)
(* end *)
(* end Hu *)
(* end). *)
(* * split; auto; intros; lia. *)
(* * destruct Hn as Hn | ; trivial; exfalso; generalize (Rfun H Hn); discriminate. *)
(* * destruct Hk as (H1 & H2); split; trivial; intros i Hi. *)
(* destruct (eq_nat_dec i n). *)
(* - subst; exists v; trivial. *)
(* - apply H2; lia. *)
(* Qed. *)
(* Hypothesis Hmin : ex minimizer. *)
(* Let bar_0 : bar 0. *)
(* Proof. *)
(* destruct Hmin as (k & H1 & H2). *)
(* apply in_bar_0 in H1. *)
(* clear Hmin HR. *)
(* revert H1. *)
(* apply nat_rev_ind' with (k := k). *)
(* intros i H3. *)
(* apply in_bar_1, H2; trivial. *)
(* lia. *)
(* Qed. *)
(* Definition minimizer_coq : sig minimizer. *)
(* Proof. *)
(* destruct (loop bar_0) as (k & H1 & H2). *)
(* exists k; split; auto. *)
(* intros; apply H2; lia. *)
(* Defined. *)
(* End minimizer. *)
(* Check minimizer_coq. *)
(* Print Assumptions minimizer_coq. *)
(* Extraction "minimizer.ml" minimizer_coq. *)
(* Copyright Dominique Larchey-Wendling * *)
(* *)
(* * Affiliation LORIA -- CNRS *)
(**************************************************************)
(* This file is distributed under the terms of the *)
(* CeCILL v2 FREE SOFTWARE LICENSE AGREEMENT *)
(**************************************************************)
Require Import Arith Lia.
Set Implicit Arguments.
Set Default Proof Using "Type".
Section nat_rev_ind.
(* A reverse recursion principle *)
Variables (P : nat -> Prop)
(HP : forall n, P (S n) -> P n).
Theorem nat_rev_ind x y : x <= y -> P y -> P x.
Proof using HP. induction 1; auto. Qed.
End nat_rev_ind.
Section nat_rev_ind'.
(* A reverse recursion principle *)
Variables (P : nat -> Prop) (k : nat)
(HP : forall n, n < k -> P (S n) -> P n).
Theorem nat_rev_ind' x y : x <= y <= k -> P y -> P x.
Proof using HP.
intros H1 H2.
set (Q n := n <= k /\ P n).
assert (forall x y, x <= y -> Q y -> Q x) as H.
apply nat_rev_ind.
intros n (H3 & H4); split.
lia.
revert H4; apply HP, H3.
apply (H x y).
lia.
split; auto; lia.
Qed.
End nat_rev_ind'.
Section minimizer_pred.
Variable (P : nat -> Prop)
(HP : forall p: { n | P n \/ ~ P n }, { P (proj1_sig p) } + { ~ P (proj1_sig p) }).
Definition minimizer n := P n /\ forall i, i < n -> ~ P i.
Inductive bar n : Prop :=
| in_bar_0 : P n -> bar n
| in_bar_1 : ~ P n -> bar (S n) -> bar n.
Let bar_ex n : bar n -> P n \/ ~ P n.
Proof. induction 1; auto. Qed.
Let loop : forall n, bar n -> { k | P k /\ forall i, n <= i < k -> ~ P i }.
Proof.
refine (fix loop n Hn { struct Hn } := match HP (exist _ n (bar_ex Hn)) with
| left H => exist _ n _
| right H => match loop (S n) _ with
| exist _ k Hk => exist _ k _
end
end).
* split; auto; intros; lia.
* destruct Hn; [ destruct H | ]; assumption.
* destruct Hk as (H1 & H2).
split; trivial; intros i Hi.
destruct (eq_nat_dec i n).
- subst; trivial.
- apply H2; lia.
Qed.
Hypothesis Hmin : ex minimizer.
Let bar_0 : bar 0.
Proof.
destruct Hmin as (k & H1 & H2).
apply in_bar_0 in H1.
clear HP.
revert H1.
apply nat_rev_ind' with (k := k).
intros i H3.
apply in_bar_1, H2; trivial.
lia.
Qed.
Definition minimizer_pred : sig minimizer.
Proof using Hmin loop.
destruct (loop bar_0) as (k & H1 & H2).
exists k; split; auto.
intros; apply H2; lia.
Defined.
End minimizer_pred.
(* Check minimizer_pred. *)
(* Print Assumptions minimizer_pred. *)
(* (* Let P be a computable predicate: *)
(* - whenever P n has a value (P n or not P n) then that value can be computed *)
(* Then minimizer P is computable as well: *)
(* - whenever minimizer P holds for some n, then such an n can be computed *)
(* *) *)
(* Corollary minimizer_alt (P : nat -> Prop) : *)
(* (forall n, P n \/ ~ P n -> { P n } + { ~ P n }) -> ex (minimizer P) -> sig (minimizer P). *)
(* Proof. *)
(* intro H; apply minimizer_pred. *)
(* intros (n & Hn); apply H, Hn. *)
(* Defined. *)
(* Check minimizer_alt. *)
(* Print Assumptions minimizer_alt. *)
(* Section minimizer. *)
(* Variable (R : nat -> nat -> Prop) *)
(* (Rfun : forall n u v, R n u -> R n v -> u = v) *)
(* (HR : forall n, ex (R n) -> sig (R n)). *)
(* Definition minimizer' n := R n 0 /\ forall i, i < n -> exists u, R i (S u). *)
(* Fact minimizer_fun n m : minimizer' n -> minimizer' m -> n = m. *)
(* Proof. *)
(* intros (H1 & H2) (H3 & H4). *)
(* destruct (lt_eq_lt_dec n m) as [ H | ] | H ; auto; *)
(* apply H4 in H | apply H2 in H ; destruct H as (u & Hu); *)
(* generalize (Rfun H1 Hu) | generalize (Rfun H3 Hu) ; discriminate. *)
(* Qed. *)
(* Inductive bar n : Prop := *)
(* | in_bar_0 : R n 0 -> bar n *)
(* | in_bar_1 : (exists u, R n (S u)) -> bar (S n) -> bar n. *)
(* Let bar_ex n : bar n -> ex (R n). *)
(* Proof. *)
(* induction 1 as n Hn | n (k & Hk) _ _ . *)
(* exists 0; auto. *)
(* exists (S k); trivial. *)
(* Qed. *)
(* Let loop : forall n, bar n -> { k | R k 0 /\ forall i, n <= i < k -> exists u, R i (S u) }. *)
(* Proof. *)
(* refine (fix loop n Hn { struct Hn } := match HR (bar_ex Hn) with *)
(* | exist _ u Hu => match u as m return R _ m -> _ with *)
(* | 0 => fun H => exist _ n _ *)
(* | S v => fun H => match loop (S n) _ with *)
(* | exist _ k Hk => exist _ k _ *)
(* end *)
(* end Hu *)
(* end). *)
(* * split; auto; intros; lia. *)
(* * destruct Hn as Hn | ; trivial; exfalso; generalize (Rfun H Hn); discriminate. *)
(* * destruct Hk as (H1 & H2); split; trivial; intros i Hi. *)
(* destruct (eq_nat_dec i n). *)
(* - subst; exists v; trivial. *)
(* - apply H2; lia. *)
(* Qed. *)
(* Hypothesis Hmin : ex minimizer. *)
(* Let bar_0 : bar 0. *)
(* Proof. *)
(* destruct Hmin as (k & H1 & H2). *)
(* apply in_bar_0 in H1. *)
(* clear Hmin HR. *)
(* revert H1. *)
(* apply nat_rev_ind' with (k := k). *)
(* intros i H3. *)
(* apply in_bar_1, H2; trivial. *)
(* lia. *)
(* Qed. *)
(* Definition minimizer_coq : sig minimizer. *)
(* Proof. *)
(* destruct (loop bar_0) as (k & H1 & H2). *)
(* exists k; split; auto. *)
(* intros; apply H2; lia. *)
(* Defined. *)
(* End minimizer. *)
(* Check minimizer_coq. *)
(* Print Assumptions minimizer_coq. *)
(* Extraction "minimizer.ml" minimizer_coq. *)