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