7 There are no negative numbers; we have |
7 There are no negative numbers; we have |
8 m #- n = 0 iff m<=n and m #- n = succ(k) iff m>n. |
8 m #- n = 0 iff m<=n and m #- n = succ(k) iff m>n. |
9 Also, rec(m, 0, %z w.z) is pred(m). |
9 Also, rec(m, 0, %z w.z) is pred(m). |
10 *) |
10 *) |
11 |
11 |
12 section{*Arithmetic Operators and Their Definitions*} |
12 section\<open>Arithmetic Operators and Their Definitions\<close> |
13 |
13 |
14 theory Arith imports Univ begin |
14 theory Arith imports Univ begin |
15 |
15 |
16 text{*Proofs about elementary arithmetic: addition, multiplication, etc.*} |
16 text\<open>Proofs about elementary arithmetic: addition, multiplication, etc.\<close> |
17 |
17 |
18 definition |
18 definition |
19 pred :: "i=>i" (*inverse of succ*) where |
19 pred :: "i=>i" (*inverse of succ*) where |
20 "pred(y) == nat_case(0, %x. x, y)" |
20 "pred(y) == nat_case(0, %x. x, y)" |
21 |
21 |
313 |
313 |
314 lemma zero_less_add: "[| n \<in> nat; m \<in> nat |] ==> 0 < m #+ n \<longleftrightarrow> (0<m | 0<n)" |
314 lemma zero_less_add: "[| n \<in> nat; m \<in> nat |] ==> 0 < m #+ n \<longleftrightarrow> (0<m | 0<n)" |
315 by (induct_tac "n", auto) |
315 by (induct_tac "n", auto) |
316 |
316 |
317 |
317 |
318 subsection{*Monotonicity of Addition*} |
318 subsection\<open>Monotonicity of Addition\<close> |
319 |
319 |
320 (*strict, in 1st argument; proof is by rule induction on 'less than'. |
320 (*strict, in 1st argument; proof is by rule induction on 'less than'. |
321 Still need j\<in>nat, for consider j = omega. Then we can have i<omega, |
321 Still need j\<in>nat, for consider j = omega. Then we can have i<omega, |
322 which is the same as i\<in>nat, but natify(j)=0, so the conclusion fails.*) |
322 which is the same as i\<in>nat, but natify(j)=0, so the conclusion fails.*) |
323 lemma add_lt_mono1: "[| i<j; j\<in>nat |] ==> i#+k < j#+k" |
323 lemma add_lt_mono1: "[| i<j; j\<in>nat |] ==> i#+k < j#+k" |
324 apply (frule lt_nat_in_nat, assumption) |
324 apply (frule lt_nat_in_nat, assumption) |
325 apply (erule succ_lt_induct) |
325 apply (erule succ_lt_induct) |
326 apply (simp_all add: leI) |
326 apply (simp_all add: leI) |
327 done |
327 done |
328 |
328 |
329 text{*strict, in second argument*} |
329 text\<open>strict, in second argument\<close> |
330 lemma add_lt_mono2: "[| i<j; j\<in>nat |] ==> k#+i < k#+j" |
330 lemma add_lt_mono2: "[| i<j; j\<in>nat |] ==> k#+i < k#+j" |
331 by (simp add: add_commute [of k] add_lt_mono1) |
331 by (simp add: add_commute [of k] add_lt_mono1) |
332 |
332 |
333 text{*A [clumsy] way of lifting < monotonicity to @{text "\<le>"} monotonicity*} |
333 text\<open>A [clumsy] way of lifting < monotonicity to @{text "\<le>"} monotonicity\<close> |
334 lemma Ord_lt_mono_imp_le_mono: |
334 lemma Ord_lt_mono_imp_le_mono: |
335 assumes lt_mono: "!!i j. [| i<j; j:k |] ==> f(i) < f(j)" |
335 assumes lt_mono: "!!i j. [| i<j; j:k |] ==> f(i) < f(j)" |
336 and ford: "!!i. i:k ==> Ord(f(i))" |
336 and ford: "!!i. i:k ==> Ord(f(i))" |
337 and leij: "i \<le> j" |
337 and leij: "i \<le> j" |
338 and jink: "j:k" |
338 and jink: "j:k" |
339 shows "f(i) \<le> f(j)" |
339 shows "f(i) \<le> f(j)" |
340 apply (insert leij jink) |
340 apply (insert leij jink) |
341 apply (blast intro!: leCI lt_mono ford elim!: leE) |
341 apply (blast intro!: leCI lt_mono ford elim!: leE) |
342 done |
342 done |
343 |
343 |
344 text{*@{text "\<le>"} monotonicity, 1st argument*} |
344 text\<open>@{text "\<le>"} monotonicity, 1st argument\<close> |
345 lemma add_le_mono1: "[| i \<le> j; j\<in>nat |] ==> i#+k \<le> j#+k" |
345 lemma add_le_mono1: "[| i \<le> j; j\<in>nat |] ==> i#+k \<le> j#+k" |
346 apply (rule_tac f = "%j. j#+k" in Ord_lt_mono_imp_le_mono, typecheck) |
346 apply (rule_tac f = "%j. j#+k" in Ord_lt_mono_imp_le_mono, typecheck) |
347 apply (blast intro: add_lt_mono1 add_type [THEN nat_into_Ord])+ |
347 apply (blast intro: add_lt_mono1 add_type [THEN nat_into_Ord])+ |
348 done |
348 done |
349 |
349 |
350 text{*@{text "\<le>"} monotonicity, both arguments*} |
350 text\<open>@{text "\<le>"} monotonicity, both arguments\<close> |
351 lemma add_le_mono: "[| i \<le> j; k \<le> l; j\<in>nat; l\<in>nat |] ==> i#+k \<le> j#+l" |
351 lemma add_le_mono: "[| i \<le> j; k \<le> l; j\<in>nat; l\<in>nat |] ==> i#+k \<le> j#+l" |
352 apply (rule add_le_mono1 [THEN le_trans], assumption+) |
352 apply (rule add_le_mono1 [THEN le_trans], assumption+) |
353 apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) |
353 apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) |
354 done |
354 done |
355 |
355 |
356 text{*Combinations of less-than and less-than-or-equals*} |
356 text\<open>Combinations of less-than and less-than-or-equals\<close> |
357 |
357 |
358 lemma add_lt_le_mono: "[| i<j; k\<le>l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
358 lemma add_lt_le_mono: "[| i<j; k\<le>l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
359 apply (rule add_lt_mono1 [THEN lt_trans2], assumption+) |
359 apply (rule add_lt_mono1 [THEN lt_trans2], assumption+) |
360 apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) |
360 apply (subst add_commute, subst add_commute, rule add_le_mono1, assumption+) |
361 done |
361 done |
362 |
362 |
363 lemma add_le_lt_mono: "[| i\<le>j; k<l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
363 lemma add_le_lt_mono: "[| i\<le>j; k<l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
364 by (subst add_commute, subst add_commute, erule add_lt_le_mono, assumption+) |
364 by (subst add_commute, subst add_commute, erule add_lt_le_mono, assumption+) |
365 |
365 |
366 text{*Less-than: in other words, strict in both arguments*} |
366 text\<open>Less-than: in other words, strict in both arguments\<close> |
367 lemma add_lt_mono: "[| i<j; k<l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
367 lemma add_lt_mono: "[| i<j; k<l; j\<in>nat; l\<in>nat |] ==> i#+k < j#+l" |
368 apply (rule add_lt_le_mono) |
368 apply (rule add_lt_le_mono) |
369 apply (auto intro: leI) |
369 apply (auto intro: leI) |
370 done |
370 done |
371 |
371 |