157 |
157 |
158 ML {* |
158 ML {* |
159 |
159 |
160 structure Arith_simp_data: TSIMP_DATA = |
160 structure Arith_simp_data: TSIMP_DATA = |
161 struct |
161 struct |
162 val refl = thm "refl_elem" |
162 val refl = @{thm refl_elem} |
163 val sym = thm "sym_elem" |
163 val sym = @{thm sym_elem} |
164 val trans = thm "trans_elem" |
164 val trans = @{thm trans_elem} |
165 val refl_red = thm "refl_red" |
165 val refl_red = @{thm refl_red} |
166 val trans_red = thm "trans_red" |
166 val trans_red = @{thm trans_red} |
167 val red_if_equal = thm "red_if_equal" |
167 val red_if_equal = @{thm red_if_equal} |
168 val default_rls = thms "arithC_rls" @ thms "comp_rls" |
168 val default_rls = @{thms arithC_rls} @ @{thms comp_rls} |
169 val routine_tac = routine_tac (thms "arith_typing_rls" @ thms "routine_rls") |
169 val routine_tac = routine_tac (@{thms arith_typing_rls} @ @{thms routine_rls}) |
170 end |
170 end |
171 |
171 |
172 structure Arith_simp = TSimpFun (Arith_simp_data) |
172 structure Arith_simp = TSimpFun (Arith_simp_data) |
173 |
173 |
174 local val congr_rls = thms "congr_rls" in |
174 local val congr_rls = @{thms congr_rls} in |
175 |
175 |
176 fun arith_rew_tac prems = make_rew_tac |
176 fun arith_rew_tac prems = make_rew_tac |
177 (Arith_simp.norm_tac(congr_rls, prems)) |
177 (Arith_simp.norm_tac(congr_rls, prems)) |
178 |
178 |
179 fun hyp_arith_rew_tac prems = make_rew_tac |
179 fun hyp_arith_rew_tac prems = make_rew_tac |
319 |
319 |
320 (*Note how easy using commutative laws can be? ...not always... *) |
320 (*Note how easy using commutative laws can be? ...not always... *) |
321 lemma absdiff_commute: "[| a:N; b:N |] ==> a |-| b = b |-| a : N" |
321 lemma absdiff_commute: "[| a:N; b:N |] ==> a |-| b = b |-| a : N" |
322 apply (unfold absdiff_def) |
322 apply (unfold absdiff_def) |
323 apply (rule add_commute) |
323 apply (rule add_commute) |
324 apply (tactic {* typechk_tac [thm "diff_typing"] *}) |
324 apply (tactic {* typechk_tac [@{thm diff_typing}] *}) |
325 done |
325 done |
326 |
326 |
327 (*If a+b=0 then a=0. Surprisingly tedious*) |
327 (*If a+b=0 then a=0. Surprisingly tedious*) |
328 schematic_lemma add_eq0_lemma: "[| a:N; b:N |] ==> ?c : PROD u: Eq(N,a#+b,0) . Eq(N,a,0)" |
328 schematic_lemma add_eq0_lemma: "[| a:N; b:N |] ==> ?c : PROD u: Eq(N,a#+b,0) . Eq(N,a,0)" |
329 apply (tactic {* NE_tac @{context} "a" 1 *}) |
329 apply (tactic {* NE_tac @{context} "a" 1 *}) |
330 apply (rule_tac [3] replace_type) |
330 apply (rule_tac [3] replace_type) |
331 apply (tactic "arith_rew_tac []") |
331 apply (tactic "arith_rew_tac []") |
332 apply (tactic "intr_tac []") (*strips remaining PRODs*) |
332 apply (tactic "intr_tac []") (*strips remaining PRODs*) |
333 apply (rule_tac [2] zero_ne_succ [THEN FE]) |
333 apply (rule_tac [2] zero_ne_succ [THEN FE]) |
334 apply (erule_tac [3] EqE [THEN sym_elem]) |
334 apply (erule_tac [3] EqE [THEN sym_elem]) |
335 apply (tactic {* typechk_tac [thm "add_typing"] *}) |
335 apply (tactic {* typechk_tac [@{thm add_typing}] *}) |
336 done |
336 done |
337 |
337 |
338 (*Version of above with the premise a+b=0. |
338 (*Version of above with the premise a+b=0. |
339 Again, resolution instantiates variables in ProdE *) |
339 Again, resolution instantiates variables in ProdE *) |
340 lemma add_eq0: "[| a:N; b:N; a #+ b = 0 : N |] ==> a = 0 : N" |
340 lemma add_eq0: "[| a:N; b:N; a #+ b = 0 : N |] ==> a = 0 : N" |
364 apply (rule absdiff_eq0_lem [THEN SumE]) |
364 apply (rule absdiff_eq0_lem [THEN SumE]) |
365 apply (tactic "TRYALL assume_tac") |
365 apply (tactic "TRYALL assume_tac") |
366 apply (tactic eqintr_tac) |
366 apply (tactic eqintr_tac) |
367 apply (rule add_diff_inverse [THEN sym_elem, THEN trans_elem]) |
367 apply (rule add_diff_inverse [THEN sym_elem, THEN trans_elem]) |
368 apply (rule_tac [3] EqE, tactic "assume_tac 3") |
368 apply (rule_tac [3] EqE, tactic "assume_tac 3") |
369 apply (tactic {* hyp_arith_rew_tac [thm "add_0_right"] *}) |
369 apply (tactic {* hyp_arith_rew_tac [@{thm add_0_right}] *}) |
370 done |
370 done |
371 |
371 |
372 |
372 |
373 subsection {* Remainder and Quotient *} |
373 subsection {* Remainder and Quotient *} |
374 |
374 |
375 (*typing of remainder: short and long versions*) |
375 (*typing of remainder: short and long versions*) |
376 |
376 |
377 lemma mod_typing: "[| a:N; b:N |] ==> a mod b : N" |
377 lemma mod_typing: "[| a:N; b:N |] ==> a mod b : N" |
378 apply (unfold mod_def) |
378 apply (unfold mod_def) |
379 apply (tactic {* typechk_tac [thm "absdiff_typing"] *}) |
379 apply (tactic {* typechk_tac [@{thm absdiff_typing}] *}) |
380 done |
380 done |
381 |
381 |
382 lemma mod_typingL: "[| a=c:N; b=d:N |] ==> a mod b = c mod d : N" |
382 lemma mod_typingL: "[| a=c:N; b=d:N |] ==> a mod b = c mod d : N" |
383 apply (unfold mod_def) |
383 apply (unfold mod_def) |
384 apply (tactic {* equal_tac [thm "absdiff_typingL"] *}) |
384 apply (tactic {* equal_tac [@{thm absdiff_typingL}] *}) |
385 done |
385 done |
386 |
386 |
387 |
387 |
388 (*computation for mod : 0 and successor cases*) |
388 (*computation for mod : 0 and successor cases*) |
389 |
389 |
390 lemma modC0: "b:N ==> 0 mod b = 0 : N" |
390 lemma modC0: "b:N ==> 0 mod b = 0 : N" |
391 apply (unfold mod_def) |
391 apply (unfold mod_def) |
392 apply (tactic {* rew_tac [thm "absdiff_typing"] *}) |
392 apply (tactic {* rew_tac [@{thm absdiff_typing}] *}) |
393 done |
393 done |
394 |
394 |
395 lemma modC_succ: |
395 lemma modC_succ: |
396 "[| a:N; b:N |] ==> succ(a) mod b = rec(succ(a mod b) |-| b, 0, %x y. succ(a mod b)) : N" |
396 "[| a:N; b:N |] ==> succ(a) mod b = rec(succ(a mod b) |-| b, 0, %x y. succ(a mod b)) : N" |
397 apply (unfold mod_def) |
397 apply (unfold mod_def) |
398 apply (tactic {* rew_tac [thm "absdiff_typing"] *}) |
398 apply (tactic {* rew_tac [@{thm absdiff_typing}] *}) |
399 done |
399 done |
400 |
400 |
401 |
401 |
402 (*typing of quotient: short and long versions*) |
402 (*typing of quotient: short and long versions*) |
403 |
403 |
404 lemma div_typing: "[| a:N; b:N |] ==> a div b : N" |
404 lemma div_typing: "[| a:N; b:N |] ==> a div b : N" |
405 apply (unfold div_def) |
405 apply (unfold div_def) |
406 apply (tactic {* typechk_tac [thm "absdiff_typing", thm "mod_typing"] *}) |
406 apply (tactic {* typechk_tac [@{thm absdiff_typing}, @{thm mod_typing}] *}) |
407 done |
407 done |
408 |
408 |
409 lemma div_typingL: "[| a=c:N; b=d:N |] ==> a div b = c div d : N" |
409 lemma div_typingL: "[| a=c:N; b=d:N |] ==> a div b = c div d : N" |
410 apply (unfold div_def) |
410 apply (unfold div_def) |
411 apply (tactic {* equal_tac [thm "absdiff_typingL", thm "mod_typingL"] *}) |
411 apply (tactic {* equal_tac [@{thm absdiff_typingL}, @{thm mod_typingL}] *}) |
412 done |
412 done |
413 |
413 |
414 lemmas div_typing_rls = mod_typing div_typing absdiff_typing |
414 lemmas div_typing_rls = mod_typing div_typing absdiff_typing |
415 |
415 |
416 |
416 |
417 (*computation for quotient: 0 and successor cases*) |
417 (*computation for quotient: 0 and successor cases*) |
418 |
418 |
419 lemma divC0: "b:N ==> 0 div b = 0 : N" |
419 lemma divC0: "b:N ==> 0 div b = 0 : N" |
420 apply (unfold div_def) |
420 apply (unfold div_def) |
421 apply (tactic {* rew_tac [thm "mod_typing", thm "absdiff_typing"] *}) |
421 apply (tactic {* rew_tac [@{thm mod_typing}, @{thm absdiff_typing}] *}) |
422 done |
422 done |
423 |
423 |
424 lemma divC_succ: |
424 lemma divC_succ: |
425 "[| a:N; b:N |] ==> succ(a) div b = |
425 "[| a:N; b:N |] ==> succ(a) div b = |
426 rec(succ(a) mod b, succ(a div b), %x y. a div b) : N" |
426 rec(succ(a) mod b, succ(a div b), %x y. a div b) : N" |
427 apply (unfold div_def) |
427 apply (unfold div_def) |
428 apply (tactic {* rew_tac [thm "mod_typing"] *}) |
428 apply (tactic {* rew_tac [@{thm mod_typing}] *}) |
429 done |
429 done |
430 |
430 |
431 |
431 |
432 (*Version of above with same condition as the mod one*) |
432 (*Version of above with same condition as the mod one*) |
433 lemma divC_succ2: "[| a:N; b:N |] ==> |
433 lemma divC_succ2: "[| a:N; b:N |] ==> |
434 succ(a) div b =rec(succ(a mod b) |-| b, succ(a div b), %x y. a div b) : N" |
434 succ(a) div b =rec(succ(a mod b) |-| b, succ(a div b), %x y. a div b) : N" |
435 apply (rule divC_succ [THEN trans_elem]) |
435 apply (rule divC_succ [THEN trans_elem]) |
436 apply (tactic {* rew_tac (thms "div_typing_rls" @ [thm "modC_succ"]) *}) |
436 apply (tactic {* rew_tac (@{thms div_typing_rls} @ [@{thm modC_succ}]) *}) |
437 apply (tactic {* NE_tac @{context} "succ (a mod b) |-|b" 1 *}) |
437 apply (tactic {* NE_tac @{context} "succ (a mod b) |-|b" 1 *}) |
438 apply (tactic {* rew_tac [thm "mod_typing", thm "div_typing", thm "absdiff_typing"] *}) |
438 apply (tactic {* rew_tac [@{thm mod_typing}, @{thm div_typing}, @{thm absdiff_typing}] *}) |
439 done |
439 done |
440 |
440 |
441 (*for case analysis on whether a number is 0 or a successor*) |
441 (*for case analysis on whether a number is 0 or a successor*) |
442 lemma iszero_decidable: "a:N ==> rec(a, inl(eq), %ka kb. inr(<ka, eq>)) : |
442 lemma iszero_decidable: "a:N ==> rec(a, inl(eq), %ka kb. inr(<ka, eq>)) : |
443 Eq(N,a,0) + (SUM x:N. Eq(N,a, succ(x)))" |
443 Eq(N,a,0) + (SUM x:N. Eq(N,a, succ(x)))" |
449 done |
449 done |
450 |
450 |
451 (*Main Result. Holds when b is 0 since a mod 0 = a and a div 0 = 0 *) |
451 (*Main Result. Holds when b is 0 since a mod 0 = a and a div 0 = 0 *) |
452 lemma mod_div_equality: "[| a:N; b:N |] ==> a mod b #+ (a div b) #* b = a : N" |
452 lemma mod_div_equality: "[| a:N; b:N |] ==> a mod b #+ (a div b) #* b = a : N" |
453 apply (tactic {* NE_tac @{context} "a" 1 *}) |
453 apply (tactic {* NE_tac @{context} "a" 1 *}) |
454 apply (tactic {* arith_rew_tac (thms "div_typing_rls" @ |
454 apply (tactic {* arith_rew_tac (@{thms div_typing_rls} @ |
455 [thm "modC0", thm "modC_succ", thm "divC0", thm "divC_succ2"]) *}) |
455 [@{thm modC0}, @{thm modC_succ}, @{thm divC0}, @{thm divC_succ2}]) *}) |
456 apply (rule EqE) |
456 apply (rule EqE) |
457 (*case analysis on succ(u mod b)|-|b *) |
457 (*case analysis on succ(u mod b)|-|b *) |
458 apply (rule_tac a1 = "succ (u mod b) |-| b" in iszero_decidable [THEN PlusE]) |
458 apply (rule_tac a1 = "succ (u mod b) |-| b" in iszero_decidable [THEN PlusE]) |
459 apply (erule_tac [3] SumE) |
459 apply (erule_tac [3] SumE) |
460 apply (tactic {* hyp_arith_rew_tac (thms "div_typing_rls" @ |
460 apply (tactic {* hyp_arith_rew_tac (@{thms div_typing_rls} @ |
461 [thm "modC0", thm "modC_succ", thm "divC0", thm "divC_succ2"]) *}) |
461 [@{thm modC0}, @{thm modC_succ}, @{thm divC0}, @{thm divC_succ2}]) *}) |
462 (*Replace one occurence of b by succ(u mod b). Clumsy!*) |
462 (*Replace one occurence of b by succ(u mod b). Clumsy!*) |
463 apply (rule add_typingL [THEN trans_elem]) |
463 apply (rule add_typingL [THEN trans_elem]) |
464 apply (erule EqE [THEN absdiff_eq0, THEN sym_elem]) |
464 apply (erule EqE [THEN absdiff_eq0, THEN sym_elem]) |
465 apply (rule_tac [3] refl_elem) |
465 apply (rule_tac [3] refl_elem) |
466 apply (tactic {* hyp_arith_rew_tac (thms "div_typing_rls") *}) |
466 apply (tactic {* hyp_arith_rew_tac @{thms div_typing_rls} *}) |
467 done |
467 done |
468 |
468 |
469 end |
469 end |