Built with Alectryon, running Coq+SerAPI v8.18.0+0.18.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Spaces.Nat.Core.Local Set Universe Minimization ToSet.LocalClose Scope trunc_scope.LocalOpen Scope nat_scope.Ltacnat_absurd_trivial :=
unfold">"in *; unfold"<"in *;
match goal with
| [ H : ?n.+1 <= 0 |- _ ] => contradiction (not_leq_Sn_0 n H)
| [ H : ?n.+1 <= ?n |- _ ] => contradiction (not_lt_n_n n H)
| [ H1 : ?k.+1 <= ?n |- _ ] =>
match goal with
| [ H2 : ?n <= ?k |- _] =>
contradiction (not_leq_Sn_n k (@leq_trans _ _ _ H1 H2))
endend.#[export] Hint Resolve not_lt_n_n : nat.#[export] Hint Resolve not_lt_n_0 : nat.#[export] Hint Resolve not_leq_Sn_0 : nat.#[export] Hint Extern2 => nat_absurd_trivial : nat.(** This is defined so that it can be added to the [nat] auto hint database. *)Local Definitionsymmetric_paths_nat (nm : nat)
: n = m -> m = n := @symmetric_paths nat n m.Local Definitiontransitive_paths_nat (nmk : nat)
: n = m -> m = k -> n = k := @transitive_paths nat n m k.#[export] Hint Resolve symmetric_paths_nat | 5 : nat.#[export] Hint Resolve transitive_paths_nat : nat.#[export] Hint Resolve leq_0_n : nat.#[export] Hint Resolve leq_trans : nat.#[export] Hint Resolve leq_antisym : nat.
n, m, k: nat
n + (m + k) = n + m + k
n, m, k: nat
n + (m + k) = n + m + k
forallmk : nat, 0 + (m + k) = 0 + m + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k
forallmk : nat, n.+1 + (m + k) = n.+1 + m + k
forallmk : nat, 0 + (m + k) = 0 + m + k
reflexivity.
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k
forallmk : nat, n.+1 + (m + k) = n.+1 + m + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
n.+1 + (m + k) = n.+1 + m + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
(n + (m + k)).+1 = n.+1 + m + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
n + (m + k).+1 = n.+1 + m + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
n + (m.+1 + k) = (n + m).+1 + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
n + m.+1 + k = (n + m).+1 + k
n: nat IHn: forallmk : nat, n + (m + k) = n + m + k m, k: nat
n + m.+1 = (n + m).+1
apply symmetric_paths, nat_add_n_Sm.Defined.
n, m: nat
~ (n < m) -> m <= n
n, m: nat
~ (n < m) -> m <= n
n, m: nat not_lt: ~ (n < m)
m <= n
destruct (@leq_dichot m n); [ assumption | contradiction].Defined.
n, m: nat
~ (n <= m) -> m < n
n, m: nat
~ (n <= m) -> m < n
n, m: nat not_leq: ~ (n <= m)
m < n
destruct (@leq_dichot n m); [ contradiction | assumption].Defined.
n, m: nat
n < m -> ~ (m <= n)
n, m: nat
n < m -> ~ (m <= n)
n, m: nat ineq1: n < m ineq2: m <= n
Empty
n, m: nat ineq1: n < m ineq2: m <= n
n < n
byapply (leq_trans ineq1).Defined.
n, m: nat
n <= m -> ~ (m < n)
n, m: nat
n <= m -> ~ (m < n)
n, m: nat ineq1: n <= m ineq2: m < n
Empty
contradiction (not_lt_n_n n); byrefine (leq_trans _ ineq2).Defined.Ltacconvert_to_positive :=
match goal with
| [ H : ~ (?n < ?m) |- _] => apply not_lt_implies_geq in H
| [ H : ~ (?n <= ?m) |- _] => apply not_leq_implies_gt in H
| [|- ~ (?n < ?m) ] => apply leq_implies_not_gt
| [|- ~ (?n <= ?m) ] => apply lt_implies_not_geq
end.#[export] Hint Extern2 => convert_to_positive : nat.(** Because of the inductive definition of [<=], one can destruct the proof of [n <= m] and get a judgemental identification between [n] and [m] rather than a propositional one, which may be preferable to the following lemma. *)
n, m: nat
n <= m -> ((n < m) + (n = m))%type
n, m: nat
n <= m -> ((n < m) + (n = m))%type
n, m: nat l: n <= m
((n < m) + (n = m))%type
n: nat
((n < n) + (n = n))%type
n, m: nat l: n <= m IHl: ((n < m) + (n = m))%type
((n < m.+1) + (n = m.+1))%type
n: nat
((n < n) + (n = n))%type
nowright.
n, m: nat l: n <= m IHl: ((n < m) + (n = m))%type
((n < m.+1) + (n = m.+1))%type
n, m: nat l: n <= m IHl: ((n < m) + (n = m))%type
n < m.+1
exact (leq_S_n' _ _ l).Defined.
n, m: nat
n <> m -> ((n < m) + (n > m))%type
n, m: nat
n <> m -> ((n < m) + (n > m))%type
n, m: nat diseq: n <> m
((n < m) + (n > m))%type
n, m: nat diseq: n <> m a: ~ (n < m)
((n < m) + (n > m))%type
n, m: nat diseq: n <> m a: ~ (n < m)
n > m
n, m: nat diseq: n <> m a: ~ (n < m) n_leq_m: n <= m
contradiction (not_lt_n_n m).Defined.#[export] Hint Resolve lt_implies_diseq : nat.(** This lemma is just for convenience in the case where the user forgets to unfold the definition of [<]. *)
nowdestruct (symmetric_paths _ _ (sub_leq_0 n m _)).Defined.
n, m: nat
n <= m -> n + (m - n) = m
n, m: nat
n <= m -> n + (m - n) = m
n, m: nat H: n <= m
n + (m - n) = m
n, m: nat H: n <= m
m - n + n = m
n, m: nat H: n <= m
n <= m
assumption.Defined.#[export] Hint Rewrite -> natminuspluseq : nat.#[export] Hint Rewrite -> natminuspluseq' : nat.
n, m: nat
n <= m <~> {k : nat & k + n = m}
n, m: nat
n <= m <~> {k : nat & k + n = m}
n, m: nat
IsHProp {k : nat & k + n = m}
n, m: nat
n <= m -> {k : nat & k + n = m}
n, m: nat
{k : nat & k + n = m} -> n <= m
n, m: nat
IsHProp {k : nat & k + n = m}
n, m: nat
forallxy : {k : nat & k + n = m}, x = y
n, m, x: nat p: x + n = m y: nat q: y + n = m
(x; p) = (y; q)
n, m, x: nat p: x + n = m y: nat q: y + n = m r:= summand_is_sub x m n p @ (summand_is_sub y m n q)^: x = y
(x; p) = (y; q)
n, m, x: nat p, q: x + n = m
(x; p) = (x; q)
n, m, x: nat p, q: x + n = m
p = q
apply path_ishprop.
n, m: nat
n <= m -> {k : nat & k + n = m}
n, m: nat p: n <= m
{k : nat & k + n = m}
n, m: nat p: n <= m
m - n + n = m
apply natminuspluseq, p.
n, m: nat
{k : nat & k + n = m} -> n <= m
n, m, k: nat p: k + n = m
n <= m
n, k: nat
n <= k + n
apply leq_add.Defined.#[export] Hint Resolve leq_S_n' : nat.Ltacleq_S_n_in_hypotheses :=
match goal with
| [ H : ?n.+1 <= ?m.+1 |- _ ] => apply leq_S_n in H
| [ H : ?n < ?m.+1 |- _ ] => apply leq_S_n in H
| [ H : ?m.+1 > ?n |- _ ] => apply leq_S_n in H
| [ H : ?m.+1 >= ?n.+1 |- _ ] => apply leq_S_n in H
end.#[export] Hint Extern4 => leq_S_n_in_hypotheses : nat.
n, m, k: nat
n <= m -> n + k <= m + k
n, m, k: nat
n <= m -> n + k <= m + k
n, m, k: nat l: n <= m
n + k <= m + k
n, m: nat l: n <= m
n + 0 <= m + 0
n, m: nat l: n <= m k: nat IHk: n + k <= m + k
n + k.+1 <= m + k.+1
n, m: nat l: n <= m
n + 0 <= m + 0
destruct (add_n_O n), (add_n_O m); exact l.
n, m: nat l: n <= m k: nat IHk: n + k <= m + k
n + k.+1 <= m + k.+1
destruct (nat_add_n_Sm n k), (nat_add_n_Sm m k);
apply leq_S_n'; exact IHk.Defined.#[export] Hint Resolve nataddpreservesleq : nat.
n, m, k: nat
n <= m -> k + n <= k + m
n, m, k: nat
n <= m -> k + n <= k + m
n, m, k: nat
n <= m -> n + k <= m + k
exact nataddpreservesleq.Defined.#[export] Hint Resolve nataddpreservesleq' : nat.
n, m, k: nat
n < m -> n + k < m + k
n, m, k: nat
n < m -> n + k < m + k
n, m, k: nat
n.+1 <= m -> (n + k).+1 <= m + k
n, m, k: nat
n.+1 <= m -> n.+1 + k <= m + k
n, m, k: nat
foralln : nat, n <= m -> n + k <= m + k
n, m, k, n': nat l: n' <= m
n' + k <= m + k
n, m, n': nat l: n' <= m
n' + 0 <= m + 0
n, m, n': nat l: n' <= m k: nat IHk: n' + k <= m + k
n' + k.+1 <= m + k.+1
n, m, n': nat l: n' <= m
n' + 0 <= m + 0
destruct (add_n_O n'), (add_n_O m); exact l.
n, m, n': nat l: n' <= m k: nat IHk: n' + k <= m + k
n' + k.+1 <= m + k.+1
destruct (nat_add_n_Sm n' k), (nat_add_n_Sm m k);
apply leq_S_n'; exact IHk.Defined.
n, m, k: nat
n < m -> k + n < k + m
n, m, k: nat
n < m -> k + n < k + m
destruct (symmetric_paths _ _ (nat_add_comm k n)),
(symmetric_paths _ _ (nat_add_comm k m));
exact nataddpreserveslt.Defined.
n, m, k: nat
n + k < m + k -> n < m
n, m, k: nat
n + k < m + k -> n < m
n, m: nat
n + 0 < m + 0 -> n < m
n, m, k: nat IHk: n + k < m + k -> n < m
n + k.+1 < m + k.+1 -> n < m
n, m: nat
n + 0 < m + 0 -> n < m
destruct (add_n_O n), (add_n_O m); trivial.
n, m, k: nat IHk: n + k < m + k -> n < m
n + k.+1 < m + k.+1 -> n < m
n, m, k: nat IHk: n + k < m + k -> n < m l: n + k.+1 < m + k.+1
n < m
n, m, k: nat IHk: n + k < m + k -> n < m l: (n + k).+1 < (m + k).+1
n < m
apply leq_S_n, IHk in l; exact l.Defined.
n, m, k: nat
n + k <= m + k -> n <= m
n, m, k: nat
n + k <= m + k -> n <= m
m, k: nat
0 + k <= m + k -> 0 <= m
n, m, k: nat
n.+1 + k <= m + k -> n.+1 <= m
m, k: nat
0 + k <= m + k -> 0 <= m
intros ?; apply leq_0_n.
n, m, k: nat
n.+1 + k <= m + k -> n.+1 <= m
n, m, k: nat a: n.+1 + k <= m + k
n.+1 <= m
n, m, k: nat a: (n + k).+1 <= m + k
n.+1 <= m
nowapply (@nataddreflectslt n m k).Defined.
n, m, k: nat
k + n < k + m -> n < m
n, m, k: nat
k + n < k + m -> n < m
destruct (symmetric_paths _ _ (nat_add_comm k n)),
(symmetric_paths _ _ (nat_add_comm k m));
exact nataddreflectslt.Defined.
n, m, k: nat
k + n <= k + m -> n <= m
n, m, k: nat
k + n <= k + m -> n <= m
destruct (symmetric_paths _ _ (nat_add_comm k n)),
(symmetric_paths _ _ (nat_add_comm k m));
exact nataddreflectsleq.Defined.
n, m, k: nat
k <= m -> n - k <= m - k -> n <= m
n, m, k: nat
k <= m -> n - k <= m - k -> n <= m
n, m, k: nat ineq1: k <= m ineq2: n - k <= m - k
n <= m
n, m, k: nat ineq1: k <= m ineq2: n - k + k <= m - k + k
n <= m
n, m, k: nat ineq1: k <= m ineq2: n - k + k <= m - k + k
n - k + k <= m
n, m, k: nat ineq1: k <= m ineq2: n - k + k <= m - k + k
m - k + k <= m
destruct (symmetric_paths _ _ (natminuspluseq k m ineq1)); easy.Defined.
k, m: nat
k <= m -> m.+1 - k = (m - k).+1
k, m: nat
k <= m -> m.+1 - k = (m - k).+1
forallm : nat, 0 <= m -> m.+1 - 0 = (m - 0).+1
k: nat IHk: forallm : nat, k <= m -> m.+1 - k = (m - k).+1
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n - k.+1 <= m - k.+1
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n - (1 + k) <= m - (1 + k)
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n - (k + 1) <= m - (k + 1)
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n - k - 1 <= m - (k + 1)
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n - k - 1 <= m - k - 1
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
pred (n - k) <= m - k - 1
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
pred (n - k) <= pred (m - k)
n, m, k: nat IHk: n <= m -> n - k <= m - k l: n <= m
n <= m
exact l.Defined.#[export] Hint Resolve natsubpreservesleq : nat.
n, k: nat
n - k <= n
n, k: nat
n - k <= n
n: nat
forallk : nat, n - k <= n
forallk : nat, 0 - k <= 0
n: nat IHn: forallk : nat, n - k <= n
forallk : nat, n.+1 - k <= n.+1
forallk : nat, 0 - k <= 0
intros; apply leq_0_n.
n: nat IHn: forallk : nat, n - k <= n
forallk : nat, n.+1 - k <= n.+1
n: nat IHn: forallk : nat, n - k <= n
n.+1 - 0 <= n.+1
n: nat IHn: forallk : nat, n - k <= n k: nat
n.+1 - k.+1 <= n.+1
n: nat IHn: forallk : nat, n - k <= n
n.+1 - 0 <= n.+1
apply leq_n.
n: nat IHn: forallk : nat, n - k <= n k: nat
n.+1 - k.+1 <= n.+1
simpl; apply (@leq_trans _ n _);
[ apply IHn | apply leq_S, leq_n].Defined.#[export] Hint Resolve sub_less : nat.#[export] Hint Resolve leq_S_n' : nat.
n, k: nat
0 < n -> 0 < k -> n - k < n
n, k: nat
0 < n -> 0 < k -> n - k < n
n, k: nat l: 0 < n l': 0 < k
n - k < n
n, k: nat l: 0 < n l': 0 < k
(n - k).+1 <= n
n, k: nat l: 0 < n.+1 l': 0 < k.+1
(n.+1 - k.+1).+1 <= n.+1
simpl; apply leq_S_n', sub_less.Defined.
k, m, n: nat
n <= k -> k < n + m -> k - n < m
k, m, n: nat
n <= k -> k < n + m -> k - n < m
k, m, n: nat l: n <= k q: k < n + m
k - n < m
k, m, n: nat l: n <= k q: k < n + m q': k - n + n < m + n
k - n < m
exact (nataddreflectslt q').Defined.#[export] Hint Resolve natpmswap1 : nat.
k, m, n: nat
n <= k -> k - n <= m -> k <= n + m
k, m, n: nat
n <= k -> k - n <= m -> k <= n + m
k, m, n: nat l: n <= k q: k - n <= m
k <= n + m
k, m, n: nat l: n <= k q: n + (k - n) <= n + m
k <= n + m
k, m, n: nat l: n <= k q: n + k - n <= n + m
k <= n + m
destruct (symmetric_paths _ _ (add_n_sub_n_eq' k n)) in q;
assumption.Defined.#[export] Hint Resolve natpmswap2 : nat.
k, m, n: nat
k <= n -> m <= n - k -> k + m <= n
k, m, n: nat
k <= n -> m <= n - k -> k + m <= n
k, m, n: nat ineq: k <= n qe: m <= n - k
k + m <= n
k, m, n: nat ineq: k <= n qe: k + m <= k + (n - k)
k + m <= n
k, m, n: nat ineq: k <= n qe: k + m <= k + n - k
k + m <= n
destruct (symmetric_paths _ _ (add_n_sub_n_eq' n k)) in qe;
assumption.Defined.#[export] Hint Resolve natpmswap3 : nat.
k, m, n: nat
k - n < m -> k < n + m
k, m, n: nat
k - n < m -> k < n + m
k, m, n: nat l: k - n + n < m + n
k < n + m
k, m, n: nat l: k - n + n < m + n
k < m + n
nowapply (mixed_trans1 k (k - n + n) (m + n)
(nat_sub_add_ineq _ _)).Defined.#[export] Hint Resolve natpmswap4 : nat.
n, m, k: nat
n <= m -> n <= m + k
n, m, k: nat
n <= m -> n <= m + k
intro l; apply (leq_trans l); exact (n_leq_add_n_k m k).Defined.
n, n', m, m': nat
n <= m -> n' <= m' -> n + n' <= m + m'
n, n', m, m': nat
n <= m -> n' <= m' -> n + n' <= m + m'
foralln'mm' : nat,
0 <= m -> n' <= m' -> 0 + n' <= m + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m'
foralln'mm' : nat,
n.+1 <= m -> n' <= m' -> n.+1 + n' <= m + m'
foralln'mm' : nat,
0 <= m -> n' <= m' -> 0 + n' <= m + m'
n', m, m': nat l: 0 <= m l': n' <= m'
0 + n' <= m + m'
n', m, m': nat l: 0 <= m l': n' <= m'
n' <= m + m'
n', m, m': nat l: 0 <= m l': n' <= m'
m' <= m + m'
exact (n_leq_add_n_k' m' m).
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m'
foralln'mm' : nat,
n.+1 <= m -> n' <= m' -> n.+1 + n' <= m + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n': nat
forallm' : nat,
n.+1 <= 0 -> n' <= m' -> n.+1 + n' <= 0 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m: nat
forallm' : nat,
n.+1 <= m.+1 -> n' <= m' -> n.+1 + n' <= m.+1 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n': nat
forallm' : nat,
n.+1 <= 0 -> n' <= m' -> n.+1 + n' <= 0 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m': nat H: n.+1 <= 0 H0: n' <= m'
n.+1 + n' <= 0 + m'
contradiction (not_leq_Sn_0 n).
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m: nat
forallm' : nat,
n.+1 <= m.+1 -> n' <= m' -> n.+1 + n' <= m.+1 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n.+1 <= m.+1 l': n' <= m'
n.+1 + n' <= m.+1 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
n.+1 + n' <= m.+1 + m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
(n + n').+1 <= (m + m').+1
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
n <= m
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
n' <= m'
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
n <= m
exact l.
n: nat IHn: foralln'mm' : nat, n <= m -> n' <= m' -> n + n' <= m + m' n', m, m': nat l: n <= m l': n' <= m'
n' <= m'
exact l'.Defined.#[export] Hint Resolve nat_add_bifunctor : nat.#[export] Hint Resolve nataddpreserveslt : nat.#[export] Hint Resolve nataddpreservesleq' : nat.#[export] Hint Resolve nataddpreserveslt' : nat.#[export] Hint Resolve natineq0eq0 : nat.#[export] Hint Resolve n_leq_add_n_k : nat.#[export] Hint Resolve n_leq_m_n_leq_plus_m_k : nat.#[export] Hint Immediate add_n_sub_n_eq : nat.#[export] Hint Immediate add_n_sub_n_eq' : nat.#[export] Hint Rewrite <- add_n_O : nat.#[export] Hint Rewrite -> add_O_n : nat.#[export] Hint Rewrite -> add_n_sub_n_eq : nat.#[export] Hint Rewrite -> add_n_sub_n_eq' : nat.#[export] Hint Rewrite -> nataddsub_assoc : nat.Ltacautorewrite_or_fail := progressltac:(autorewrite with nat).#[export] Hint Extern7 => autorewrite_or_fail : nat.
P: nat -> Type
(foralln : nat, (forallm : nat, m < n -> P m) -> P n) ->
foralln : nat, P n
P: nat -> Type
(foralln : nat, (forallm : nat, m < n -> P m) -> P n) ->
foralln : nat, P n
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n
foralln : nat, P n
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n
forallnm : nat, m < n -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n X: forallnm : nat, m < n -> P m
foralln : nat, P n
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n
forallnm : nat, m < n -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n
forallm : nat, m < 0 -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n -> P m
forallm : nat, m < n.+1 -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n
forallm : nat, m < 0 -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n m: nat l: m < 0
P m
contradiction (not_lt_n_0 m).
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n -> P m
forallm : nat, m < n.+1 -> P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n -> P m m: nat l: m < n.+1
P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n -> P m m: nat l: m <= n
P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n m: nat IHn: forallm0 : nat, m0 < m -> P m0
P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n.+1 -> P m m: nat l: m <= n
P m
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n m: nat IHn: forallm0 : nat, m0 < m -> P m0
P m
apply a; intros ? ?; nowapply IHn.
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n n: nat IHn: forallm : nat, m < n.+1 -> P m m: nat l: m <= n
P m
nowapply (IHn m), leq_S_n'.
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n X: forallnm : nat, m < n -> P m
foralln : nat, P n
P: nat -> Type a: foralln : nat,
(forallm : nat, m < n -> P m) -> P n X: forallnm : nat, m < n -> P m n: nat
P n
apply (X (n.+1) n), (leq_n n.+1).Defined.(** This inductive type is defined because it lets you loop from [i = 0] up to [i = n] by structural induction on a proof of [increasing_geq n 0]. With the existing [leq] type and the inductive structure of [n], it is easier and more natural to loop downwards from [i = n] to [i = 0], but harder to find the least natural number in the interval $[0,n]$ satisfying a given property. *)Local Unset Elimination Schemes.Inductiveincreasing_geq (n : nat) : nat -> Type0 :=
| increasing_geq_n : increasing_geq n n
| increasing_geq_S (m : nat) : increasing_geq n m.+1 ->
increasing_geq n m.Schemeincreasing_geq_ind := Induction for increasing_geq SortType.Schemeincreasing_geq_rec := Minimality for increasing_geq SortType.Definitionincreasing_geq_rect := increasing_geq_rec.Local Set Elimination Schemes.
n, m: nat
increasing_geq n m -> increasing_geq n.+1 m.+1
n, m: nat
increasing_geq n m -> increasing_geq n.+1 m.+1
n, m: nat a: increasing_geq n m
increasing_geq n.+1 m.+1
n: nat
increasing_geq n.+1 n.+1
n, m: nat a: increasing_geq n m.+1 IHa: increasing_geq n.+1 m.+2
increasing_geq n.+1 m.+1
n: nat
increasing_geq n.+1 n.+1
constructor.
n, m: nat a: increasing_geq n m.+1 IHa: increasing_geq n.+1 m.+2
increasing_geq n.+1 m.+1
nowconstructor.Defined.
n: nat
increasing_geq n 0
n: nat
increasing_geq n 0
increasing_geq 00
n: nat IHn: increasing_geq n 0
increasing_geq n.+10
increasing_geq 00
constructor.
n: nat IHn: increasing_geq n 0
increasing_geq n.+10
n: nat
increasing_geq n.+1 n
n, m: nat IHn: increasing_geq n m.+1 IHIHn: increasing_geq n.+1 m.+1
increasing_geq n.+1 m
n: nat
increasing_geq n.+1 n
constructor; nowconstructor.
n, m: nat IHn: increasing_geq n m.+1 IHIHn: increasing_geq n.+1 m.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n
forallm : nat, n.+1 <= m -> m - (m - n.+1) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m
m - (m - n.+1) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m
m - (m - (1 + n)) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m
m - (m - (n + 1)) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m
m - (m - n - 1) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m
m - pred (m - n) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m dp: 0 < m - n
m - pred (m - n) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m dp: 0 < m - n sh: pred (m - n) < m
m - pred (m - n) = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m dp: 0 < m - n sh: pred (m - n) < m
(m - (pred (m - n)).+1).+1 = n.+1
n: nat IHn: forallm : nat, n <= m -> m - (m - n) = n m: nat ineq: n.+1 <= m dp: 0 < m - n sh: pred (m - n) < m
(m - (m - n)).+1 = n.+1
apply (ap S), IHn, leq_S', ineq.Defined.
n, m: nat
n <= m <-> increasing_geq m n
n, m: nat
n <= m <-> increasing_geq m n
n, m: nat
n <= m -> increasing_geq m n
n, m: nat
increasing_geq m n -> n <= m
n, m: nat
n <= m -> increasing_geq m n
n, m: nat ineq: n <= m
increasing_geq m n
n: nat
increasing_geq n n
n, m: nat ineq: n <= m IHineq: increasing_geq m n
increasing_geq m.+1 n
n: nat
increasing_geq n n
constructor.
n, m: nat ineq: n <= m IHineq: increasing_geq m n
increasing_geq m.+1 n
apply increasing_geq_S_n in IHineq; constructor; assumption.
n, m: nat
increasing_geq m n -> n <= m
n, m: nat a: increasing_geq m n
n <= m
m: nat
m <= m
m, m0: nat a: increasing_geq m m0.+1 IHa: m0.+1 <= m
m0 <= m
m: nat
m <= m
constructor.
m, m0: nat a: increasing_geq m m0.+1 IHa: m0.+1 <= m
m0 <= m
exact (leq_S' _ _ _).Defined.(** This tautology accepts a (potentially opaqued or QED'ed) proof of [n <= m], and returns a transparent proof which can be computed with (i.e., one can loop from n to m) *)
n, m: nat
n <= m -> n <= m
n, m: nat
n <= m -> n <= m
n, m: nat ineq: n <= m
n <= m
n, m: nat ineq, l: n <= m
n <= m
n, m: nat ineq: n <= m g: n > m
n <= m
n, m: nat ineq, l: n <= m
n <= m
exact l.
n, m: nat ineq: n <= m g: n > m
n <= m
contradiction (not_lt_n_n m (@mixed_trans2 _ _ _ g ineq)).Defined.
R: nat -> nat -> Type p: Symmetric R p': Reflexive R
(forallnm : nat, n < m -> R n m) ->
forallnm : nat, R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R
(forallnm : nat, n < m -> R n m) ->
forallnm : nat, R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat
R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat m_leq_n: m <= n
R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat m_gt_n: m > n
R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat m_leq_n: m <= n
R n m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat m_leq_n: m <= n
R m n
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m: nat
R m m
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m, m0: nat m_leq_n: m <= m0
R m m0.+1
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m: nat
R m m
applyreflexivity.
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m, m0: nat m_leq_n: m <= m0
R m m0.+1
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m, m0: nat m_leq_n: m <= m0
m < m0.+1
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m m, m0: nat m_leq_n: m <= m0
m <= m0
assumption.
R: nat -> nat -> Type p: Symmetric R p': Reflexive R A: forallnm : nat, n < m -> R n m n, m: nat m_gt_n: m > n