| author | wenzelm | 
| Sat, 15 Oct 2005 00:08:05 +0200 | |
| changeset 17856 | 0551978bfda5 | 
| parent 17702 | ea88ddeafabe | 
| child 18648 | 22f96cd085d5 | 
| permissions | -rw-r--r-- | 
| 923 | 1 | (* Title: HOL/Nat.thy | 
| 2 | ID: $Id$ | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 3 | Author: Tobias Nipkow and Lawrence C Paulson | 
| 923 | 4 | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 5 | Type "nat" is a linear order, and a datatype; arithmetic operators + - | 
| 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 6 | and * (for div, mod and dvd, see theory Divides). | 
| 923 | 7 | *) | 
| 8 | ||
| 13449 | 9 | header {* Natural numbers *}
 | 
| 10 | ||
| 15131 | 11 | theory Nat | 
| 15140 | 12 | imports Wellfounded_Recursion Ring_and_Field | 
| 15131 | 13 | begin | 
| 13449 | 14 | |
| 15 | subsection {* Type @{text ind} *}
 | |
| 16 | ||
| 17 | typedecl ind | |
| 18 | ||
| 19 | consts | |
| 20 | Zero_Rep :: ind | |
| 21 | Suc_Rep :: "ind => ind" | |
| 22 | ||
| 23 | axioms | |
| 24 |   -- {* the axiom of infinity in 2 parts *}
 | |
| 25 | inj_Suc_Rep: "inj Suc_Rep" | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 26 | Suc_Rep_not_Zero_Rep: "Suc_Rep x \<noteq> Zero_Rep" | 
| 17702 | 27 | finalconsts | 
| 28 | Zero_Rep | |
| 29 | Suc_Rep | |
| 13449 | 30 | |
| 31 | subsection {* Type nat *}
 | |
| 32 | ||
| 33 | text {* Type definition *}
 | |
| 34 | ||
| 35 | consts | |
| 36 | Nat :: "ind set" | |
| 37 | ||
| 38 | inductive Nat | |
| 39 | intros | |
| 40 | Zero_RepI: "Zero_Rep : Nat" | |
| 41 | Suc_RepI: "i : Nat ==> Suc_Rep i : Nat" | |
| 42 | ||
| 43 | global | |
| 44 | ||
| 45 | typedef (open Nat) | |
| 14208 | 46 | nat = Nat by (rule exI, rule Nat.Zero_RepI) | 
| 13449 | 47 | |
| 14691 | 48 | instance nat :: "{ord, zero, one}" ..
 | 
| 13449 | 49 | |
| 50 | ||
| 51 | text {* Abstract constants and syntax *}
 | |
| 52 | ||
| 53 | consts | |
| 54 | Suc :: "nat => nat" | |
| 55 | pred_nat :: "(nat * nat) set" | |
| 56 | ||
| 57 | local | |
| 58 | ||
| 59 | defs | |
| 60 | Zero_nat_def: "0 == Abs_Nat Zero_Rep" | |
| 61 | Suc_def: "Suc == (%n. Abs_Nat (Suc_Rep (Rep_Nat n)))" | |
| 62 | One_nat_def [simp]: "1 == Suc 0" | |
| 63 | ||
| 64 |   -- {* nat operations *}
 | |
| 65 |   pred_nat_def: "pred_nat == {(m, n). n = Suc m}"
 | |
| 66 | ||
| 67 | less_def: "m < n == (m, n) : trancl pred_nat" | |
| 68 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 69 | le_def: "m \<le> (n::nat) == ~ (n < m)" | 
| 13449 | 70 | |
| 71 | ||
| 72 | text {* Induction *}
 | |
| 923 | 73 | |
| 13449 | 74 | theorem nat_induct: "P 0 ==> (!!n. P n ==> P (Suc n)) ==> P n" | 
| 75 | apply (unfold Zero_nat_def Suc_def) | |
| 76 |   apply (rule Rep_Nat_inverse [THEN subst]) -- {* types force good instantiation *}
 | |
| 77 | apply (erule Rep_Nat [THEN Nat.induct]) | |
| 17589 | 78 | apply (iprover elim: Abs_Nat_inverse [THEN subst]) | 
| 13449 | 79 | done | 
| 80 | ||
| 81 | text {* Distinctness of constructors *}
 | |
| 82 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 83 | lemma Suc_not_Zero [iff]: "Suc m \<noteq> 0" | 
| 15413 | 84 | by (simp add: Zero_nat_def Suc_def Abs_Nat_inject Rep_Nat Suc_RepI Zero_RepI | 
| 85 | Suc_Rep_not_Zero_Rep) | |
| 13449 | 86 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 87 | lemma Zero_not_Suc [iff]: "0 \<noteq> Suc m" | 
| 13449 | 88 | by (rule not_sym, rule Suc_not_Zero not_sym) | 
| 89 | ||
| 90 | lemma Suc_neq_Zero: "Suc m = 0 ==> R" | |
| 91 | by (rule notE, rule Suc_not_Zero) | |
| 92 | ||
| 93 | lemma Zero_neq_Suc: "0 = Suc m ==> R" | |
| 94 | by (rule Suc_neq_Zero, erule sym) | |
| 95 | ||
| 96 | text {* Injectiveness of @{term Suc} *}
 | |
| 97 | ||
| 16733 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 98 | lemma inj_Suc[simp]: "inj_on Suc N" | 
| 15413 | 99 | by (simp add: Suc_def inj_on_def Abs_Nat_inject Rep_Nat Suc_RepI | 
| 100 | inj_Suc_Rep [THEN inj_eq] Rep_Nat_inject) | |
| 13449 | 101 | |
| 102 | lemma Suc_inject: "Suc x = Suc y ==> x = y" | |
| 103 | by (rule inj_Suc [THEN injD]) | |
| 104 | ||
| 105 | lemma Suc_Suc_eq [iff]: "(Suc m = Suc n) = (m = n)" | |
| 15413 | 106 | by (rule inj_Suc [THEN inj_eq]) | 
| 13449 | 107 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 108 | lemma nat_not_singleton: "(\<forall>x. x = (0::nat)) = False" | 
| 13449 | 109 | by auto | 
| 110 | ||
| 111 | text {* @{typ nat} is a datatype *}
 | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 112 | |
| 5188 
633ec5f6c155
Declaration of type 'nat' as a datatype (this allows usage of
 berghofe parents: 
4640diff
changeset | 113 | rep_datatype nat | 
| 13449 | 114 | distinct Suc_not_Zero Zero_not_Suc | 
| 115 | inject Suc_Suc_eq | |
| 116 | induction nat_induct | |
| 117 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 118 | lemma n_not_Suc_n: "n \<noteq> Suc n" | 
| 13449 | 119 | by (induct n) simp_all | 
| 120 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 121 | lemma Suc_n_not_n: "Suc t \<noteq> t" | 
| 13449 | 122 | by (rule not_sym, rule n_not_Suc_n) | 
| 123 | ||
| 124 | text {* A special form of induction for reasoning
 | |
| 125 |   about @{term "m < n"} and @{term "m - n"} *}
 | |
| 126 | ||
| 127 | theorem diff_induct: "(!!x. P x 0) ==> (!!y. P 0 (Suc y)) ==> | |
| 128 | (!!x y. P x y ==> P (Suc x) (Suc y)) ==> P m n" | |
| 14208 | 129 | apply (rule_tac x = m in spec) | 
| 15251 | 130 | apply (induct n) | 
| 13449 | 131 | prefer 2 | 
| 132 | apply (rule allI) | |
| 17589 | 133 | apply (induct_tac x, iprover+) | 
| 13449 | 134 | done | 
| 135 | ||
| 136 | subsection {* Basic properties of "less than" *}
 | |
| 137 | ||
| 138 | lemma wf_pred_nat: "wf pred_nat" | |
| 14208 | 139 | apply (unfold wf_def pred_nat_def, clarify) | 
| 140 | apply (induct_tac x, blast+) | |
| 13449 | 141 | done | 
| 142 | ||
| 143 | lemma wf_less: "wf {(x, y::nat). x < y}"
 | |
| 144 | apply (unfold less_def) | |
| 14208 | 145 | apply (rule wf_pred_nat [THEN wf_trancl, THEN wf_subset], blast) | 
| 13449 | 146 | done | 
| 147 | ||
| 148 | lemma less_eq: "((m, n) : pred_nat^+) = (m < n)" | |
| 149 | apply (unfold less_def) | |
| 150 | apply (rule refl) | |
| 151 | done | |
| 152 | ||
| 153 | subsubsection {* Introduction properties *}
 | |
| 154 | ||
| 155 | lemma less_trans: "i < j ==> j < k ==> i < (k::nat)" | |
| 156 | apply (unfold less_def) | |
| 14208 | 157 | apply (rule trans_trancl [THEN transD], assumption+) | 
| 13449 | 158 | done | 
| 159 | ||
| 160 | lemma lessI [iff]: "n < Suc n" | |
| 161 | apply (unfold less_def pred_nat_def) | |
| 162 | apply (simp add: r_into_trancl) | |
| 163 | done | |
| 164 | ||
| 165 | lemma less_SucI: "i < j ==> i < Suc j" | |
| 14208 | 166 | apply (rule less_trans, assumption) | 
| 13449 | 167 | apply (rule lessI) | 
| 168 | done | |
| 169 | ||
| 170 | lemma zero_less_Suc [iff]: "0 < Suc n" | |
| 171 | apply (induct n) | |
| 172 | apply (rule lessI) | |
| 173 | apply (erule less_trans) | |
| 174 | apply (rule lessI) | |
| 175 | done | |
| 176 | ||
| 177 | subsubsection {* Elimination properties *}
 | |
| 178 | ||
| 179 | lemma less_not_sym: "n < m ==> ~ m < (n::nat)" | |
| 180 | apply (unfold less_def) | |
| 181 | apply (blast intro: wf_pred_nat wf_trancl [THEN wf_asym]) | |
| 182 | done | |
| 183 | ||
| 184 | lemma less_asym: | |
| 185 | assumes h1: "(n::nat) < m" and h2: "~ P ==> m < n" shows P | |
| 186 | apply (rule contrapos_np) | |
| 187 | apply (rule less_not_sym) | |
| 188 | apply (rule h1) | |
| 189 | apply (erule h2) | |
| 190 | done | |
| 191 | ||
| 192 | lemma less_not_refl: "~ n < (n::nat)" | |
| 193 | apply (unfold less_def) | |
| 194 | apply (rule wf_pred_nat [THEN wf_trancl, THEN wf_not_refl]) | |
| 195 | done | |
| 196 | ||
| 197 | lemma less_irrefl [elim!]: "(n::nat) < n ==> R" | |
| 198 | by (rule notE, rule less_not_refl) | |
| 199 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 200 | lemma less_not_refl2: "n < m ==> m \<noteq> (n::nat)" by blast | 
| 13449 | 201 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 202 | lemma less_not_refl3: "(s::nat) < t ==> s \<noteq> t" | 
| 13449 | 203 | by (rule not_sym, rule less_not_refl2) | 
| 204 | ||
| 205 | lemma lessE: | |
| 206 | assumes major: "i < k" | |
| 207 | and p1: "k = Suc i ==> P" and p2: "!!j. i < j ==> k = Suc j ==> P" | |
| 208 | shows P | |
| 14208 | 209 | apply (rule major [unfolded less_def pred_nat_def, THEN tranclE], simp_all) | 
| 13449 | 210 | apply (erule p1) | 
| 211 | apply (rule p2) | |
| 14208 | 212 | apply (simp add: less_def pred_nat_def, assumption) | 
| 13449 | 213 | done | 
| 214 | ||
| 215 | lemma not_less0 [iff]: "~ n < (0::nat)" | |
| 216 | by (blast elim: lessE) | |
| 217 | ||
| 218 | lemma less_zeroE: "(n::nat) < 0 ==> R" | |
| 219 | by (rule notE, rule not_less0) | |
| 220 | ||
| 221 | lemma less_SucE: assumes major: "m < Suc n" | |
| 222 | and less: "m < n ==> P" and eq: "m = n ==> P" shows P | |
| 223 | apply (rule major [THEN lessE]) | |
| 14208 | 224 | apply (rule eq, blast) | 
| 225 | apply (rule less, blast) | |
| 13449 | 226 | done | 
| 227 | ||
| 228 | lemma less_Suc_eq: "(m < Suc n) = (m < n | m = n)" | |
| 229 | by (blast elim!: less_SucE intro: less_trans) | |
| 230 | ||
| 231 | lemma less_one [iff]: "(n < (1::nat)) = (n = 0)" | |
| 232 | by (simp add: less_Suc_eq) | |
| 233 | ||
| 234 | lemma less_Suc0 [iff]: "(n < Suc 0) = (n = 0)" | |
| 235 | by (simp add: less_Suc_eq) | |
| 236 | ||
| 237 | lemma Suc_mono: "m < n ==> Suc m < Suc n" | |
| 238 | by (induct n) (fast elim: less_trans lessE)+ | |
| 239 | ||
| 240 | text {* "Less than" is a linear ordering *}
 | |
| 241 | lemma less_linear: "m < n | m = n | n < (m::nat)" | |
| 15251 | 242 | apply (induct m) | 
| 243 | apply (induct n) | |
| 13449 | 244 | apply (rule refl [THEN disjI1, THEN disjI2]) | 
| 245 | apply (rule zero_less_Suc [THEN disjI1]) | |
| 246 | apply (blast intro: Suc_mono less_SucI elim: lessE) | |
| 247 | done | |
| 248 | ||
| 14302 | 249 | text {* "Less than" is antisymmetric, sort of *}
 | 
| 250 | lemma less_antisym: "\<lbrakk> \<not> n < m; n < Suc m \<rbrakk> \<Longrightarrow> m = n" | |
| 251 | apply(simp only:less_Suc_eq) | |
| 252 | apply blast | |
| 253 | done | |
| 254 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 255 | lemma nat_neq_iff: "((m::nat) \<noteq> n) = (m < n | n < m)" | 
| 13449 | 256 | using less_linear by blast | 
| 257 | ||
| 258 | lemma nat_less_cases: assumes major: "(m::nat) < n ==> P n m" | |
| 259 | and eqCase: "m = n ==> P n m" and lessCase: "n<m ==> P n m" | |
| 260 | shows "P n m" | |
| 261 | apply (rule less_linear [THEN disjE]) | |
| 262 | apply (erule_tac [2] disjE) | |
| 263 | apply (erule lessCase) | |
| 264 | apply (erule sym [THEN eqCase]) | |
| 265 | apply (erule major) | |
| 266 | done | |
| 267 | ||
| 268 | ||
| 269 | subsubsection {* Inductive (?) properties *}
 | |
| 270 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 271 | lemma Suc_lessI: "m < n ==> Suc m \<noteq> n ==> Suc m < n" | 
| 13449 | 272 | apply (simp add: nat_neq_iff) | 
| 273 | apply (blast elim!: less_irrefl less_SucE elim: less_asym) | |
| 274 | done | |
| 275 | ||
| 276 | lemma Suc_lessD: "Suc m < n ==> m < n" | |
| 277 | apply (induct n) | |
| 278 | apply (fast intro!: lessI [THEN less_SucI] elim: less_trans lessE)+ | |
| 279 | done | |
| 280 | ||
| 281 | lemma Suc_lessE: assumes major: "Suc i < k" | |
| 282 | and minor: "!!j. i < j ==> k = Suc j ==> P" shows P | |
| 283 | apply (rule major [THEN lessE]) | |
| 284 | apply (erule lessI [THEN minor]) | |
| 14208 | 285 | apply (erule Suc_lessD [THEN minor], assumption) | 
| 13449 | 286 | done | 
| 287 | ||
| 288 | lemma Suc_less_SucD: "Suc m < Suc n ==> m < n" | |
| 289 | by (blast elim: lessE dest: Suc_lessD) | |
| 4104 | 290 | |
| 16635 | 291 | lemma Suc_less_eq [iff, code]: "(Suc m < Suc n) = (m < n)" | 
| 13449 | 292 | apply (rule iffI) | 
| 293 | apply (erule Suc_less_SucD) | |
| 294 | apply (erule Suc_mono) | |
| 295 | done | |
| 296 | ||
| 297 | lemma less_trans_Suc: | |
| 298 | assumes le: "i < j" shows "j < k ==> Suc i < k" | |
| 14208 | 299 | apply (induct k, simp_all) | 
| 13449 | 300 | apply (insert le) | 
| 301 | apply (simp add: less_Suc_eq) | |
| 302 | apply (blast dest: Suc_lessD) | |
| 303 | done | |
| 304 | ||
| 16635 | 305 | lemma [code]: "((n::nat) < 0) = False" by simp | 
| 306 | lemma [code]: "(0 < Suc n) = True" by simp | |
| 307 | ||
| 13449 | 308 | text {* Can be used with @{text less_Suc_eq} to get @{term "n = m | n < m"} *}
 | 
| 309 | lemma not_less_eq: "(~ m < n) = (n < Suc m)" | |
| 14208 | 310 | by (rule_tac m = m and n = n in diff_induct, simp_all) | 
| 13449 | 311 | |
| 312 | text {* Complete induction, aka course-of-values induction *}
 | |
| 313 | lemma nat_less_induct: | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 314 | assumes prem: "!!n. \<forall>m::nat. m < n --> P m ==> P n" shows "P n" | 
| 13449 | 315 | apply (rule_tac a=n in wf_induct) | 
| 316 | apply (rule wf_pred_nat [THEN wf_trancl]) | |
| 317 | apply (rule prem) | |
| 14208 | 318 | apply (unfold less_def, assumption) | 
| 13449 | 319 | done | 
| 320 | ||
| 14131 | 321 | lemmas less_induct = nat_less_induct [rule_format, case_names less] | 
| 322 | ||
| 323 | subsection {* Properties of "less than or equal" *}
 | |
| 13449 | 324 | |
| 325 | text {* Was @{text le_eq_less_Suc}, but this orientation is more useful *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 326 | lemma less_Suc_eq_le: "(m < Suc n) = (m \<le> n)" | 
| 13449 | 327 | by (unfold le_def, rule not_less_eq [symmetric]) | 
| 328 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 329 | lemma le_imp_less_Suc: "m \<le> n ==> m < Suc n" | 
| 13449 | 330 | by (rule less_Suc_eq_le [THEN iffD2]) | 
| 331 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 332 | lemma le0 [iff]: "(0::nat) \<le> n" | 
| 13449 | 333 | by (unfold le_def, rule not_less0) | 
| 334 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 335 | lemma Suc_n_not_le_n: "~ Suc n \<le> n" | 
| 13449 | 336 | by (simp add: le_def) | 
| 337 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 338 | lemma le_0_eq [iff]: "((i::nat) \<le> 0) = (i = 0)" | 
| 13449 | 339 | by (induct i) (simp_all add: le_def) | 
| 340 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 341 | lemma le_Suc_eq: "(m \<le> Suc n) = (m \<le> n | m = Suc n)" | 
| 13449 | 342 | by (simp del: less_Suc_eq_le add: less_Suc_eq_le [symmetric] less_Suc_eq) | 
| 343 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 344 | lemma le_SucE: "m \<le> Suc n ==> (m \<le> n ==> R) ==> (m = Suc n ==> R) ==> R" | 
| 17589 | 345 | by (drule le_Suc_eq [THEN iffD1], iprover+) | 
| 13449 | 346 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 347 | lemma Suc_leI: "m < n ==> Suc(m) \<le> n" | 
| 13449 | 348 | apply (simp add: le_def less_Suc_eq) | 
| 349 | apply (blast elim!: less_irrefl less_asym) | |
| 350 |   done -- {* formerly called lessD *}
 | |
| 351 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 352 | lemma Suc_leD: "Suc(m) \<le> n ==> m \<le> n" | 
| 13449 | 353 | by (simp add: le_def less_Suc_eq) | 
| 354 | ||
| 355 | text {* Stronger version of @{text Suc_leD} *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 356 | lemma Suc_le_lessD: "Suc m \<le> n ==> m < n" | 
| 13449 | 357 | apply (simp add: le_def less_Suc_eq) | 
| 358 | using less_linear | |
| 359 | apply blast | |
| 360 | done | |
| 361 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 362 | lemma Suc_le_eq: "(Suc m \<le> n) = (m < n)" | 
| 13449 | 363 | by (blast intro: Suc_leI Suc_le_lessD) | 
| 364 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 365 | lemma le_SucI: "m \<le> n ==> m \<le> Suc n" | 
| 13449 | 366 | by (unfold le_def) (blast dest: Suc_lessD) | 
| 367 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 368 | lemma less_imp_le: "m < n ==> m \<le> (n::nat)" | 
| 13449 | 369 | by (unfold le_def) (blast elim: less_asym) | 
| 370 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 371 | text {* For instance, @{text "(Suc m < Suc n) = (Suc m \<le> n) = (m < n)"} *}
 | 
| 13449 | 372 | lemmas le_simps = less_imp_le less_Suc_eq_le Suc_le_eq | 
| 373 | ||
| 374 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 375 | text {* Equivalence of @{term "m \<le> n"} and @{term "m < n | m = n"} *}
 | 
| 13449 | 376 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 377 | lemma le_imp_less_or_eq: "m \<le> n ==> m < n | m = (n::nat)" | 
| 13449 | 378 | apply (unfold le_def) | 
| 379 | using less_linear | |
| 380 | apply (blast elim: less_irrefl less_asym) | |
| 381 | done | |
| 382 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 383 | lemma less_or_eq_imp_le: "m < n | m = n ==> m \<le> (n::nat)" | 
| 13449 | 384 | apply (unfold le_def) | 
| 385 | using less_linear | |
| 386 | apply (blast elim!: less_irrefl elim: less_asym) | |
| 387 | done | |
| 388 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 389 | lemma le_eq_less_or_eq: "(m \<le> (n::nat)) = (m < n | m=n)" | 
| 17589 | 390 | by (iprover intro: less_or_eq_imp_le le_imp_less_or_eq) | 
| 13449 | 391 | |
| 392 | text {* Useful with @{text Blast}. *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 393 | lemma eq_imp_le: "(m::nat) = n ==> m \<le> n" | 
| 13449 | 394 | by (rule less_or_eq_imp_le, rule disjI2) | 
| 395 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 396 | lemma le_refl: "n \<le> (n::nat)" | 
| 13449 | 397 | by (simp add: le_eq_less_or_eq) | 
| 398 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 399 | lemma le_less_trans: "[| i \<le> j; j < k |] ==> i < (k::nat)" | 
| 13449 | 400 | by (blast dest!: le_imp_less_or_eq intro: less_trans) | 
| 401 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 402 | lemma less_le_trans: "[| i < j; j \<le> k |] ==> i < (k::nat)" | 
| 13449 | 403 | by (blast dest!: le_imp_less_or_eq intro: less_trans) | 
| 404 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 405 | lemma le_trans: "[| i \<le> j; j \<le> k |] ==> i \<le> (k::nat)" | 
| 13449 | 406 | by (blast dest!: le_imp_less_or_eq intro: less_or_eq_imp_le less_trans) | 
| 407 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 408 | lemma le_anti_sym: "[| m \<le> n; n \<le> m |] ==> m = (n::nat)" | 
| 13449 | 409 | by (blast dest!: le_imp_less_or_eq elim!: less_irrefl elim: less_asym) | 
| 410 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 411 | lemma Suc_le_mono [iff]: "(Suc n \<le> Suc m) = (n \<le> m)" | 
| 13449 | 412 | by (simp add: le_simps) | 
| 413 | ||
| 414 | text {* Axiom @{text order_less_le} of class @{text order}: *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 415 | lemma nat_less_le: "((m::nat) < n) = (m \<le> n & m \<noteq> n)" | 
| 13449 | 416 | by (simp add: le_def nat_neq_iff) (blast elim!: less_asym) | 
| 417 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 418 | lemma le_neq_implies_less: "(m::nat) \<le> n ==> m \<noteq> n ==> m < n" | 
| 13449 | 419 | by (rule iffD2, rule nat_less_le, rule conjI) | 
| 420 | ||
| 421 | text {* Axiom @{text linorder_linear} of class @{text linorder}: *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 422 | lemma nat_le_linear: "(m::nat) \<le> n | n \<le> m" | 
| 13449 | 423 | apply (simp add: le_eq_less_or_eq) | 
| 424 | using less_linear | |
| 425 | apply blast | |
| 426 | done | |
| 427 | ||
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 428 | text {* Type {@typ nat} is a wellfounded linear order *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 429 | |
| 14691 | 430 | instance nat :: "{order, linorder, wellorder}"
 | 
| 431 | by intro_classes | |
| 432 | (assumption | | |
| 433 | rule le_refl le_trans le_anti_sym nat_less_le nat_le_linear wf_less)+ | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 434 | |
| 15921 | 435 | lemmas linorder_neqE_nat = linorder_neqE[where 'a = nat] | 
| 436 | ||
| 13449 | 437 | lemma not_less_less_Suc_eq: "~ n < m ==> (n < Suc m) = (n = m)" | 
| 438 | by (blast elim!: less_SucE) | |
| 439 | ||
| 440 | text {*
 | |
| 441 |   Rewrite @{term "n < Suc m"} to @{term "n = m"}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 442 |   if @{term "~ n < m"} or @{term "m \<le> n"} hold.
 | 
| 13449 | 443 | Not suitable as default simprules because they often lead to looping | 
| 444 | *} | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 445 | lemma le_less_Suc_eq: "m \<le> n ==> (n < Suc m) = (n = m)" | 
| 13449 | 446 | by (rule not_less_less_Suc_eq, rule leD) | 
| 447 | ||
| 448 | lemmas not_less_simps = not_less_less_Suc_eq le_less_Suc_eq | |
| 449 | ||
| 450 | ||
| 451 | text {*
 | |
| 452 |   Re-orientation of the equations @{text "0 = x"} and @{text "1 = x"}. 
 | |
| 453 | No longer added as simprules (they loop) | |
| 454 |   but via @{text reorient_simproc} in Bin
 | |
| 455 | *} | |
| 456 | ||
| 457 | text {* Polymorphic, not just for @{typ nat} *}
 | |
| 458 | lemma zero_reorient: "(0 = x) = (x = 0)" | |
| 459 | by auto | |
| 460 | ||
| 461 | lemma one_reorient: "(1 = x) = (x = 1)" | |
| 462 | by auto | |
| 463 | ||
| 464 | subsection {* Arithmetic operators *}
 | |
| 1660 | 465 | |
| 12338 
de0f4a63baa5
renamed class "term" to "type" (actually "HOL.type");
 wenzelm parents: 
11451diff
changeset | 466 | axclass power < type | 
| 10435 | 467 | |
| 3370 
5c5fdce3a4e4
Overloading of "^" requires new type class "power", with types "nat" and
 paulson parents: 
2608diff
changeset | 468 | consts | 
| 13449 | 469 |   power :: "('a::power) => nat => 'a"            (infixr "^" 80)
 | 
| 3370 
5c5fdce3a4e4
Overloading of "^" requires new type class "power", with types "nat" and
 paulson parents: 
2608diff
changeset | 470 | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 471 | |
| 13449 | 472 | text {* arithmetic operators @{text "+ -"} and @{text "*"} *}
 | 
| 473 | ||
| 14691 | 474 | instance nat :: "{plus, minus, times, power}" ..
 | 
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 475 | |
| 13449 | 476 | text {* size of a datatype value; overloaded *}
 | 
| 477 | consts size :: "'a => nat" | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 478 | |
| 13449 | 479 | primrec | 
| 480 | add_0: "0 + n = n" | |
| 481 | add_Suc: "Suc m + n = Suc (m + n)" | |
| 482 | ||
| 483 | primrec | |
| 484 | diff_0: "m - 0 = m" | |
| 485 | diff_Suc: "m - Suc n = (case m - n of 0 => 0 | Suc k => k)" | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 486 | |
| 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 487 | primrec | 
| 13449 | 488 | mult_0: "0 * n = 0" | 
| 489 | mult_Suc: "Suc m * n = n + (m * n)" | |
| 490 | ||
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 491 | text {* These two rules ease the use of primitive recursion. 
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 492 | NOTE USE OF @{text "=="} *}
 | 
| 13449 | 493 | lemma def_nat_rec_0: "(!!n. f n == nat_rec c h n) ==> f 0 = c" | 
| 494 | by simp | |
| 495 | ||
| 496 | lemma def_nat_rec_Suc: "(!!n. f n == nat_rec c h n) ==> f (Suc n) = h n (f n)" | |
| 497 | by simp | |
| 498 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 499 | lemma not0_implies_Suc: "n \<noteq> 0 ==> \<exists>m. n = Suc m" | 
| 13449 | 500 | by (case_tac n) simp_all | 
| 501 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 502 | lemma gr_implies_not0: "!!n::nat. m<n ==> n \<noteq> 0" | 
| 13449 | 503 | by (case_tac n) simp_all | 
| 504 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 505 | lemma neq0_conv [iff]: "!!n::nat. (n \<noteq> 0) = (0 < n)" | 
| 13449 | 506 | by (case_tac n) simp_all | 
| 507 | ||
| 508 | text {* This theorem is useful with @{text blast} *}
 | |
| 509 | lemma gr0I: "((n::nat) = 0 ==> False) ==> 0 < n" | |
| 17589 | 510 | by (rule iffD1, rule neq0_conv, iprover) | 
| 13449 | 511 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 512 | lemma gr0_conv_Suc: "(0 < n) = (\<exists>m. n = Suc m)" | 
| 13449 | 513 | by (fast intro: not0_implies_Suc) | 
| 514 | ||
| 515 | lemma not_gr0 [iff]: "!!n::nat. (~ (0 < n)) = (n = 0)" | |
| 516 | apply (rule iffI) | |
| 14208 | 517 | apply (rule ccontr, simp_all) | 
| 13449 | 518 | done | 
| 519 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 520 | lemma Suc_le_D: "(Suc n \<le> m') ==> (? m. m' = Suc m)" | 
| 13449 | 521 | by (induct m') simp_all | 
| 522 | ||
| 523 | text {* Useful in certain inductive arguments *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 524 | lemma less_Suc_eq_0_disj: "(m < Suc n) = (m = 0 | (\<exists>j. m = Suc j & j < n))" | 
| 13449 | 525 | by (case_tac m) simp_all | 
| 526 | ||
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 527 | lemma nat_induct2: "[|P 0; P (Suc 0); !!k. P k ==> P (Suc (Suc k))|] ==> P n" | 
| 13449 | 528 | apply (rule nat_less_induct) | 
| 529 | apply (case_tac n) | |
| 530 | apply (case_tac [2] nat) | |
| 531 | apply (blast intro: less_trans)+ | |
| 532 | done | |
| 533 | ||
| 15341 
254f6f00b60e
converted to Isar script, simplifying some results
 paulson parents: 
15281diff
changeset | 534 | subsection {* @{text LEAST} theorems for type @{typ nat}*}
 | 
| 13449 | 535 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 536 | lemma Least_Suc: | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 537 | "[| P n; ~ P 0 |] ==> (LEAST n. P n) = Suc (LEAST m. P(Suc m))" | 
| 14208 | 538 | apply (case_tac "n", auto) | 
| 13449 | 539 | apply (frule LeastI) | 
| 540 | apply (drule_tac P = "%x. P (Suc x) " in LeastI) | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 541 | apply (subgoal_tac " (LEAST x. P x) \<le> Suc (LEAST x. P (Suc x))") | 
| 13449 | 542 | apply (erule_tac [2] Least_le) | 
| 14208 | 543 | apply (case_tac "LEAST x. P x", auto) | 
| 13449 | 544 | apply (drule_tac P = "%x. P (Suc x) " in Least_le) | 
| 545 | apply (blast intro: order_antisym) | |
| 546 | done | |
| 547 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 548 | lemma Least_Suc2: | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 549 | "[|P n; Q m; ~P 0; !k. P (Suc k) = Q k|] ==> Least P = Suc (Least Q)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 550 | by (erule (1) Least_Suc [THEN ssubst], simp) | 
| 13449 | 551 | |
| 552 | ||
| 14265 
95b42e69436c
HOL: installation of Ring_and_Field as the basis for Naturals and Reals
 paulson parents: 
14208diff
changeset | 553 | |
| 13449 | 554 | subsection {* @{term min} and @{term max} *}
 | 
| 555 | ||
| 556 | lemma min_0L [simp]: "min 0 n = (0::nat)" | |
| 557 | by (rule min_leastL) simp | |
| 558 | ||
| 559 | lemma min_0R [simp]: "min n 0 = (0::nat)" | |
| 560 | by (rule min_leastR) simp | |
| 561 | ||
| 562 | lemma min_Suc_Suc [simp]: "min (Suc m) (Suc n) = Suc (min m n)" | |
| 563 | by (simp add: min_of_mono) | |
| 564 | ||
| 565 | lemma max_0L [simp]: "max 0 n = (n::nat)" | |
| 566 | by (rule max_leastL) simp | |
| 567 | ||
| 568 | lemma max_0R [simp]: "max n 0 = (n::nat)" | |
| 569 | by (rule max_leastR) simp | |
| 570 | ||
| 571 | lemma max_Suc_Suc [simp]: "max (Suc m) (Suc n) = Suc(max m n)" | |
| 572 | by (simp add: max_of_mono) | |
| 573 | ||
| 574 | ||
| 575 | subsection {* Basic rewrite rules for the arithmetic operators *}
 | |
| 576 | ||
| 577 | text {* Difference *}
 | |
| 578 | ||
| 14193 
30e41f63712e
Improved efficiency of code generated for + and -
 berghofe parents: 
14131diff
changeset | 579 | lemma diff_0_eq_0 [simp, code]: "0 - n = (0::nat)" | 
| 15251 | 580 | by (induct n) simp_all | 
| 13449 | 581 | |
| 14193 
30e41f63712e
Improved efficiency of code generated for + and -
 berghofe parents: 
14131diff
changeset | 582 | lemma diff_Suc_Suc [simp, code]: "Suc(m) - Suc(n) = m - n" | 
| 15251 | 583 | by (induct n) simp_all | 
| 13449 | 584 | |
| 585 | ||
| 586 | text {*
 | |
| 587 | Could be (and is, below) generalized in various ways | |
| 588 | However, none of the generalizations are currently in the simpset, | |
| 589 | and I dread to think what happens if I put them in | |
| 590 | *} | |
| 591 | lemma Suc_pred [simp]: "0 < n ==> Suc (n - Suc 0) = n" | |
| 592 | by (simp split add: nat.split) | |
| 593 | ||
| 14193 
30e41f63712e
Improved efficiency of code generated for + and -
 berghofe parents: 
14131diff
changeset | 594 | declare diff_Suc [simp del, code del] | 
| 13449 | 595 | |
| 596 | ||
| 597 | subsection {* Addition *}
 | |
| 598 | ||
| 599 | lemma add_0_right [simp]: "m + 0 = (m::nat)" | |
| 600 | by (induct m) simp_all | |
| 601 | ||
| 602 | lemma add_Suc_right [simp]: "m + Suc n = Suc (m + n)" | |
| 603 | by (induct m) simp_all | |
| 604 | ||
| 14193 
30e41f63712e
Improved efficiency of code generated for + and -
 berghofe parents: 
14131diff
changeset | 605 | lemma [code]: "Suc m + n = m + Suc n" by simp | 
| 
30e41f63712e
Improved efficiency of code generated for + and -
 berghofe parents: 
14131diff
changeset | 606 | |
| 13449 | 607 | |
| 608 | text {* Associative law for addition *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 609 | lemma nat_add_assoc: "(m + n) + k = m + ((n + k)::nat)" | 
| 13449 | 610 | by (induct m) simp_all | 
| 611 | ||
| 612 | text {* Commutative law for addition *}
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 613 | lemma nat_add_commute: "m + n = n + (m::nat)" | 
| 13449 | 614 | by (induct m) simp_all | 
| 615 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 616 | lemma nat_add_left_commute: "x + (y + z) = y + ((x + z)::nat)" | 
| 13449 | 617 | apply (rule mk_left_commute [of "op +"]) | 
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 618 | apply (rule nat_add_assoc) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 619 | apply (rule nat_add_commute) | 
| 13449 | 620 | done | 
| 621 | ||
| 14331 | 622 | lemma nat_add_left_cancel [simp]: "(k + m = k + n) = (m = (n::nat))" | 
| 13449 | 623 | by (induct k) simp_all | 
| 624 | ||
| 14331 | 625 | lemma nat_add_right_cancel [simp]: "(m + k = n + k) = (m=(n::nat))" | 
| 13449 | 626 | by (induct k) simp_all | 
| 627 | ||
| 14331 | 628 | lemma nat_add_left_cancel_le [simp]: "(k + m \<le> k + n) = (m\<le>(n::nat))" | 
| 13449 | 629 | by (induct k) simp_all | 
| 630 | ||
| 14331 | 631 | lemma nat_add_left_cancel_less [simp]: "(k + m < k + n) = (m<(n::nat))" | 
| 13449 | 632 | by (induct k) simp_all | 
| 633 | ||
| 634 | text {* Reasoning about @{text "m + 0 = 0"}, etc. *}
 | |
| 635 | ||
| 636 | lemma add_is_0 [iff]: "!!m::nat. (m + n = 0) = (m = 0 & n = 0)" | |
| 637 | by (case_tac m) simp_all | |
| 638 | ||
| 639 | lemma add_is_1: "(m+n= Suc 0) = (m= Suc 0 & n=0 | m=0 & n= Suc 0)" | |
| 640 | by (case_tac m) simp_all | |
| 641 | ||
| 642 | lemma one_is_add: "(Suc 0 = m + n) = (m = Suc 0 & n = 0 | m = 0 & n = Suc 0)" | |
| 643 | by (rule trans, rule eq_commute, rule add_is_1) | |
| 644 | ||
| 645 | lemma add_gr_0 [iff]: "!!m::nat. (0 < m + n) = (0 < m | 0 < n)" | |
| 646 | by (simp del: neq0_conv add: neq0_conv [symmetric]) | |
| 647 | ||
| 648 | lemma add_eq_self_zero: "!!m::nat. m + n = m ==> n = 0" | |
| 649 | apply (drule add_0_right [THEN ssubst]) | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 650 | apply (simp add: nat_add_assoc del: add_0_right) | 
| 13449 | 651 | done | 
| 652 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 653 | |
| 16733 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 654 | lemma inj_on_add_nat[simp]: "inj_on (%n::nat. n+k) N" | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 655 | apply(induct k) | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 656 | apply simp | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 657 | apply(drule comp_inj_on[OF _ inj_Suc]) | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 658 | apply (simp add:o_def) | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 659 | done | 
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 660 | |
| 
236dfafbeb63
linear arithmetic now takes "&" in assumptions apart.
 nipkow parents: 
16635diff
changeset | 661 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 662 | subsection {* Multiplication *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 663 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 664 | text {* right annihilation in product *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 665 | lemma mult_0_right [simp]: "(m::nat) * 0 = 0" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 666 | by (induct m) simp_all | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 667 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 668 | text {* right successor law for multiplication *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 669 | lemma mult_Suc_right [simp]: "m * Suc n = m + (m * n)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 670 | by (induct m) (simp_all add: nat_add_left_commute) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 671 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 672 | text {* Commutative law for multiplication *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 673 | lemma nat_mult_commute: "m * n = n * (m::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 674 | by (induct m) simp_all | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 675 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 676 | text {* addition distributes over multiplication *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 677 | lemma add_mult_distrib: "(m + n) * k = (m * k) + ((n * k)::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 678 | by (induct m) (simp_all add: nat_add_assoc nat_add_left_commute) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 679 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 680 | lemma add_mult_distrib2: "k * (m + n) = (k * m) + ((k * n)::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 681 | by (induct m) (simp_all add: nat_add_assoc) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 682 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 683 | text {* Associative law for multiplication *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 684 | lemma nat_mult_assoc: "(m * n) * k = m * ((n * k)::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 685 | by (induct m) (simp_all add: add_mult_distrib) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 686 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 687 | |
| 14740 | 688 | text{*The naturals form a @{text comm_semiring_1_cancel}*}
 | 
| 14738 | 689 | instance nat :: comm_semiring_1_cancel | 
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 690 | proof | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 691 | fix i j k :: nat | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 692 | show "(i + j) + k = i + (j + k)" by (rule nat_add_assoc) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 693 | show "i + j = j + i" by (rule nat_add_commute) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 694 | show "0 + i = i" by simp | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 695 | show "(i * j) * k = i * (j * k)" by (rule nat_mult_assoc) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 696 | show "i * j = j * i" by (rule nat_mult_commute) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 697 | show "1 * i = i" by simp | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 698 | show "(i + j) * k = i * k + j * k" by (simp add: add_mult_distrib) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 699 | show "0 \<noteq> (1::nat)" by simp | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 700 | assume "k+i = k+j" thus "i=j" by simp | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 701 | qed | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 702 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 703 | lemma mult_is_0 [simp]: "((m::nat) * n = 0) = (m=0 | n=0)" | 
| 15251 | 704 | apply (induct m) | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 705 | apply (induct_tac [2] n, simp_all) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 706 | done | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 707 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 708 | subsection {* Monotonicity of Addition *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 709 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 710 | text {* strict, in 1st argument *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 711 | lemma add_less_mono1: "i < j ==> i + k < j + (k::nat)" | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 712 | by (induct k) simp_all | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 713 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 714 | text {* strict, in both arguments *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 715 | lemma add_less_mono: "[|i < j; k < l|] ==> i + k < j + (l::nat)" | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 716 | apply (rule add_less_mono1 [THEN less_trans], assumption+) | 
| 15251 | 717 | apply (induct j, simp_all) | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 718 | done | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 719 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 720 | text {* Deleted @{text less_natE}; use @{text "less_imp_Suc_add RS exE"} *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 721 | lemma less_imp_Suc_add: "m < n ==> (\<exists>k. n = Suc (m + k))" | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 722 | apply (induct n) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 723 | apply (simp_all add: order_le_less) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 724 | apply (blast elim!: less_SucE | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 725 | intro!: add_0_right [symmetric] add_Suc_right [symmetric]) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 726 | done | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 727 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 728 | text {* strict, in 1st argument; proof is by induction on @{text "k > 0"} *}
 | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 729 | lemma mult_less_mono2: "(i::nat) < j ==> 0 < k ==> k * i < k * j" | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 730 | apply (erule_tac m1 = 0 in less_imp_Suc_add [THEN exE], simp) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 731 | apply (induct_tac x) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 732 | apply (simp_all add: add_less_mono) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 733 | done | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 734 | |
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 735 | |
| 14740 | 736 | text{*The naturals form an ordered @{text comm_semiring_1_cancel}*}
 | 
| 14738 | 737 | instance nat :: ordered_semidom | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 738 | proof | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 739 | fix i j k :: nat | 
| 14348 
744c868ee0b7
Defining the type class "ringpower" and deleting superseded theorems for
 paulson parents: 
14341diff
changeset | 740 | show "0 < (1::nat)" by simp | 
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 741 | show "i \<le> j ==> k + i \<le> k + j" by simp | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 742 | show "i < j ==> 0 < k ==> k * i < k * j" by (simp add: mult_less_mono2) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 743 | qed | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 744 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 745 | lemma nat_mult_1: "(1::nat) * n = n" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 746 | by simp | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 747 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 748 | lemma nat_mult_1_right: "n * (1::nat) = n" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 749 | by simp | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 750 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 751 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 752 | subsection {* Additional theorems about "less than" *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 753 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 754 | text {* A [clumsy] way of lifting @{text "<"}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 755 |   monotonicity to @{text "\<le>"} monotonicity *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 756 | lemma less_mono_imp_le_mono: | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 757 | assumes lt_mono: "!!i j::nat. i < j ==> f i < f j" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 758 | and le: "i \<le> j" shows "f i \<le> ((f j)::nat)" using le | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 759 | apply (simp add: order_le_less) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 760 | apply (blast intro!: lt_mono) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 761 | done | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 762 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 763 | text {* non-strict, in 1st argument *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 764 | lemma add_le_mono1: "i \<le> j ==> i + k \<le> j + (k::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 765 | by (rule add_right_mono) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 766 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 767 | text {* non-strict, in both arguments *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 768 | lemma add_le_mono: "[| i \<le> j; k \<le> l |] ==> i + k \<le> j + (l::nat)" | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 769 | by (rule add_mono) | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 770 | |
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 771 | lemma le_add2: "n \<le> ((m + n)::nat)" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 772 | by (insert add_right_mono [of 0 m n], simp) | 
| 13449 | 773 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 774 | lemma le_add1: "n \<le> ((n + m)::nat)" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 775 | by (simp add: add_commute, rule le_add2) | 
| 13449 | 776 | |
| 777 | lemma less_add_Suc1: "i < Suc (i + m)" | |
| 778 | by (rule le_less_trans, rule le_add1, rule lessI) | |
| 779 | ||
| 780 | lemma less_add_Suc2: "i < Suc (m + i)" | |
| 781 | by (rule le_less_trans, rule le_add2, rule lessI) | |
| 782 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 783 | lemma less_iff_Suc_add: "(m < n) = (\<exists>k. n = Suc (m + k))" | 
| 17589 | 784 | by (iprover intro!: less_add_Suc1 less_imp_Suc_add) | 
| 13449 | 785 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 786 | lemma trans_le_add1: "(i::nat) \<le> j ==> i \<le> j + m" | 
| 13449 | 787 | by (rule le_trans, assumption, rule le_add1) | 
| 788 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 789 | lemma trans_le_add2: "(i::nat) \<le> j ==> i \<le> m + j" | 
| 13449 | 790 | by (rule le_trans, assumption, rule le_add2) | 
| 791 | ||
| 792 | lemma trans_less_add1: "(i::nat) < j ==> i < j + m" | |
| 793 | by (rule less_le_trans, assumption, rule le_add1) | |
| 794 | ||
| 795 | lemma trans_less_add2: "(i::nat) < j ==> i < m + j" | |
| 796 | by (rule less_le_trans, assumption, rule le_add2) | |
| 797 | ||
| 798 | lemma add_lessD1: "i + j < (k::nat) ==> i < k" | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 799 | apply (rule le_less_trans [of _ "i+j"]) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 800 | apply (simp_all add: le_add1) | 
| 13449 | 801 | done | 
| 802 | ||
| 803 | lemma not_add_less1 [iff]: "~ (i + j < (i::nat))" | |
| 804 | apply (rule notI) | |
| 805 | apply (erule add_lessD1 [THEN less_irrefl]) | |
| 806 | done | |
| 807 | ||
| 808 | lemma not_add_less2 [iff]: "~ (j + i < (i::nat))" | |
| 809 | by (simp add: add_commute not_add_less1) | |
| 810 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 811 | lemma add_leD1: "m + k \<le> n ==> m \<le> (n::nat)" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 812 | apply (rule order_trans [of _ "m+k"]) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 813 | apply (simp_all add: le_add1) | 
| 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 814 | done | 
| 13449 | 815 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 816 | lemma add_leD2: "m + k \<le> n ==> k \<le> (n::nat)" | 
| 13449 | 817 | apply (simp add: add_commute) | 
| 818 | apply (erule add_leD1) | |
| 819 | done | |
| 820 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 821 | lemma add_leE: "(m::nat) + k \<le> n ==> (m \<le> n ==> k \<le> n ==> R) ==> R" | 
| 13449 | 822 | by (blast dest: add_leD1 add_leD2) | 
| 823 | ||
| 824 | text {* needs @{text "!!k"} for @{text add_ac} to work *}
 | |
| 825 | lemma less_add_eq_less: "!!k::nat. k < l ==> m + l = k + n ==> m < n" | |
| 826 | by (force simp del: add_Suc_right | |
| 827 | simp add: less_iff_Suc_add add_Suc_right [symmetric] add_ac) | |
| 828 | ||
| 829 | ||
| 830 | ||
| 831 | subsection {* Difference *}
 | |
| 832 | ||
| 833 | lemma diff_self_eq_0 [simp]: "(m::nat) - m = 0" | |
| 834 | by (induct m) simp_all | |
| 835 | ||
| 836 | text {* Addition is the inverse of subtraction:
 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 837 |   if @{term "n \<le> m"} then @{term "n + (m - n) = m"}. *}
 | 
| 13449 | 838 | lemma add_diff_inverse: "~ m < n ==> n + (m - n) = (m::nat)" | 
| 839 | by (induct m n rule: diff_induct) simp_all | |
| 840 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 841 | lemma le_add_diff_inverse [simp]: "n \<le> m ==> n + (m - n) = (m::nat)" | 
| 16796 | 842 | by (simp add: add_diff_inverse linorder_not_less) | 
| 13449 | 843 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 844 | lemma le_add_diff_inverse2 [simp]: "n \<le> m ==> (m - n) + n = (m::nat)" | 
| 13449 | 845 | by (simp add: le_add_diff_inverse add_commute) | 
| 846 | ||
| 847 | ||
| 848 | subsection {* More results about difference *}
 | |
| 849 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 850 | lemma Suc_diff_le: "n \<le> m ==> Suc m - n = Suc (m - n)" | 
| 13449 | 851 | by (induct m n rule: diff_induct) simp_all | 
| 852 | ||
| 853 | lemma diff_less_Suc: "m - n < Suc m" | |
| 854 | apply (induct m n rule: diff_induct) | |
| 855 | apply (erule_tac [3] less_SucE) | |
| 856 | apply (simp_all add: less_Suc_eq) | |
| 857 | done | |
| 858 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 859 | lemma diff_le_self [simp]: "m - n \<le> (m::nat)" | 
| 13449 | 860 | by (induct m n rule: diff_induct) (simp_all add: le_SucI) | 
| 861 | ||
| 862 | lemma less_imp_diff_less: "(j::nat) < k ==> j - n < k" | |
| 863 | by (rule le_less_trans, rule diff_le_self) | |
| 864 | ||
| 865 | lemma diff_diff_left: "(i::nat) - j - k = i - (j + k)" | |
| 866 | by (induct i j rule: diff_induct) simp_all | |
| 867 | ||
| 868 | lemma Suc_diff_diff [simp]: "(Suc m - n) - Suc k = m - n - k" | |
| 869 | by (simp add: diff_diff_left) | |
| 870 | ||
| 871 | lemma diff_Suc_less [simp]: "0<n ==> n - Suc i < n" | |
| 14208 | 872 | apply (case_tac "n", safe) | 
| 13449 | 873 | apply (simp add: le_simps) | 
| 874 | done | |
| 875 | ||
| 876 | text {* This and the next few suggested by Florian Kammueller *}
 | |
| 877 | lemma diff_commute: "(i::nat) - j - k = i - k - j" | |
| 878 | by (simp add: diff_diff_left add_commute) | |
| 879 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 880 | lemma diff_add_assoc: "k \<le> (j::nat) ==> (i + j) - k = i + (j - k)" | 
| 13449 | 881 | by (induct j k rule: diff_induct) simp_all | 
| 882 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 883 | lemma diff_add_assoc2: "k \<le> (j::nat) ==> (j + i) - k = (j - k) + i" | 
| 13449 | 884 | by (simp add: add_commute diff_add_assoc) | 
| 885 | ||
| 886 | lemma diff_add_inverse: "(n + m) - n = (m::nat)" | |
| 887 | by (induct n) simp_all | |
| 888 | ||
| 889 | lemma diff_add_inverse2: "(m + n) - n = (m::nat)" | |
| 890 | by (simp add: diff_add_assoc) | |
| 891 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 892 | lemma le_imp_diff_is_add: "i \<le> (j::nat) ==> (j - i = k) = (j = k + i)" | 
| 13449 | 893 | apply safe | 
| 894 | apply (simp_all add: diff_add_inverse2) | |
| 895 | done | |
| 896 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 897 | lemma diff_is_0_eq [simp]: "((m::nat) - n = 0) = (m \<le> n)" | 
| 13449 | 898 | by (induct m n rule: diff_induct) simp_all | 
| 899 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 900 | lemma diff_is_0_eq' [simp]: "m \<le> n ==> (m::nat) - n = 0" | 
| 13449 | 901 | by (rule iffD2, rule diff_is_0_eq) | 
| 902 | ||
| 903 | lemma zero_less_diff [simp]: "(0 < n - (m::nat)) = (m < n)" | |
| 904 | by (induct m n rule: diff_induct) simp_all | |
| 905 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 906 | lemma less_imp_add_positive: "i < j ==> \<exists>k::nat. 0 < k & i + k = j" | 
| 13449 | 907 | apply (rule_tac x = "j - i" in exI) | 
| 908 | apply (simp (no_asm_simp) add: add_diff_inverse less_not_sym) | |
| 909 | done | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 910 | |
| 13449 | 911 | lemma zero_induct_lemma: "P k ==> (!!n. P (Suc n) ==> P n) ==> P (k - i)" | 
| 912 | apply (induct k i rule: diff_induct) | |
| 913 | apply (simp_all (no_asm)) | |
| 17589 | 914 | apply iprover | 
| 13449 | 915 | done | 
| 916 | ||
| 917 | lemma zero_induct: "P k ==> (!!n. P (Suc n) ==> P n) ==> P 0" | |
| 918 | apply (rule diff_self_eq_0 [THEN subst]) | |
| 17589 | 919 | apply (rule zero_induct_lemma, iprover+) | 
| 13449 | 920 | done | 
| 921 | ||
| 922 | lemma diff_cancel: "(k + m) - (k + n) = m - (n::nat)" | |
| 923 | by (induct k) simp_all | |
| 924 | ||
| 925 | lemma diff_cancel2: "(m + k) - (n + k) = m - (n::nat)" | |
| 926 | by (simp add: diff_cancel add_commute) | |
| 927 | ||
| 928 | lemma diff_add_0: "n - (n + m) = (0::nat)" | |
| 929 | by (induct n) simp_all | |
| 930 | ||
| 931 | ||
| 932 | text {* Difference distributes over multiplication *}
 | |
| 933 | ||
| 934 | lemma diff_mult_distrib: "((m::nat) - n) * k = (m * k) - (n * k)" | |
| 935 | by (induct m n rule: diff_induct) (simp_all add: diff_cancel) | |
| 936 | ||
| 937 | lemma diff_mult_distrib2: "k * ((m::nat) - n) = (k * m) - (k * n)" | |
| 938 | by (simp add: diff_mult_distrib mult_commute [of k]) | |
| 939 |   -- {* NOT added as rewrites, since sometimes they are used from right-to-left *}
 | |
| 940 | ||
| 941 | lemmas nat_distrib = | |
| 942 | add_mult_distrib add_mult_distrib2 diff_mult_distrib diff_mult_distrib2 | |
| 943 | ||
| 944 | ||
| 945 | subsection {* Monotonicity of Multiplication *}
 | |
| 946 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 947 | lemma mult_le_mono1: "i \<le> (j::nat) ==> i * k \<le> j * k" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 948 | by (simp add: mult_right_mono) | 
| 13449 | 949 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 950 | lemma mult_le_mono2: "i \<le> (j::nat) ==> k * i \<le> k * j" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 951 | by (simp add: mult_left_mono) | 
| 13449 | 952 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 953 | text {* @{text "\<le>"} monotonicity, BOTH arguments *}
 | 
| 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 954 | lemma mult_le_mono: "i \<le> (j::nat) ==> k \<le> l ==> i * k \<le> j * l" | 
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 955 | by (simp add: mult_mono) | 
| 13449 | 956 | |
| 957 | lemma mult_less_mono1: "(i::nat) < j ==> 0 < k ==> i * k < j * k" | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 958 | by (simp add: mult_strict_right_mono) | 
| 13449 | 959 | |
| 14266 | 960 | text{*Differs from the standard @{text zero_less_mult_iff} in that
 | 
| 961 | there are no negative numbers.*} | |
| 962 | lemma nat_0_less_mult_iff [simp]: "(0 < (m::nat) * n) = (0 < m & 0 < n)" | |
| 13449 | 963 | apply (induct m) | 
| 14208 | 964 | apply (case_tac [2] n, simp_all) | 
| 13449 | 965 | done | 
| 966 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 967 | lemma one_le_mult_iff [simp]: "(Suc 0 \<le> m * n) = (1 \<le> m & 1 \<le> n)" | 
| 13449 | 968 | apply (induct m) | 
| 14208 | 969 | apply (case_tac [2] n, simp_all) | 
| 13449 | 970 | done | 
| 971 | ||
| 972 | lemma mult_eq_1_iff [simp]: "(m * n = Suc 0) = (m = 1 & n = 1)" | |
| 15251 | 973 | apply (induct m, simp) | 
| 974 | apply (induct n, simp, fastsimp) | |
| 13449 | 975 | done | 
| 976 | ||
| 977 | lemma one_eq_mult_iff [simp]: "(Suc 0 = m * n) = (m = 1 & n = 1)" | |
| 978 | apply (rule trans) | |
| 14208 | 979 | apply (rule_tac [2] mult_eq_1_iff, fastsimp) | 
| 13449 | 980 | done | 
| 981 | ||
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 982 | lemma mult_less_cancel2 [simp]: "((m::nat) * k < n * k) = (0 < k & m < n)" | 
| 13449 | 983 | apply (safe intro!: mult_less_mono1) | 
| 14208 | 984 | apply (case_tac k, auto) | 
| 13449 | 985 | apply (simp del: le_0_eq add: linorder_not_le [symmetric]) | 
| 986 | apply (blast intro: mult_le_mono1) | |
| 987 | done | |
| 988 | ||
| 989 | lemma mult_less_cancel1 [simp]: "(k * (m::nat) < k * n) = (0 < k & m < n)" | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 990 | by (simp add: mult_commute [of k]) | 
| 13449 | 991 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 992 | lemma mult_le_cancel1 [simp]: "(k * (m::nat) \<le> k * n) = (0 < k --> m \<le> n)" | 
| 14208 | 993 | by (simp add: linorder_not_less [symmetric], auto) | 
| 13449 | 994 | |
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 995 | lemma mult_le_cancel2 [simp]: "((m::nat) * k \<le> n * k) = (0 < k --> m \<le> n)" | 
| 14208 | 996 | by (simp add: linorder_not_less [symmetric], auto) | 
| 13449 | 997 | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 998 | lemma mult_cancel2 [simp]: "(m * k = n * k) = (m = n | (k = (0::nat)))" | 
| 14208 | 999 | apply (cut_tac less_linear, safe, auto) | 
| 13449 | 1000 | apply (drule mult_less_mono1, assumption, simp)+ | 
| 1001 | done | |
| 1002 | ||
| 1003 | lemma mult_cancel1 [simp]: "(k * m = k * n) = (m = n | (k = (0::nat)))" | |
| 14341 
a09441bd4f1e
Ring_and_Field now requires axiom add_left_imp_eq for semirings.
 paulson parents: 
14331diff
changeset | 1004 | by (simp add: mult_commute [of k]) | 
| 13449 | 1005 | |
| 1006 | lemma Suc_mult_less_cancel1: "(Suc k * m < Suc k * n) = (m < n)" | |
| 1007 | by (subst mult_less_cancel1) simp | |
| 1008 | ||
| 14267 
b963e9cee2a0
More refinements to Ring_and_Field and numerics. Conversion of Divides_lemmas
 paulson parents: 
14266diff
changeset | 1009 | lemma Suc_mult_le_cancel1: "(Suc k * m \<le> Suc k * n) = (m \<le> n)" | 
| 13449 | 1010 | by (subst mult_le_cancel1) simp | 
| 1011 | ||
| 1012 | lemma Suc_mult_cancel1: "(Suc k * m = Suc k * n) = (m = n)" | |
| 1013 | by (subst mult_cancel1) simp | |
| 1014 | ||
| 1015 | text {* Lemma for @{text gcd} *}
 | |
| 1016 | lemma mult_eq_self_implies_10: "(m::nat) = m * n ==> n = 1 | m = 0" | |
| 1017 | apply (drule sym) | |
| 1018 | apply (rule disjCI) | |
| 1019 | apply (rule nat_less_cases, erule_tac [2] _) | |
| 1020 | apply (fastsimp elim!: less_SucE) | |
| 1021 | apply (fastsimp dest: mult_less_mono2) | |
| 1022 | done | |
| 9436 
62bb04ab4b01
rearranged setup of arithmetic procedures, avoiding global reference values;
 wenzelm parents: 
7702diff
changeset | 1023 | |
| 15539 | 1024 | |
| 923 | 1025 | end |