src/HOL/Arith.ML
changeset 3352 04502e5431fb
parent 3339 cfa72a70f2b5
child 3366 2402c6ab1561
equal deleted inserted replaced
3351:ed64b6799303 3352:04502e5431fb
   323 qed_goal "diff_self_eq_0" Arith.thy "m - m = 0"
   323 qed_goal "diff_self_eq_0" Arith.thy "m - m = 0"
   324  (fn _ => [induct_tac "m" 1, ALLGOALS Asm_simp_tac]);
   324  (fn _ => [induct_tac "m" 1, ALLGOALS Asm_simp_tac]);
   325 Addsimps [diff_self_eq_0];
   325 Addsimps [diff_self_eq_0];
   326 
   326 
   327 (*Addition is the inverse of subtraction: if n<=m then n+(m-n) = m. *)
   327 (*Addition is the inverse of subtraction: if n<=m then n+(m-n) = m. *)
   328 val [prem] = goal Arith.thy "[| ~ m<n |] ==> n+(m-n) = (m::nat)";
   328 val [prem] = goal Arith.thy "~ m<n ==> n+(m-n) = (m::nat)";
   329 by (rtac (prem RS rev_mp) 1);
   329 by (rtac (prem RS rev_mp) 1);
   330 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   330 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   331 by (ALLGOALS (Asm_simp_tac));
   331 by (ALLGOALS Asm_simp_tac);
   332 qed "add_diff_inverse";
   332 qed "add_diff_inverse";
   333 
   333 
   334 Delsimps  [diff_Suc];
   334 Delsimps  [diff_Suc];
   335 
   335 
   336 
   336 
   337 (*** More results about difference ***)
   337 (*** More results about difference ***)
       
   338 
       
   339 val [prem] = goal Arith.thy "n < Suc(m) ==> Suc(m)-n = Suc(m-n)";
       
   340 by (rtac (prem RS rev_mp) 1);
       
   341 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
       
   342 by (ALLGOALS Asm_simp_tac);
       
   343 qed "Suc_diff_n";
   338 
   344 
   339 goal Arith.thy "m - n < Suc(m)";
   345 goal Arith.thy "m - n < Suc(m)";
   340 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   346 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   341 by (etac less_SucE 3);
   347 by (etac less_SucE 3);
   342 by (ALLGOALS (asm_simp_tac (!simpset addsimps [less_Suc_eq])));
   348 by (ALLGOALS (asm_simp_tac (!simpset addsimps [less_Suc_eq])));
   345 goal Arith.thy "!!m::nat. m - n <= m";
   351 goal Arith.thy "!!m::nat. m - n <= m";
   346 by (res_inst_tac [("m","m"), ("n","n")] diff_induct 1);
   352 by (res_inst_tac [("m","m"), ("n","n")] diff_induct 1);
   347 by (ALLGOALS Asm_simp_tac);
   353 by (ALLGOALS Asm_simp_tac);
   348 qed "diff_le_self";
   354 qed "diff_le_self";
   349 
   355 
       
   356 goal Arith.thy "!!i::nat. i-j-k = i - (j+k)";
       
   357 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1);
       
   358 by (ALLGOALS Asm_simp_tac);
       
   359 qed "diff_diff_left";
       
   360 
       
   361 (*This and the next few suggested by Florian Kammüller*)
       
   362 goal Arith.thy "!!i::nat. i-j-k = i-k-j";
       
   363 by (simp_tac (!simpset addsimps [diff_diff_left, add_commute]) 1);
       
   364 qed "diff_commute";
       
   365 
       
   366 goal Arith.thy "!!i j k:: nat. k<=j --> j<=i --> i - (j - k) = i - j + k";
       
   367 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1);
       
   368 by (ALLGOALS Asm_simp_tac);
       
   369 by (asm_simp_tac
       
   370     (!simpset addsimps [Suc_diff_n, le_imp_less_Suc, le_Suc_eq]) 1);
       
   371 by (simp_tac
       
   372     (!simpset addsimps [add_diff_inverse, not_less_iff_le, add_commute]) 1);
       
   373 qed_spec_mp "diff_diff_right";
       
   374 
       
   375 goal Arith.thy "!!i j k:: nat. k<=j --> (i + j) - k = i + (j - k)";
       
   376 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1);
       
   377 by (ALLGOALS Asm_simp_tac);
       
   378 qed_spec_mp "diff_add_assoc";
       
   379 
   350 goal Arith.thy "!!n::nat. (n+m) - n = m";
   380 goal Arith.thy "!!n::nat. (n+m) - n = m";
   351 by (induct_tac "n" 1);
   381 by (induct_tac "n" 1);
   352 by (ALLGOALS Asm_simp_tac);
   382 by (ALLGOALS Asm_simp_tac);
   353 qed "diff_add_inverse";
   383 qed "diff_add_inverse";
   354 Addsimps [diff_add_inverse];
   384 Addsimps [diff_add_inverse];
   355 
   385 
   356 goal Arith.thy "!!n::nat.(m+n) - n = m";
   386 goal Arith.thy "!!n::nat.(m+n) - n = m";
   357 by (res_inst_tac [("m1","m")] (add_commute RS ssubst) 1);
   387 by (simp_tac (!simpset addsimps [diff_add_assoc]) 1);
   358 by (REPEAT (ares_tac [diff_add_inverse] 1));
       
   359 qed "diff_add_inverse2";
   388 qed "diff_add_inverse2";
   360 Addsimps [diff_add_inverse2];
   389 Addsimps [diff_add_inverse2];
   361 
   390 
   362 val [prem] = goal Arith.thy "m < Suc(n) ==> m-n = 0";
   391 val [prem] = goal Arith.thy "m < Suc(n) ==> m-n = 0";
   363 by (rtac (prem RS rev_mp) 1);
   392 by (rtac (prem RS rev_mp) 1);
   364 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   393 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   365 by (asm_simp_tac (!simpset addsimps [less_Suc_eq]) 1);
   394 by (asm_simp_tac (!simpset addsimps [less_Suc_eq]) 1);
   366 by (ALLGOALS (Asm_simp_tac));
   395 by (ALLGOALS Asm_simp_tac);
   367 qed "less_imp_diff_is_0";
   396 qed "less_imp_diff_is_0";
   368 
   397 
   369 val prems = goal Arith.thy "m-n = 0  -->  n-m = 0  -->  m=n";
   398 val prems = goal Arith.thy "m-n = 0  -->  n-m = 0  -->  m=n";
   370 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   399 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   371 by (REPEAT(Simp_tac 1 THEN TRY(atac 1)));
   400 by (REPEAT(Simp_tac 1 THEN TRY(atac 1)));
   372 qed_spec_mp "diffs0_imp_equal";
   401 qed_spec_mp "diffs0_imp_equal";
   373 
   402 
   374 val [prem] = goal Arith.thy "m<n ==> 0<n-m";
   403 val [prem] = goal Arith.thy "m<n ==> 0<n-m";
   375 by (rtac (prem RS rev_mp) 1);
   404 by (rtac (prem RS rev_mp) 1);
   376 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   405 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   377 by (ALLGOALS (Asm_simp_tac));
   406 by (ALLGOALS Asm_simp_tac);
   378 qed "less_imp_diff_positive";
   407 qed "less_imp_diff_positive";
   379 
       
   380 val [prem] = goal Arith.thy "n < Suc(m) ==> Suc(m)-n = Suc(m-n)";
       
   381 by (rtac (prem RS rev_mp) 1);
       
   382 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
       
   383 by (ALLGOALS (Asm_simp_tac));
       
   384 qed "Suc_diff_n";
       
   385 
   408 
   386 goal Arith.thy "Suc(m)-n = (if m<n then 0 else Suc(m-n))";
   409 goal Arith.thy "Suc(m)-n = (if m<n then 0 else Suc(m-n))";
   387 by (simp_tac (!simpset addsimps [less_imp_diff_is_0, not_less_eq, Suc_diff_n]
   410 by (simp_tac (!simpset addsimps [less_imp_diff_is_0, not_less_eq, Suc_diff_n]
   388                     setloop (split_tac [expand_if])) 1);
   411                     setloop (split_tac [expand_if])) 1);
   389 qed "if_Suc_diff_n";
   412 qed "if_Suc_diff_n";