Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
(* Evgeny Makarov, INRIA, 2007 *)
(************************************************************************)
This file defined the strong (course-of-value, well-founded) recursion
and proves its properties
Require Export NSub. Ltac f_equiv' := repeat (repeat f_equiv; try intros ? ? ?; auto). Module NStrongRecProp (Import N : NAxiomsRecSig'). Include NSubProp N. Section StrongRecursion. Variable A : Type. Variable Aeq : relation A. Variable Aeq_equiv : Equivalence Aeq.
strong_rec allows defining a recursive function phi given by
an equation phi(n) = F(phi)(n) where recursive calls to phi
in F are made on strictly lower numbers than n.
For strong_rec a F n:
- Parameter a:A is a default value used internally, it has no effect on the final result.
- Parameter F:(N→A)->N→A is the step function: F f n should return phi(n) when f is a function that coincide with phi for numbers strictly less than n.
Definition strong_rec (a : A) (f : (N.t -> A) -> N.t -> A) (n : N.t) : A :=
recursion (fun _ => a) (fun _ => f) (S n) n.
For convenience, we use in proofs an intermediate definition
between recursion and strong_rec.
Definition strong_rec0 (a : A) (f : (N.t -> A) -> N.t -> A) : N.t -> N.t -> A := recursion (fun _ => a) (fun _ => f).A:TypeAeq:relation AAeq_equiv:Equivalence Aeqforall (a : A) (f : (t -> A) -> t -> A) (n : t), strong_rec a f n = strong_rec0 a f (S n) nreflexivity. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqforall (a : A) (f : (t -> A) -> t -> A) (n : t), strong_rec a f n = strong_rec0 a f (S n) nA:TypeAeq:relation AAeq_equiv:Equivalence AeqProper (Aeq ==> ((eq ==> Aeq) ==> eq ==> Aeq) ==> eq ==> eq ==> Aeq) strong_rec0unfold strong_rec0; f_equiv'. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence AeqProper (Aeq ==> ((eq ==> Aeq) ==> eq ==> Aeq) ==> eq ==> eq ==> Aeq) strong_rec0A:TypeAeq:relation AAeq_equiv:Equivalence AeqProper (Aeq ==> ((eq ==> Aeq) ==> eq ==> Aeq) ==> eq ==> Aeq) strong_recA:TypeAeq:relation AAeq_equiv:Equivalence AeqProper (Aeq ==> ((eq ==> Aeq) ==> eq ==> Aeq) ==> eq ==> Aeq) strong_recrewrite !strong_rec_alt; f_equiv'. Qed. Section FixPoint. Variable f : (N.t -> A) -> N.t -> A. Variable f_wd : Proper ((N.eq==>Aeq)==>N.eq==>Aeq) f.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqa, a':AEaa':Aeq a a'f, f':(t -> A) -> t -> AEff':((eq ==> Aeq) ==> eq ==> Aeq)%signature f f'n, n':tEnn':n == n'Aeq (strong_rec a f n) (strong_rec a' f' n')A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall (a : A) (m : t), strong_rec0 a f 0 m = aA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall (a : A) (m : t), strong_rec0 a f 0 m = aA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:Am:tstrong_rec0 a f 0 m = arewrite recursion_0; auto. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:Am:trecursion (fun _ : t => a) (fun _ : t => f) 0 m = aA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall (a : A) (n m : t), Aeq (strong_rec0 a f (S n) m) (f (strong_rec0 a f n) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall (a : A) (n m : t), Aeq (strong_rec0 a f (S n) m) (f (strong_rec0 a f n) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:An, m:tAeq (strong_rec0 a f (S n) m) (f (strong_rec0 a f n) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:An, m:tAeq (recursion (fun _ : t => a) (fun _ : t => f) (S n) m) (f (recursion (fun _ : t => a) (fun _ : t => f) n) m)rewrite recursion_succ; f_equiv'. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:An, m:t(Logic.eq ==> Aeq)%signature (recursion (fun _ : t => a) (fun _ : t => f) (S n)) (f (recursion (fun _ : t => a) (fun _ : t => f) n))A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall a : A, Aeq (strong_rec a f 0) (f (fun _ : t => a) 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fforall a : A, Aeq (strong_rec a f 0) (f (fun _ : t => a) 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:AAeq (strong_rec a f 0) (f (fun _ : t => a) 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:Ax, y:tH:x == yAeq (strong_rec0 a f 0 x) areflexivity. Qed. (* We need an assumption saying that for every n, the step function (f h n) calls h only on the segment [0 ... n - 1]. This means that if h1 and h2 coincide on values < n, then (f h1 n) coincides with (f h2 n) *) Hypothesis step_good : forall (n : N.t) (h1 h2 : N.t -> A), (forall m : N.t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n).A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fa:Ax, y:tH:x == yAeq a aA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (k n m : t), m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (k n m : t), m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tforall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:t(fun t0 : t => forall m : t, m < t0 -> Aeq (strong_rec0 a f t0 m) (strong_rec0 a f (t0 + k) m)) nA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tProper (eq ==> iff) (fun t0 : t => forall m : t, m < t0 -> Aeq (strong_rec0 a f t0 m) (strong_rec0 a f (t0 + k) m))A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall m : t, m < 0 -> Aeq (strong_rec0 a f 0 m) (strong_rec0 a f (0 + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall n : t, (forall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)) -> forall m : t, m < S n -> Aeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall m : t, m < 0 -> Aeq (strong_rec0 a f 0 m) (strong_rec0 a f (0 + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall n : t, (forall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)) -> forall m : t, m < S n -> Aeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n) (f h2 n)a:Ak, m:tHm:m < 0Aeq (strong_rec0 a f 0 m) (strong_rec0 a f (0 + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall n : t, (forall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)) -> forall m : t, m < S n -> Aeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Ak:tforall n : t, (forall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (n + k) m)) -> forall m : t, m < S n -> Aeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m < S nAeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nAeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S n + k) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nAeq (strong_rec0 a f (S n) m) (strong_rec0 a f (S (n + k)) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nAeq (f (strong_rec0 a f n) m) (f (strong_rec0 a f (n + k)) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nforall m0 : t, m0 < m -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nm':tHm':m' < mAeq (strong_rec0 a f n m') (strong_rec0 a f (n + k) m')apply lt_le_trans with m; auto. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:Ak, n:tIH:forall m0 : t, m0 < n -> Aeq (strong_rec0 a f n m0) (strong_rec0 a f (n + k) m0)m:tHm:m <= nm':tHm':m' < mm' < nA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (n : t), Aeq (strong_rec0 a f (S n) n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (n : t), Aeq (strong_rec0 a f (S n) n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (strong_rec0 a f (S n) n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (f (strong_rec0 a f n) n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tforall m : t, m < n -> Aeq (strong_rec0 a f n m) (strong_rec0 a f (S m) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nAeq (strong_rec0 a f n m) (strong_rec0 a f (S m) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nAeq (strong_rec0 a f (S m) m) (strong_rec0 a f n m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nAeq (strong_rec0 a f (S m) m) (strong_rec0 a f (S m + (n - S m)) m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nn == S m + (n - S m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nm < S mA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nn == S m + (n - S m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nn == S m + (n - S m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nn == n - S m + S mA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nn - S m + S m == nrewrite le_succ_l; auto. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a:An, m:tHm:m < nS m <= nA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (n : t), Aeq (strong_rec a f n) (f (strong_rec a f) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (n : t), Aeq (strong_rec a f n) (f (strong_rec a f) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (strong_rec a f n) (f (strong_rec a f) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (strong_rec a f n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (f (fun n0 : t => strong_rec0 a f (S n0) n0) n) (f (strong_rec a f) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (strong_rec0 a f (S n) n) (f (fun n0 : t => strong_rec0 a f (S n0) n0) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (f (fun n0 : t => strong_rec0 a f (S n0) n0) n) (f (strong_rec a f) n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:tAeq (f (fun n0 : t => strong_rec0 a f (S n0) n0) n) (f (strong_rec a f) n)intros x x' Hx; rewrite strong_rec_alt, Hx; auto with *. Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a:An:t(eq ==> Aeq)%signature (fun n0 : t => strong_rec0 a f (S n0) n0) (strong_rec a f)
NB: without the step_good hypothesis, we have proved that
strong_rec a f 0 is f (fun _ ⇒ a) 0. Now we can prove
that the first argument of f is arbitrary in this case...
A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (any : t -> A), Aeq (strong_rec a f 0) (f any 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a : A) (any : t -> A), Aeq (strong_rec a f 0) (f any 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Aany:t -> AAeq (strong_rec a f 0) (f any 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Aany:t -> AAeq (f (strong_rec a f) 0) (f any 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a:Aany:t -> Aforall m : t, m < 0 -> Aeq (strong_rec a f m) (any m)destruct (nlt_0_r _ Hm). Qed.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n) (f h2 n)a:Aany:t -> Am:tHm:m < 0Aeq (strong_rec a f m) (any m)
... and that first argument of strong_rec is always arbitrary.
A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a a' : A) (n : t), Aeq (strong_rec a f n) (strong_rec a' f n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)forall (a a' : A) (n : t), Aeq (strong_rec a f n) (strong_rec a' f n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tAeq (strong_rec a f n) (strong_rec a' f n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tn <= n -> Aeq (strong_rec a f n) (strong_rec a' f n)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tk:=n:tk <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An, k:tk <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tforall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:t(fun t0 : t => forall k : t, k <= t0 -> Aeq (strong_rec a f k) (strong_rec a' f k)) n(* compat *)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':AProper (eq ==> iff) (fun t0 : t => forall k : t, k <= t0 -> Aeq (strong_rec a f k) (strong_rec a' f k))A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall k : t, k <= 0 -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An, n':tHn:n == n'(forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) <-> (forall k : t, k <= n' -> Aeq (strong_rec a f k) (strong_rec a' f k))A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall k : t, k <= 0 -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)(* 0 *)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall k : t, k <= 0 -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Ak:tHk:k <= 0Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Ak:tHk:k == 0Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Ak:tHk:k == 0Aeq (f (fun _ : t => a) 0) (strong_rec a' f 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Ak:tHk:k == 0Aeq (strong_rec a' f 0) (f (fun _ : t => a) 0)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)(* S *)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n : t) (h1 h2 : t -> A), (forall m : t, m < n -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n) (f h2 n)a, a':Aforall n : t, (forall k : t, k <= n -> Aeq (strong_rec a f k) (strong_rec a' f k)) -> forall k : t, k <= S n -> Aeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nAeq (strong_rec a f k) (strong_rec a' f k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nAeq (f (strong_rec a f) k) (f (strong_rec a' f) k)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m : t, m < n0 -> Aeq (h1 m) (h2 m)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nforall m : t, m < k -> Aeq (strong_rec a f m) (strong_rec a' f m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nm:tHm:m < kAeq (strong_rec a f m) (strong_rec a' f m)A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nm:tHm:m < km <= nA:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nm:tHm:m < kS m <= S nrewrite le_succ_l; auto. Qed. End FixPoint. End StrongRecursion. Arguments strong_rec [A] a f n. End NStrongRecProp.A:TypeAeq:relation AAeq_equiv:Equivalence Aeqf:(t -> A) -> t -> Af_wd:Proper ((eq ==> Aeq) ==> eq ==> Aeq) fstep_good:forall (n0 : t) (h1 h2 : t -> A), (forall m0 : t, m0 < n0 -> Aeq (h1 m0) (h2 m0)) -> Aeq (f h1 n0) (f h2 n0)a, a':An:tIH:forall k0 : t, k0 <= n -> Aeq (strong_rec a f k0) (strong_rec a' f k0)k:tHk:k <= S nm:tHm:m < kS m <= k