src/CTT/Arith.thy
changeset 39159 0dec18004e75
parent 36319 8feb2c4bef1a
child 58318 f95754ca7082
equal deleted inserted replaced
39158:e6b96b4cde7e 39159:0dec18004e75
    80 
    80 
    81 (*typing of mult: short and long versions*)
    81 (*typing of mult: short and long versions*)
    82 
    82 
    83 lemma mult_typing: "[| a:N;  b:N |] ==> a #* b : N"
    83 lemma mult_typing: "[| a:N;  b:N |] ==> a #* b : N"
    84 apply (unfold arith_defs)
    84 apply (unfold arith_defs)
    85 apply (tactic {* typechk_tac [thm "add_typing"] *})
    85 apply (tactic {* typechk_tac [@{thm add_typing}] *})
    86 done
    86 done
    87 
    87 
    88 lemma mult_typingL: "[| a=c:N;  b=d:N |] ==> a #* b = c #* d : N"
    88 lemma mult_typingL: "[| a=c:N;  b=d:N |] ==> a #* b = c #* d : N"
    89 apply (unfold arith_defs)
    89 apply (unfold arith_defs)
    90 apply (tactic {* equal_tac [thm "add_typingL"] *})
    90 apply (tactic {* equal_tac [@{thm add_typingL}] *})
    91 done
    91 done
    92 
    92 
    93 (*computation for mult: 0 and successor cases*)
    93 (*computation for mult: 0 and successor cases*)
    94 
    94 
    95 lemma multC0: "b:N ==> 0 #* b = 0 : N"
    95 lemma multC0: "b:N ==> 0 #* b = 0 : N"
   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
   269 apply (rule_tac [4] replace_type)
   269 apply (rule_tac [4] replace_type)
   270 apply (tactic "arith_rew_tac []")
   270 apply (tactic "arith_rew_tac []")
   271 (*Solves first 0 goal, simplifies others.  Two sugbgoals remain.
   271 (*Solves first 0 goal, simplifies others.  Two sugbgoals remain.
   272   Both follow by rewriting, (2) using quantified induction hyp*)
   272   Both follow by rewriting, (2) using quantified induction hyp*)
   273 apply (tactic "intr_tac []") (*strips remaining PRODs*)
   273 apply (tactic "intr_tac []") (*strips remaining PRODs*)
   274 apply (tactic {* hyp_arith_rew_tac [thm "add_0_right"] *})
   274 apply (tactic {* hyp_arith_rew_tac [@{thm add_0_right}] *})
   275 apply assumption
   275 apply assumption
   276 done
   276 done
   277 
   277 
   278 
   278 
   279 (*Version of above with premise   b-a=0   i.e.    a >= b.
   279 (*Version of above with premise   b-a=0   i.e.    a >= b.
   301 apply (tactic "equal_tac []")
   301 apply (tactic "equal_tac []")
   302 done
   302 done
   303 
   303 
   304 lemma absdiff_self_eq_0: "a:N ==> a |-| a = 0 : N"
   304 lemma absdiff_self_eq_0: "a:N ==> a |-| a = 0 : N"
   305 apply (unfold absdiff_def)
   305 apply (unfold absdiff_def)
   306 apply (tactic {* arith_rew_tac [thm "diff_self_eq_0"] *})
   306 apply (tactic {* arith_rew_tac [@{thm diff_self_eq_0}] *})
   307 done
   307 done
   308 
   308 
   309 lemma absdiffC0: "a:N ==> 0 |-| a = a : N"
   309 lemma absdiffC0: "a:N ==> 0 |-| a = a : N"
   310 apply (unfold absdiff_def)
   310 apply (unfold absdiff_def)
   311 apply (tactic "hyp_arith_rew_tac []")
   311 apply (tactic "hyp_arith_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"
   352 apply (tactic "intr_tac []")
   352 apply (tactic "intr_tac []")
   353 apply (tactic eqintr_tac)
   353 apply (tactic eqintr_tac)
   354 apply (rule_tac [2] add_eq0)
   354 apply (rule_tac [2] add_eq0)
   355 apply (rule add_eq0)
   355 apply (rule add_eq0)
   356 apply (rule_tac [6] add_commute [THEN trans_elem])
   356 apply (rule_tac [6] add_commute [THEN trans_elem])
   357 apply (tactic {* typechk_tac [thm "diff_typing"] *})
   357 apply (tactic {* typechk_tac [@{thm diff_typing}] *})
   358 done
   358 done
   359 
   359 
   360 (*if  a |-| b = 0  then  a = b
   360 (*if  a |-| b = 0  then  a = b
   361   proof: a-b=0 and b-a=0, so b = a+(b-a) = a+0 = a*)
   361   proof: a-b=0 and b-a=0, so b = a+(b-a) = a+0 = a*)
   362 lemma absdiff_eq0: "[| a |-| b = 0 : N;  a:N;  b:N |] ==> a = b : N"
   362 lemma absdiff_eq0: "[| a |-| b = 0 : N;  a:N;  b:N |] ==> a = b : 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