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 *) (************************************************************************) Require Import NZAxioms NZBase Decidable OrdersTac. Module Type NZOrderProp (Import NZ : NZOrdSig')(Import NZBase : NZBaseProp NZ).Proper (eq ==> eq ==> iff) leProper (eq ==> eq ==> iff) lenow rewrite <- !lt_succ_r, Hn, Hm. Qed. Ltac le_elim H := rewrite lt_eq_cases in H; destruct H as [H | H].n, n':tHn:n == n'm, m':tHm:m == m'n <= m <-> n' <= m'forall n m : t, n < m -> n <= mforall n m : t, n < m -> n <= mn, m:tH:n < mn <= mnow left. Qed.n, m:tH:n < mn < m \/ n == mforall n : t, n <= nforall n : t, n <= nn:tn <= nnow right. Qed.n:tn < n \/ n == nforall n : t, n < S nforall n : t, n < S nn:tn < S napply le_refl. Qed.n:tn <= nforall n : t, n <= S nintro; apply lt_le_incl; apply lt_succ_diag_r. Qed.forall n : t, n <= S nforall n : t, S n ~= nforall n : t, S n ~= nn:tH:S n == nFalsen:tH:S n == nn < napply lt_succ_diag_r. Qed.n:tH:S n == nn < S nforall n : t, n ~= S nintro n; apply neq_sym, neq_succ_diag_l. Qed.forall n : t, n ~= S nforall n : t, ~ S n < nforall n : t, ~ S n < nn:tH:S n < nFalsen:tH:S n < nS n < S nnow apply lt_le_incl. Qed.n:tH:S n < nS n <= nforall n : t, ~ S n <= nforall n : t, ~ S n <= nn:tH:S n < nFalsen:tH:S n == nFalsefalse_hyp H nlt_succ_diag_l.n:tH:S n < nFalsefalse_hyp H neq_succ_diag_l. Qed.n:tH:S n == nFalseforall n m : t, S n <= m <-> n < mforall n m : t, S n <= m <-> n < mn:tS n <= n <-> n < nn:tforall n0 : t, (S n <= n0 <-> n < n0) <-> (S n <= S n0 <-> n < S n0)n:tS n <= n <-> n < nn:tH:S n <= nn < nn:tH:n < nS n <= nfalse_hyp H nle_succ_diag_l.n:tH:S n <= nn < nfalse_hyp H lt_irrefl.n:tH:n < nS n <= nn:tforall n0 : t, (S n <= n0 <-> n < n0) <-> (S n <= S n0 <-> n < S n0)n, m:t(S n <= m <-> n < m) <-> (S n <= S m <-> n < S m)n, m:t(S n <= m <-> n < m) <-> (S n <= m \/ n == m <-> n < m \/ n == m)n, m:t(S n <= m <-> n < m) <-> (S n <= m <-> n < m)n, m:tS n <= m -> n ~= mn, m:tn < m -> n ~= mreflexivity.n, m:t(S n <= m <-> n < m) <-> (S n <= m <-> n < m)intros LE EQ; rewrite EQ in LE; false_hyp LE nle_succ_diag_l.n, m:tS n <= m -> n ~= mintros LT EQ; rewrite EQ in LT; false_hyp LT lt_irrefl. Qed.n, m:tn < m -> n ~= m
Trichotomy
forall n m : t, n <= m \/ m < nforall n m : t, n <= m \/ m < nm:tm <= m \/ m < mm:tforall n : t, n <= m \/ m < n <-> S n <= m \/ m < S nleft; apply le_refl.m:tm <= m \/ m < mm:tforall n : t, n <= m \/ m < n <-> S n <= m \/ m < S nm, n:tn <= m \/ m < n <-> S n <= m \/ m < S nintuition. Qed.m, n:t(n < m \/ n == m) \/ m < n <-> n < m \/ m < n \/ m == nforall n m : t, n < m \/ n == m \/ m < nforall n m : t, n < m \/ n == m \/ m < ngeneralize (le_gt_cases n m); rewrite lt_eq_cases; tauto. Qed. Notation lt_eq_gt_cases := lt_trichotomy (only parsing).n, m:tn < m \/ n == m \/ m < n
Asymmetry and transitivity.
forall n m : t, n < m -> ~ m < nforall n m : t, n < m -> ~ m < nm:tm < m -> ~ m < mm:tforall n : t, (n < m -> ~ m < n) <-> (S n < m -> ~ m < S n)intros H; false_hyp H lt_irrefl.m:tm < m -> ~ m < mm:tforall n : t, (n < m -> ~ m < n) <-> (S n < m -> ~ m < S n)m, n:tH:n < m -> ~ m < nH1:S n < mH2:m < S nFalsem, n:tH:S n < m -> ~ m < S nH1:n < mH2:m < nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m < S nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m <= nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m < nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m == nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m < nFalsem, n:tH:n < m -> ~ m < nH1:S n < mH2:m < nn < mnow apply lt_le_incl.m, n:tH:n < m -> ~ m < nH1:S n < mH2:m < nS n <= mm, n:tH:n < m -> ~ m < nH1:S n < mH2:m == nFalsefalse_hyp H1 nlt_succ_diag_l.m, n:tH:n < m -> ~ m < nH1:S n < nH2:m == nFalsem, n:tH:S n < m -> ~ m < S nH1:n < mH2:m < nFalsem, n:tH:S n < m -> ~ m < S nH1:S n <= mH2:m < nFalsem, n:tH:S n < m -> ~ m < S nH1:S n < mH2:m < nFalsem, n:tH:S n < m -> ~ m < S nH1:S n == mH2:m < nFalsem, n:tH:S n < m -> ~ m < S nH1:S n < mH2:m < nFalsem, n:tH:S n < m -> ~ m < S nH1:S n < mH2:m < nm < S nnow apply lt_le_incl.m, n:tH:S n < m -> ~ m < S nH1:S n < mH2:m < nm <= nm, n:tH:S n < m -> ~ m < S nH1:S n == mH2:m < nFalsefalse_hyp H2 nlt_succ_diag_l. Qed. Notation lt_ngt := lt_asymm (only parsing).m, n:tH:S n < m -> ~ m < S nH1:S n == mH2:S n < nFalseforall n m p : t, n < m -> m < p -> n < pforall n m p : t, n < m -> m < p -> n < pn, m:tn < m -> m < m -> n < mn, m:tforall n0 : t, (n < m -> m < n0 -> n < n0) <-> (n < m -> m < S n0 -> n < S n0)intros _ H; false_hyp H lt_irrefl.n, m:tn < m -> m < m -> n < mn, m:tforall n0 : t, (n < m -> m < n0 -> n < n0) <-> (n < m -> m < S n0 -> n < S n0)n, m, p:t(n < m -> m < p -> n < p) <-> (n < m -> m < S p -> n < S p)n, m, p:t(n < m -> m < p -> n < p) <-> (n < m -> m <= p -> n <= p)n, m, p:tH:n < m -> m < p -> n < pH1:n < mH2:m <= pn <= pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pn < papply lt_le_incl; le_elim H2; [now apply H | now rewrite H2 in H1].n, m, p:tH:n < m -> m < p -> n < pH1:n < mH2:m <= pn <= pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pn < pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pH3:n <= pn < pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pH3:n < pn < pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pH3:n == pn < passumption.n, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pH3:n < pn < pn, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < pH3:n == pn < pelim (lt_asymm n m); auto. Qed.n, m, p:tH:n < m -> m <= p -> n <= pH1:n < mH2:m < nH3:n == pn < pforall n m p : t, n <= m -> m <= p -> n <= pforall n m p : t, n <= m -> m <= p -> n <= pn, m, p:tn <= m -> m <= p -> n <= pintros [LT|EQ] [LT'|EQ']; try rewrite EQ; try rewrite <- EQ'; generalize (lt_trans n m p); auto with relations. Qed.n, m, p:tn < m \/ n == m -> m < p \/ m == p -> n < p \/ n == p
Some type classes about order
StrictOrder ltStrictOrder ltIrreflexive ltTransitive ltexact lt_irrefl.Irreflexive ltexact lt_trans. Qed.Transitive ltPreOrder lePreOrder leReflexive leTransitive leexact le_refl.Reflexive leexact le_trans. Qed.Transitive lePartialOrder eq lePartialOrder eq lex, y:tpointwise_lifting iff Tnil (x == y) (relation_conjunction le (Basics.flip le) x y)x, y:t(x == y -> x <= y <= x) /\ (x <= y <= x -> x == y)x, y:tx == y -> x <= y <= xx, y:tx <= y <= x -> x == yintro EQ; now rewrite EQ.x, y:tx == y -> x <= y <= xx, y:tx <= y <= x -> x == yx, y:t(x < y \/ x == y) /\ (y < x \/ y == x) -> x == yx, y:tH:x < yH0:y < xx == ynow transitivity y. Qed.x, y:tH:x < yH0:y < xx < x
We know enough now to benefit from the generic order tactic.
Definition lt_compat := lt_wd. Definition lt_total := lt_trichotomy. Definition le_lteq := lt_eq_cases. Module Private_OrderTac. Module IsTotal. Definition eq_equiv := eq_equiv. Definition lt_strorder := lt_strorder. Definition lt_compat := lt_compat. Definition lt_total := lt_total. Definition le_lteq := le_lteq. End IsTotal. Module Tac := !MakeOrderTac NZ IsTotal. End Private_OrderTac. Ltac order := Private_OrderTac.Tac.order.
Some direct consequences of order.
forall n m : t, n < m -> n ~= morder. Qed.forall n m : t, n < m -> n ~= mforall n m : t, n < m <-> n <= m /\ n ~= mintuition order. Qed.forall n m : t, n < m <-> n <= m /\ n ~= mforall n m : t, n == m -> n <= morder. Qed.forall n m : t, n == m -> n <= mforall x y z : t, x < y -> x == z -> z < yorder. Qed.forall x y z : t, x < y -> x == z -> z < yforall x y z : t, x < y -> y == z -> x < zorder. Qed.forall x y z : t, x < y -> y == z -> x < zforall x y z : t, x <= y -> x == z -> z <= yorder. Qed.forall x y z : t, x <= y -> x == z -> z <= yforall x y z : t, x <= y -> y == z -> x <= zorder. Qed. Declare Left Step lt_stepl. Declare Right Step lt_stepr. Declare Left Step le_stepl. Declare Right Step le_stepr.forall x y z : t, x <= y -> y == z -> x <= zforall n m p : t, n <= m -> m < p -> n < porder. Qed.forall n m p : t, n <= m -> m < p -> n < pforall n m p : t, n < m -> m <= p -> n < porder. Qed.forall n m p : t, n < m -> m <= p -> n < pforall n m : t, n <= m -> m <= n -> n == morder. Qed.forall n m : t, n <= m -> m <= n -> n == m
More properties of < and ≤ with respect to S and 0.
forall n m : t, n <= S m <-> n <= m \/ n == S mforall n m : t, n <= S m <-> n <= m \/ n == S mnow rewrite lt_succ_r. Qed.n, m:tn < S m \/ n == S m <-> n <= m \/ n == S mforall n m : t, S n < m -> n < mintros n m H; apply le_succ_l; order. Qed.forall n m : t, S n < m -> n < mforall n m : t, n <= m -> n <= S mforall n m : t, n <= m -> n <= S mn, m:tLE:n <= mn <= S morder. Qed.n, m:tLE:n < S mn <= S mforall n m : t, n < m -> n < S mforall n m : t, n < m -> n < S mn, m:tH:n < mn < S morder. Qed.n, m:tH:n < mn <= mforall n m : t, n < m <-> S n < S mforall n m : t, n < m <-> S n < S mn, m:tn < m <-> S n < S mn, m:tS n <= m <-> S n < S mapply lt_succ_r. Qed.n, m:tS n < S m <-> S n <= mforall n m : t, n <= m <-> S n <= S mforall n m : t, n <= m <-> S n <= S mnow rewrite 2 lt_eq_cases, <- succ_lt_mono, succ_inj_wd. Qed.n, m:tn <= m <-> S n <= S m0 < 10 < 1apply lt_succ_diag_r. Qed.0 < S 00 <= 1apply lt_le_incl, lt_0_1. Qed.0 <= 11 < 21 < 2apply lt_succ_diag_r. Qed.1 < S 10 < 20 < 20 < 11 < 2apply lt_0_1.0 < 1apply lt_1_2. Qed.1 < 20 <= 2apply lt_le_incl, lt_0_2. Qed.0 <= 2
The order tactic enriched with some knowledge of 0,1,2
Ltac order' := generalize lt_0_1 lt_1_2; order.forall n m : t, 0 < n -> n < m -> 1 < mforall n m : t, 0 < n -> n < m -> 1 < mn, m:tH1:0 < nH2:n < m1 < morder. Qed.n, m:tH1:1 <= nH2:n < m1 < m
More Trichotomy, decidability and double negation elimination.
The following theorem is cleary redundant, but helps not to
remember whether one has to say le_gt_cases or lt_ge_cases
forall n m : t, n < m \/ m <= nintros n m; destruct (le_gt_cases m n); intuition order. Qed.forall n m : t, n < m \/ m <= nforall n m : t, n <= m \/ m <= nintros n m; destruct (le_gt_cases n m); intuition order. Qed.forall n m : t, n <= m \/ m <= nforall n m : t, n ~= m <-> n < m \/ m < nintros n m; destruct (lt_trichotomy n m); intuition order. Qed.forall n m : t, n ~= m <-> n < m \/ m < n
Decidability of equality, even though true in each finite ring, does not
have a uniform proof. Otherwise, the proof for two fixed numbers would
reduce to a normal form that will say if the numbers are equal or not,
which cannot be true in all finite rings. Therefore, we prove decidability
in the presence of order.
forall n m : t, decidable (n == m)intros n m; destruct (lt_trichotomy n m) as [ | [ | ]]; (right; order) || (left; order). Qed.forall n m : t, decidable (n == m)
DNE stands for double-negation elimination
forall n m : t, ~ n ~= m <-> n == mforall n m : t, ~ n ~= m <-> n == mn, m:tH:~ n ~= mn == mn, m:tH:n == m~ n ~= mn, m:tH:~ n ~= mn == mn, m:tH:~ n ~= mH1:n == mn == mn, m:tH:~ n ~= mH1:n ~= mn == massumption.n, m:tH:~ n ~= mH1:n == mn == mfalse_hyp H1 H.n, m:tH:~ n ~= mH1:n ~= mn == mintro H1; now apply H1. Qed.n, m:tH:n == m~ n ~= mforall n m : t, n <= m <-> ~ m < nintuition order. Qed.forall n m : t, n <= m <-> ~ m < n
Redundant but useful
forall n m : t, ~ n < m <-> m <= nintuition order. Qed.forall n m : t, ~ n < m <-> m <= nforall n m : t, decidable (n < m)intros n m; destruct (le_gt_cases m n); [right|left]; order. Qed.forall n m : t, decidable (n < m)forall n m : t, ~ ~ n < m <-> n < mforall n m : t, ~ ~ n < m <-> n < mn, m:tH:~ ~ n < mn < mn, m:tH:n < m~ ~ n < mdestruct (lt_decidable n m) as [H1 | H1]; [assumption | false_hyp H1 H].n, m:tH:~ ~ n < mn < mintro H1; false_hyp H H1. Qed.n, m:tH:n < m~ ~ n < mforall n m : t, ~ n <= m <-> m < nintuition order. Qed.forall n m : t, ~ n <= m <-> m < n
Redundant but useful
forall n m : t, n < m <-> ~ m <= nintuition order. Qed.forall n m : t, n < m <-> ~ m <= nforall n m : t, decidable (n <= m)intros n m; destruct (le_gt_cases n m); [left|right]; order. Qed.forall n m : t, decidable (n <= m)forall n m : t, ~ ~ n <= m <-> n <= mforall n m : t, ~ ~ n <= m <-> n <= mn, m:tH:~ ~ n <= mn <= mn, m:tH:n <= m~ ~ n <= mdestruct (le_decidable n m) as [H1 | H1]; [assumption | false_hyp H1 H].n, m:tH:~ ~ n <= mn <= mintro H1; false_hyp H H1. Qed.n, m:tH:n <= m~ ~ n <= mforall n m : t, ~ m < S n <-> n < mforall n m : t, ~ m < S n <-> n < mintuition order. Qed.n, m:t~ m <= n <-> n < m
The difference between integers and natural numbers is that for
every integer there is a predecessor, which is not true for natural
numbers. However, for both classes, every number that is bigger than
some other number has a predecessor. The proof of this fact by regular
induction does not go through, so we need to use strong
(course-of-value) induction.
forall z n m : t, z < m -> m <= n -> exists k : t, m == S k /\ z <= kforall z n m : t, z < m -> m <= n -> exists k : t, m == S k /\ z <= kz:tforall m : t, z < m -> m <= z -> exists k : t, m == S k /\ z <= kz:tforall n : t, (forall m : t, z < m -> m <= n -> exists k : t, m == S k /\ z <= k) <-> (forall m : t, z < m -> m <= S n -> exists k : t, m == S k /\ z <= k)order.z:tforall m : t, z < m -> m <= z -> exists k : t, m == S k /\ z <= kz:tforall n : t, (forall m : t, z < m -> m <= n -> exists k : t, m == S k /\ z <= k) <-> (forall m : t, z < m -> m <= S n -> exists k : t, m == S k /\ z <= k)z, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= S nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= S nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= n \/ m == S nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m == S nexists k : t, m == S k /\ z <= know apply IH.z, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m == S nexists k : t, m == S k /\ z <= know split; [| rewrite <- lt_succ_r; rewrite <- H2].z, n:tIH:forall m0 : t, z < m0 -> m0 <= n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m == S nm == S n /\ z <= nz, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nexists k : t, m == S k /\ z <= kz, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nz < mz, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nm <= S nassumption.z, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nz < mnow apply le_le_succ_r. Qed.z, n:tIH:forall m0 : t, z < m0 -> m0 <= S n -> exists k : t, m0 == S k /\ z <= km:tH1:z < mH2:m <= nm <= S nforall z n : t, z < n -> exists k : t, n == S k /\ z <= kforall z n : t, z < n -> exists k : t, n == S k /\ z <= kz, n:tH:z < nz < nz, n:tH:z < nn <= nassumption.z, n:tH:z < nz < napply le_refl. Qed.z, n:tH:z < nn <= nforall z n : t, z < n -> S (P n) == nforall z n : t, z < n -> S (P n) == nz, n:tH:z < nS (P n) == nz, n:tH:z < nn':tEQ:n == S n'LE:z <= n'S (P n) == nnow rewrite pred_succ. Qed.z, n:tH:z < nn':tEQ:n == S n'LE:z <= n'S (P (S n')) == S n'
Stronger variant of induction with assumptions n >= 0 (n < 0)
in the induction step
Section Induction. Variable A : t -> Prop. Hypothesis A_wd : Proper (eq==>iff) A. Section Center. Variable z : t. (* A z is the basis of induction *) Section RightInduction. Let A' (n : t) := forall m, z <= m -> m < n -> A m. Let right_step := forall n, z <= n -> A n -> A (S n). Let right_step' := forall n, z <= n -> A' n -> A n. Let right_step'' := forall n, A' n <-> A' (S n).A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA z -> right_step -> right_step'A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA z -> right_step -> right_step'A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:z <= nH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:z < nH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:z == nH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:z < nH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:exists k : t, n == S k /\ z <= kH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn, k:tH3:n == S kH4:z <= kH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn, k:tH3:n == S kH4:z <= kH2:A' nA (S k)A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn, k:tH3:n == S kH4:z <= kH2:A' nA krewrite H3; apply lt_succ_diag_r.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn, k:tH3:n == S kH4:z <= kH2:A' nk < nrewrite <- H1; apply Az. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zRS:right_stepn:tH1:z == nH2:A' nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propright_step' -> right_step''A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propright_step' -> right_step''A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, z <= m0 -> m0 < n0 -> A m0:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropRS':right_step'n:tH1:A' nm:tH2:z <= mH3:m < S nA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, z <= m0 -> m0 < n0 -> A m0:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropRS':right_step'n:tH1:A' (S n)m:tH2:z <= mH3:m < nA mapply lt_succ_r in H3; le_elim H3; [now apply H1 | rewrite H3 in *; now apply RS'].A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, z <= m0 -> m0 < n0 -> A m0:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropRS':right_step'n:tH1:A' nm:tH2:z <= mH3:m < S nA mapply H1; [assumption | now apply lt_lt_succ_r]. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, z <= m0 -> m0 < n0 -> A m0:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropRS':right_step'n:tH1:A' (S n)m:tH2:z <= mH3:m < nA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA' zA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA' zA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m0 : t, z <= m0 -> m0 < n -> A m0:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propm:tH1:z <= mH2:m < zA mfalse_hyp H2 H1. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m0 : t, z <= m0 -> m0 < n -> A m0:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propm:tH1:~ m < zH2:m < zA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, A' n) -> forall n : t, z <= n -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, A' n) -> forall n : t, z <= n -> A napply H1 with (n := S n); [assumption | apply lt_succ_diag_r]. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropH1:forall n0 : t, A' n0n:tH2:z <= nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propright_step' -> forall n : t, z <= n -> A nintro RS'; apply A'A_right; unfold A'; nzinduct n z; [apply rbase | apply rs'_rs''; apply RS']. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Propright_step' -> forall n : t, z <= n -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA z -> right_step -> forall n : t, z <= n -> A nintros Az RS; apply strong_right_induction; now apply rs_rs'. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):PropA z -> right_step -> forall n : t, z <= n -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, n <= z -> A n) -> right_step -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, n <= z -> A n) -> right_step -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nA napply L; now apply lt_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:n < zA napply L; now apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nA zA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nright_stepA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nz <= napply L; now apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nA zassumption.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nright_stepnow apply lt_le_incl. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_stepn:tH:z < nz <= nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, n <= z -> A n) -> right_step' -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, z <= m -> m < n -> A m:t -> Propright_step:=forall n : t, z <= n -> A n -> A (S n):Propright_step':=forall n : t, z <= n -> A' n -> A n:Propright_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, n <= z -> A n) -> right_step' -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nA napply L; now apply lt_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:n < zA napply L; now apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nright_step'A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nz <= nassumption.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nright_step'now apply lt_le_incl. Qed. End RightInduction. Section LeftInduction. Let A' (n : t) := forall m, m <= z -> n <= m -> A m. Let left_step := forall n, n < z -> A (S n) -> A n. Let left_step' := forall n, n <= z -> A' (S n) -> A n. Let left_step'' := forall n, A' n <-> A' (S n).A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, z <= m -> m < n0 -> A m:t -> Propright_step:=forall n0 : t, z <= n0 -> A n0 -> A (S n0):Propright_step':=forall n0 : t, z <= n0 -> A' n0 -> A n0:Propright_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropL:forall n0 : t, n0 <= z -> A n0R:right_step'n:tH:z < nz <= nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA z -> left_step -> left_step'A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA z -> left_step -> left_step'A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n <= zH2:A' (S n)A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n < zH2:A' (S n)A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n == zH2:A' (S n)A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n < zH2:A' (S n)A napply H2; [now apply le_succ_l | now apply eq_le_incl].A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n < zH2:A' (S n)A (S n)rewrite H1; apply Az. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropAz:A zLS:left_stepn:tH1:n == zH2:A' (S n)A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propleft_step' -> left_step''A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propleft_step' -> left_step''A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' nm:tH2:m <= zH3:S n <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' nm:tH2:m <= zH3:S n <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' nm:tH2:m <= zH3:n < mA mnow apply H1.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' nm:tH2:m <= zH3:n <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n < mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n == mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n < mA mnow apply H1.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:S n <= mA mrewrite <- H3 in *; now apply LS'. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m0 : t, m0 <= z -> n0 <= m0 -> A m0:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropLS':left_step'n:tH1:A' (S n)m:tH2:m <= zH3:n == mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA' (S z)A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA' (S z)A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m0 : t, m0 <= z -> n <= m0 -> A m0:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propm:tH1:m <= zH2:S z <= mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m0 : t, m0 <= z -> n <= m0 -> A m0:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propm:tH1:m <= zH2:z < mA mfalse_hyp H2 H1. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m0 : t, m0 <= z -> n <= m0 -> A m0:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propm:tH1:~ z < mH2:z < mA mA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, A' n) -> forall n : t, n <= z -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, A' n) -> forall n : t, n <= z -> A napply (H1 n); [assumption | now apply eq_le_incl]. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropH1:forall n0 : t, A' n0n:tH2:n <= zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propleft_step' -> forall n : t, n <= z -> A nintro LS'; apply A'A_left; unfold A'; nzinduct n (S z); [apply lbase | apply ls'_ls''; apply LS']. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Propleft_step' -> forall n : t, n <= z -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA z -> left_step -> forall n : t, n <= z -> A nintros Az LS; apply strong_left_induction; now apply ls_ls'. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):PropA z -> left_step -> forall n : t, n <= z -> A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, z <= n -> A n) -> left_step -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, z <= n -> A n) -> left_step -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zA zA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zleft_stepA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zn <= zA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zA znow apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zz <= zassumption.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zleft_stepnow apply lt_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n < zn <= zrewrite H; apply R; now apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:n == zA napply R; now apply lt_le_incl. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_stepn:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, z <= n -> A n) -> left_step' -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n : t => forall m : t, m <= z -> n <= m -> A m:t -> Propleft_step:=forall n : t, n < z -> A (S n) -> A n:Propleft_step':=forall n : t, n <= z -> A' (S n) -> A n:Propleft_step'':=forall n : t, A' n <-> A' (S n):Prop(forall n : t, z <= n -> A n) -> left_step' -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:n < zA nnow apply lt_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:n < zn <= zrewrite H; apply R; now apply eq_le_incl.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:n == zA napply R; now apply lt_le_incl. Qed. End LeftInduction.A:t -> PropA_wd:Proper (eq ==> iff) Az:tA':=fun n0 : t => forall m : t, m <= z -> n0 <= m -> A m:t -> Propleft_step:=forall n0 : t, n0 < z -> A (S n0) -> A n0:Propleft_step':=forall n0 : t, n0 <= z -> A' (S n0) -> A n0:Propleft_step'':=forall n0 : t, A' n0 <-> A' (S n0):PropR:forall n0 : t, z <= n0 -> A n0L:left_step'n:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA z -> (forall n : t, z <= n -> A n -> A (S n)) -> (forall n : t, n < z -> A (S n) -> A n) -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA z -> (forall n : t, z <= n -> A n -> A (S n)) -> (forall n : t, n < z -> A (S n) -> A n) -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:n < zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:n == zA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:z < nA nnow apply left_induction; [| | apply lt_le_incl].A:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:n < zA nnow rewrite H.A:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:n == zA nnow apply right_induction; [| | apply lt_le_incl]. Qed.A:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zRS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)LS:forall n0 : t, n0 < z -> A (S n0) -> A n0n:tH:z < nA nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA z -> (forall n : t, z <= n -> A n -> A (S n)) -> (forall n : t, n <= z -> A n -> A (P n)) -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tA z -> (forall n : t, z <= n -> A n -> A (S n)) -> (forall n : t, n <= z -> A n -> A (P n)) -> forall n : t, A nA:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zAS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)AP:forall n0 : t, n0 <= z -> A n0 -> A (P n0)n:tforall n0 : t, n0 < z -> A (S n0) -> A n0A:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zAS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)AP:forall n0 : t, n0 <= z -> A n0 -> A (P n0)n, m:tH1:m < zH2:A (S m)A mnow rewrite pred_succ in H2. Qed. End Center.A:t -> PropA_wd:Proper (eq ==> iff) Az:tAz:A zAS:forall n0 : t, z <= n0 -> A n0 -> A (S n0)AP:forall n0 : t, n0 <= z -> A n0 -> A (P n0)n, m:tH1:m < zH2:A (P (S m))A mProof (order_induction 0).A:t -> PropA_wd:Proper (eq ==> iff) AA 0 -> (forall n : t, 0 <= n -> A n -> A (S n)) -> (forall n : t, n < 0 -> A (S n) -> A n) -> forall n : t, A nProof (order_induction' 0).A:t -> PropA_wd:Proper (eq ==> iff) AA 0 -> (forall n : t, 0 <= n -> A n -> A (S n)) -> (forall n : t, n <= 0 -> A n -> A (P n)) -> forall n : t, A n
Elimintation principle for <
A:t -> PropA_wd:Proper (eq ==> iff) Aforall n : t, A (S n) -> (forall m : t, n < m -> A m -> A (S m)) -> forall m : t, n < m -> A mA:t -> PropA_wd:Proper (eq ==> iff) Aforall n : t, A (S n) -> (forall m : t, n < m -> A m -> A (S m)) -> forall m : t, n < m -> A mA:t -> PropA_wd:Proper (eq ==> iff) An:tH1:A (S n)H2:forall m0 : t, n < m0 -> A m0 -> A (S m0)m:tH3:n < mA mA:t -> PropA_wd:Proper (eq ==> iff) An:tH1:A (S n)H2:forall m0 : t, n < m0 -> A m0 -> A (S m0)m:tH3:n < mforall n0 : t, S n <= n0 -> A n0 -> A (S n0)now apply le_succ_l. Qed.A:t -> PropA_wd:Proper (eq ==> iff) An:tH1:A (S n)H2:forall m0 : t, n < m0 -> A m0 -> A (S m0)m:tH3:n < mn0:tH:S n <= n0H0:A n0n < n0
Elimination principle for <=
A:t -> PropA_wd:Proper (eq ==> iff) Aforall n : t, A n -> (forall m : t, n <= m -> A m -> A (S m)) -> forall m : t, n <= m -> A mA:t -> PropA_wd:Proper (eq ==> iff) Aforall n : t, A n -> (forall m : t, n <= m -> A m -> A (S m)) -> forall m : t, n <= m -> A mnow apply right_induction with n. Qed. End Induction. Tactic Notation "nzord_induct" ident(n) := induction_maker n ltac:(apply order_induction_0). Tactic Notation "nzord_induct" ident(n) constr(z) := induction_maker n ltac:(apply order_induction with z). Section WF. Variable z : t. Let Rlt (n m : t) := z <= n < m. Let Rgt (n m : t) := m < n <= z.A:t -> PropA_wd:Proper (eq ==> iff) An:tH1:A nH2:forall m0 : t, n <= m0 -> A m0 -> A (S m0)m:tH3:n <= mA mz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> eq ==> iff) Rltz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> eq ==> iff) Rltrewrite H1; now rewrite H2. Qed.z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propx1, x2:tH1:x1 == x2x3, x4:tH2:x3 == x4z <= x1 < x3 <-> z <= x2 < x4z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> eq ==> iff) Rgtintros x1 x2 H1 x3 x4 H2; unfold Rgt; rewrite H1; now rewrite H2. Qed.z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> eq ==> iff) Rgtz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propwell_founded Rltz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propwell_founded Rltz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall a : t, Acc Rlt az:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> iff) (Acc Rlt)z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, n <= z -> Acc Rlt nz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, z <= n -> (forall m : t, z <= m -> m < n -> Acc Rlt m) -> Acc Rlt nauto with typeclass_instances.z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> iff) (Acc Rlt)z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, n <= z -> Acc Rlt nz:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:n <= zy:tH1:z <= yH2:y < nAcc Rlt yz:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:n <= zy:tH1:z <= yH2:~ n <= yAcc Rlt ynow apply le_trans with z.z:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:n <= zy:tH1:z <= yH2:~ n <= yn <= yz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, z <= n -> (forall m : t, z <= m -> m < n -> Acc Rlt m) -> Acc Rlt nnow apply H2. Qed.z:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:z <= nH2:forall m0 : t, z <= m0 -> m0 < n -> Acc Rlt m0m:tH3:z <= mH4:m < nAcc Rlt mz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propwell_founded Rgtz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propwell_founded Rgtz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall a : t, Acc Rgt az:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> iff) (Acc Rgt)z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, z <= n -> Acc Rgt nz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, n <= z -> (forall m : t, m <= z -> S n <= m -> Acc Rgt m) -> Acc Rgt nauto with typeclass_instances.z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> PropProper (eq ==> iff) (Acc Rgt)z:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, z <= n -> Acc Rgt nz:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:z <= ny:tH1:n < yH2:y <= zAcc Rgt yz:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:z <= ny:tH1:n < yH2:FalseAcc Rgt yz:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:z <= ny:tH1:n < yH2:y <= zH0:forall n0 m : t, m < n0 -> ~ n0 <= mz < yelim H2.z:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:z <= ny:tH1:n < yH2:FalseAcc Rgt ynow apply le_lt_trans with n.z:tRlt:=fun n0 m : t => z <= n0 < m:t -> t -> PropRgt:=fun n0 m : t => m < n0 <= z:t -> t -> Propn:tH:z <= ny:tH1:n < yH2:y <= zH0:forall n0 m : t, m < n0 -> ~ n0 <= mz < yz:tRlt:=fun n m : t => z <= n < m:t -> t -> PropRgt:=fun n m : t => m < n <= z:t -> t -> Propforall n : t, n <= z -> (forall m : t, m <= z -> S n <= m -> Acc Rgt m) -> Acc Rgt nz:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:n <= zH2:forall m0 : t, m0 <= z -> S n <= m0 -> Acc Rgt m0m:tH3:n < mH4:m <= zAcc Rgt mz:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:n <= zH2:forall m0 : t, m0 <= z -> S n <= m0 -> Acc Rgt m0m:tH3:n < mH4:m <= zm <= zz:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:n <= zH2:forall m0 : t, m0 <= z -> S n <= m0 -> Acc Rgt m0m:tH3:n < mH4:m <= zS n <= massumption.z:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:n <= zH2:forall m0 : t, m0 <= z -> S n <= m0 -> Acc Rgt m0m:tH3:n < mH4:m <= zm <= znow apply le_succ_l. Qed. End WF. End NZOrderProp.z:tRlt:=fun n0 m0 : t => z <= n0 < m0:t -> t -> PropRgt:=fun n0 m0 : t => m0 < n0 <= z:t -> t -> Propn:tH1:n <= zH2:forall m0 : t, m0 <= z -> S n <= m0 -> Acc Rgt m0m:tH3:n < mH4:m <= zS n <= m
If we have moreover a compare function, we can build
an OrderedType structure.
(* Temporary workaround for bug #2949: remove this problematic + unused functor
Module NZOrderedType (NZ : NZDecOrdSig')
<: DecidableTypeFull <: OrderedTypeFull
:= NZ <+ NZBaseProp <+ NZOrderProp <+ Compare2EqBool <+ HasEqBool2Dec.
*)