11 |
11 |
12 subsection \<open>Arithmetic operators and their definitions\<close> |
12 subsection \<open>Arithmetic operators and their definitions\<close> |
13 |
13 |
14 definition |
14 definition |
15 add :: "[i,i]\<Rightarrow>i" (infixr "#+" 65) where |
15 add :: "[i,i]\<Rightarrow>i" (infixr "#+" 65) where |
16 "a#+b == rec(a, b, \<lambda>u v. succ(v))" |
16 "a#+b \<equiv> rec(a, b, \<lambda>u v. succ(v))" |
17 |
17 |
18 definition |
18 definition |
19 diff :: "[i,i]\<Rightarrow>i" (infixr "-" 65) where |
19 diff :: "[i,i]\<Rightarrow>i" (infixr "-" 65) where |
20 "a-b == rec(b, a, \<lambda>u v. rec(v, 0, \<lambda>x y. x))" |
20 "a-b \<equiv> rec(b, a, \<lambda>u v. rec(v, 0, \<lambda>x y. x))" |
21 |
21 |
22 definition |
22 definition |
23 absdiff :: "[i,i]\<Rightarrow>i" (infixr "|-|" 65) where |
23 absdiff :: "[i,i]\<Rightarrow>i" (infixr "|-|" 65) where |
24 "a|-|b == (a-b) #+ (b-a)" |
24 "a|-|b \<equiv> (a-b) #+ (b-a)" |
25 |
25 |
26 definition |
26 definition |
27 mult :: "[i,i]\<Rightarrow>i" (infixr "#*" 70) where |
27 mult :: "[i,i]\<Rightarrow>i" (infixr "#*" 70) where |
28 "a#*b == rec(a, 0, \<lambda>u v. b #+ v)" |
28 "a#*b \<equiv> rec(a, 0, \<lambda>u v. b #+ v)" |
29 |
29 |
30 definition |
30 definition |
31 mod :: "[i,i]\<Rightarrow>i" (infixr "mod" 70) where |
31 mod :: "[i,i]\<Rightarrow>i" (infixr "mod" 70) where |
32 "a mod b == rec(a, 0, %u v. rec(succ(v) |-| b, 0, %x y. succ(v)))" |
32 "a mod b \<equiv> rec(a, 0, \<lambda>u v. rec(succ(v) |-| b, 0, \<lambda>x y. succ(v)))" |
33 |
33 |
34 definition |
34 definition |
35 div :: "[i,i]\<Rightarrow>i" (infixr "div" 70) where |
35 div :: "[i,i]\<Rightarrow>i" (infixr "div" 70) where |
36 "a div b == rec(a, 0, \<lambda>u v. rec(succ(u) mod b, succ(v), \<lambda>x y. v))" |
36 "a div b \<equiv> rec(a, 0, \<lambda>u v. rec(succ(u) mod b, succ(v), \<lambda>x y. v))" |
37 |
|
38 |
|
39 notation (xsymbols) |
|
40 mult (infixr "#\<times>" 70) |
|
41 |
37 |
42 |
38 |
43 lemmas arith_defs = add_def diff_def absdiff_def mult_def mod_def div_def |
39 lemmas arith_defs = add_def diff_def absdiff_def mult_def mod_def div_def |
44 |
40 |
45 |
41 |
262 |
258 |
263 (*Addition is the inverse of subtraction: if b<=x then b#+(x-b) = x. |
259 (*Addition is the inverse of subtraction: if b<=x then b#+(x-b) = x. |
264 An example of induction over a quantified formula (a product). |
260 An example of induction over a quantified formula (a product). |
265 Uses rewriting with a quantified, implicative inductive hypothesis.*) |
261 Uses rewriting with a quantified, implicative inductive hypothesis.*) |
266 schematic_goal add_diff_inverse_lemma: |
262 schematic_goal add_diff_inverse_lemma: |
267 "b:N \<Longrightarrow> ?a : PROD x:N. Eq(N, b-x, 0) --> Eq(N, b #+ (x-b), x)" |
263 "b:N \<Longrightarrow> ?a : \<Prod>x:N. Eq(N, b-x, 0) \<longrightarrow> Eq(N, b #+ (x-b), x)" |
268 apply (NE b) |
264 apply (NE b) |
269 (*strip one "universal quantifier" but not the "implication"*) |
265 (*strip one "universal quantifier" but not the "implication"*) |
270 apply (rule_tac [3] intr_rls) |
266 apply (rule_tac [3] intr_rls) |
271 (*case analysis on x in |
267 (*case analysis on x in |
272 (succ(u) <= x) --> (succ(u)#+(x-succ(u)) = x) *) |
268 (succ(u) <= x) \<longrightarrow> (succ(u)#+(x-succ(u)) = x) *) |
273 prefer 4 |
269 prefer 4 |
274 apply (NE x) |
270 apply (NE x) |
275 apply assumption |
271 apply assumption |
276 (*Prepare for simplification of types -- the antecedent succ(u)<=x *) |
272 (*Prepare for simplification of types -- the antecedent succ(u)<=x *) |
277 apply (rule_tac [2] replace_type) |
273 apply (rule_tac [2] replace_type) |
332 apply (rule add_commute) |
328 apply (rule add_commute) |
333 apply (typechk diff_typing) |
329 apply (typechk diff_typing) |
334 done |
330 done |
335 |
331 |
336 (*If a+b=0 then a=0. Surprisingly tedious*) |
332 (*If a+b=0 then a=0. Surprisingly tedious*) |
337 schematic_goal add_eq0_lemma: "\<lbrakk>a:N; b:N\<rbrakk> \<Longrightarrow> ?c : PROD u: Eq(N,a#+b,0) . Eq(N,a,0)" |
333 schematic_goal add_eq0_lemma: "\<lbrakk>a:N; b:N\<rbrakk> \<Longrightarrow> ?c : \<Prod>u: Eq(N,a#+b,0) . Eq(N,a,0)" |
338 apply (NE a) |
334 apply (NE a) |
339 apply (rule_tac [3] replace_type) |
335 apply (rule_tac [3] replace_type) |
340 apply arith_rew |
336 apply arith_rew |
341 apply intr (*strips remaining PRODs*) |
337 apply intr (*strips remaining PRODs*) |
342 apply (rule_tac [2] zero_ne_succ [THEN FE]) |
338 apply (rule_tac [2] zero_ne_succ [THEN FE]) |
353 apply typechk |
349 apply typechk |
354 done |
350 done |
355 |
351 |
356 (*Here is a lemma to infer a-b=0 and b-a=0 from a|-|b=0, below. *) |
352 (*Here is a lemma to infer a-b=0 and b-a=0 from a|-|b=0, below. *) |
357 schematic_goal absdiff_eq0_lem: |
353 schematic_goal absdiff_eq0_lem: |
358 "\<lbrakk>a:N; b:N; a |-| b = 0 : N\<rbrakk> \<Longrightarrow> ?a : SUM v: Eq(N, a-b, 0) . Eq(N, b-a, 0)" |
354 "\<lbrakk>a:N; b:N; a |-| b = 0 : N\<rbrakk> \<Longrightarrow> ?a : \<Sum>v: Eq(N, a-b, 0) . Eq(N, b-a, 0)" |
359 apply (unfold absdiff_def) |
355 apply (unfold absdiff_def) |
360 apply intr |
356 apply intr |
361 apply eqintr |
357 apply eqintr |
362 apply (rule_tac [2] add_eq0) |
358 apply (rule_tac [2] add_eq0) |
363 apply (rule add_eq0) |
359 apply (rule add_eq0) |
444 apply (rew mod_typing div_typing absdiff_typing) |
440 apply (rew mod_typing div_typing absdiff_typing) |
445 done |
441 done |
446 |
442 |
447 (*for case analysis on whether a number is 0 or a successor*) |
443 (*for case analysis on whether a number is 0 or a successor*) |
448 lemma iszero_decidable: "a:N \<Longrightarrow> rec(a, inl(eq), \<lambda>ka kb. inr(<ka, eq>)) : |
444 lemma iszero_decidable: "a:N \<Longrightarrow> rec(a, inl(eq), \<lambda>ka kb. inr(<ka, eq>)) : |
449 Eq(N,a,0) + (SUM x:N. Eq(N,a, succ(x)))" |
445 Eq(N,a,0) + (\<Sum>x:N. Eq(N,a, succ(x)))" |
450 apply (NE a) |
446 apply (NE a) |
451 apply (rule_tac [3] PlusI_inr) |
447 apply (rule_tac [3] PlusI_inr) |
452 apply (rule_tac [2] PlusI_inl) |
448 apply (rule_tac [2] PlusI_inl) |
453 apply eqintr |
449 apply eqintr |
454 apply equal |
450 apply equal |