1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
|
(************************************************************************)
(* * The Rocq Prover / The Rocq Development Team *)
(* v * Copyright INRIA, CNRS and contributors *)
(* <O___,, * (see version control and CREDITS file for authors & dates) *)
(* \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 *)
(************************************************************************)
From Stdlib Require Export NAdd.
Module NOrderProp (Import N : NAxiomsMiniSig').
Include NAddProp N.
(* Theorems that are true for natural numbers but not for integers *)
Theorem lt_wf_0 : well_founded lt.
Proof.
setoid_replace lt with (fun n m => 0 <= n < m).
- apply lt_wf.
- intros x y; split.
+ intro H; split; [apply le_0_l | assumption].
+ now intros [_ H].
Defined.
(* "le_0_l : forall n : N, 0 <= n" was proved in NBase.v *)
Theorem nlt_0_r : forall n, ~ n < 0.
Proof.
intro n; apply le_ngt. apply le_0_l.
Qed.
Theorem nle_succ_0 : forall n, ~ (S n <= 0).
Proof.
intros n H; apply le_succ_l in H; false_hyp H nlt_0_r.
Qed.
Theorem le_0_r : forall n, n <= 0 <-> n == 0.
Proof.
intros n; split; intro H.
- le_elim H; [false_hyp H nlt_0_r | assumption].
- now apply eq_le_incl.
Qed.
Theorem lt_0_succ : forall n, 0 < S n.
Proof.
intro n; induct n; [apply lt_succ_diag_r | intros n H; now apply lt_lt_succ_r].
Qed.
Theorem le_1_succ : forall n, 1 <= S n.
Proof.
intros n; rewrite one_succ; apply ->succ_le_mono; exact (le_0_l _).
Qed.
Theorem neq_0_lt_0 : forall n, n ~= 0 <-> 0 < n.
Proof.
intro n; cases n.
- split; intro H; [now elim H | intro; now apply lt_irrefl with 0].
- intro n; split; intro H; [apply lt_0_succ | apply neq_succ_0].
Qed.
Theorem neq_0_le_1 : forall n, n ~= 0 <-> 1 <= n.
Proof.
intros n; split.
- intros <-%succ_pred; exact (le_1_succ _).
- intros H E; rewrite E, one_succ in H; apply (nle_succ_0 0); exact H.
Qed.
Theorem eq_0_gt_0_cases : forall n, n == 0 \/ 0 < n.
Proof.
intro n; cases n.
- now left.
- intro; right; apply lt_0_succ.
Qed.
Theorem zero_one : forall n, n == 0 \/ n == 1 \/ 1 < n.
Proof.
setoid_rewrite one_succ.
intro n; induct n. { now left. }
intro n; cases n. { intros; right; now left. }
intros n IH. destruct IH as [H | [H | H]].
- false_hyp H neq_succ_0.
- right; right. rewrite H. apply lt_succ_diag_r.
- right; right. now apply lt_lt_succ_r.
Qed.
Theorem lt_1_r : forall n, n < 1 <-> n == 0.
Proof.
setoid_rewrite one_succ.
intro n; cases n.
- split; intro; [reflexivity | apply lt_succ_diag_r].
- intros n. rewrite <- succ_lt_mono.
split; intro H; [false_hyp H nlt_0_r | false_hyp H neq_succ_0].
Qed.
Theorem le_1_r : forall n, n <= 1 <-> n == 0 \/ n == 1.
Proof.
setoid_rewrite one_succ.
intro n; cases n.
- split; intro; [now left | apply le_succ_diag_r].
- intro n. rewrite <- succ_le_mono, le_0_r, succ_inj_wd.
split; [intro; now right | intros [H | H]; [false_hyp H neq_succ_0 | assumption]].
Qed.
Theorem lt_lt_0 : forall n m, n < m -> 0 < m.
Proof.
intros n m; induct n.
- trivial.
- intros n IH H. apply IH; now apply lt_succ_l.
Qed.
Theorem lt_1_l' : forall n m p, n < m -> m < p -> 1 < p.
Proof.
intros n m p H H0. apply lt_1_l with m; auto.
apply le_lt_trans with n; auto. now apply le_0_l.
Qed.
(** Elimination principlies for < and <= for relations *)
Section RelElim.
Variable R : relation N.t.
Hypothesis R_wd : Proper (N.eq==>N.eq==>iff) R.
Theorem le_ind_rel :
(forall m, R 0 m) ->
(forall n m, n <= m -> R n m -> R (S n) (S m)) ->
forall n m, n <= m -> R n m.
Proof.
intros Base Step n; induct n.
{ intros; apply Base. }
intros n IH m H. elim H using le_ind.
- solve_proper.
- apply Step; [| apply IH]; now apply eq_le_incl.
- intros k H1 H2. apply le_succ_l in H1. apply lt_le_incl in H1. auto.
Qed.
Theorem lt_ind_rel :
(forall m, R 0 (S m)) ->
(forall n m, n < m -> R n m -> R (S n) (S m)) ->
forall n m, n < m -> R n m.
Proof.
intros Base Step n; induct n.
- intros m H. apply lt_exists_pred in H; destruct H as [m' [H _]].
rewrite H; apply Base.
- intros n IH m H. elim H using lt_ind.
+ solve_proper.
+ apply Step; [| apply IH]; now apply lt_succ_diag_r.
+ intros k H1 H2. apply lt_succ_l in H1. auto.
Qed.
End RelElim.
(** Predecessor and order *)
Theorem succ_pred_pos : forall n, 0 < n -> S (P n) == n.
Proof.
intros n H; apply succ_pred; intro H1; rewrite H1 in H.
false_hyp H lt_irrefl.
Qed.
Theorem le_pred_l : forall n, P n <= n.
Proof.
intro n; cases n.
- rewrite pred_0; now apply eq_le_incl.
- intros; rewrite pred_succ; apply le_succ_diag_r.
Qed.
Theorem lt_pred_l : forall n, n ~= 0 -> P n < n.
Proof.
intro n; cases n.
- intro H; exfalso; now apply H.
- intros; rewrite pred_succ; apply lt_succ_diag_r.
Qed.
Theorem le_le_pred : forall n m, n <= m -> P n <= m.
Proof.
intros n m H; apply le_trans with n.
- apply le_pred_l.
- assumption.
Qed.
Theorem lt_lt_pred : forall n m, n < m -> P n < m.
Proof.
intros n m H; apply le_lt_trans with n.
- apply le_pred_l.
- assumption.
Qed.
Theorem lt_le_pred : forall n m, n < m -> n <= P m.
(* Converse is false for n == m == 0 *)
Proof.
intros n m; cases m.
- intro H; false_hyp H nlt_0_r.
- intros m IH. rewrite pred_succ; now apply lt_succ_r.
Qed.
Theorem lt_pred_le : forall n m, P n < m -> n <= m.
(* Converse is false for n == m == 0 *)
Proof.
intros n m; cases n.
- rewrite pred_0; intro H; now apply lt_le_incl.
- intros n IH. rewrite pred_succ in IH. now apply le_succ_l.
Qed.
Theorem lt_pred_lt : forall n m, n < P m -> n < m.
Proof.
intros n m H; apply lt_le_trans with (P m); [assumption | apply le_pred_l].
Qed.
Theorem le_pred_le : forall n m, n <= P m -> n <= m.
Proof.
intros n m H; apply le_trans with (P m); [assumption | apply le_pred_l].
Qed.
Theorem pred_le_mono : forall n m, n <= m -> P n <= P m.
(* Converse is false for n == 1, m == 0 *)
Proof.
intros n m H; elim H using le_ind_rel.
- solve_proper.
- intro; rewrite pred_0; apply le_0_l.
- intros p q H1 _; now do 2 rewrite pred_succ.
Qed.
Theorem pred_lt_mono : forall n m, n ~= 0 -> (n < m <-> P n < P m).
Proof.
intros n m H1; split; intro H2.
- assert (m ~= 0). { apply neq_0_lt_0. now apply lt_lt_0 with n. }
now rewrite <- (succ_pred n) in H2; rewrite <- (succ_pred m) in H2 ;
[apply succ_lt_mono | | |].
- assert (m ~= 0).
{ apply neq_0_lt_0. apply lt_lt_0 with (P n).
apply lt_le_trans with (P m).
- assumption.
- apply le_pred_l.
}
apply succ_lt_mono in H2. now do 2 rewrite succ_pred in H2.
Qed.
Theorem lt_succ_lt_pred : forall n m, S n < m <-> n < P m.
Proof.
intros n m. rewrite pred_lt_mono by apply neq_succ_0. now rewrite pred_succ.
Qed.
Theorem le_succ_le_pred : forall n m, S n <= m -> n <= P m.
(* Converse is false for n == m == 0 *)
Proof.
intros n m H. apply lt_le_pred. now apply le_succ_l.
Qed.
Theorem lt_pred_lt_succ : forall n m, P n < m -> n < S m.
(* Converse is false for n == m == 0 *)
Proof.
intros n m H. apply lt_succ_r. now apply lt_pred_le.
Qed.
Theorem le_pred_le_succ : forall n m, P n <= m <-> n <= S m.
Proof.
intros n m; cases n.
- rewrite pred_0. split; intro H; apply le_0_l.
- intro n. rewrite pred_succ. apply succ_le_mono.
Qed.
Lemma measure_induction : forall (X : Type) (f : X -> t) (A : X -> Type),
(forall x, (forall y, f y < f x -> A y) -> A x) ->
forall x, A x.
Proof.
intros X f A IH x. apply (measure_right_induction X f A 0); [|apply le_0_l].
intros y _ IH'. apply IH. intros. apply IH'. now split; [apply le_0_l|].
Defined.
(* This is kept private in order to drop the [Proper] condition in
implementations. *)
(* begin hide *)
Theorem Private_strong_induction_le {A : t -> Prop} :
Proper (eq ==> iff) A ->
A 0 -> (forall n, ((forall m, m <= n -> A m) -> A (S n))) -> (forall n, A n).
Proof.
intros H H0 sIH n.
enough (forall k, k <= n -> A k) as key. {
apply key; exact (le_refl _).
}
induct n.
- intros k ->%le_0_r; exact H0.
- intros n I k [Hk%lt_succ_r%I | ->]%lt_eq_cases.
+ exact Hk.
+ apply sIH; exact I.
Qed.
(* end hide *)
End NOrderProp.
|