src/HOL/Arith.ML
changeset 5414 8a458866637c
parent 5409 e97558ee8e76
child 5427 26c9a7c0b36b
equal deleted inserted replaced
5413:9d11f2d39b13 5414:8a458866637c
   329 Addsimps  [le_add_diff_inverse, le_add_diff_inverse2];
   329 Addsimps  [le_add_diff_inverse, le_add_diff_inverse2];
   330 
   330 
   331 
   331 
   332 (*** More results about difference ***)
   332 (*** More results about difference ***)
   333 
   333 
   334 Goal "n < Suc(m) ==> Suc(m)-n = Suc(m-n)";
   334 Goal "n <= m ==> Suc(m)-n = Suc(m-n)";
   335 by (etac rev_mp 1);
   335 by (etac rev_mp 1);
   336 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   336 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   337 by (ALLGOALS Asm_simp_tac);
   337 by (ALLGOALS Asm_simp_tac);
   338 qed "Suc_diff_n";
   338 qed "Suc_diff_le";
   339 
   339 
   340 Goal "m - n < Suc(m)";
   340 Goal "m - n < Suc(m)";
   341 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   341 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   342 by (etac less_SucE 3);
   342 by (etac less_SucE 3);
   343 by (ALLGOALS (asm_simp_tac (simpset() addsimps [less_Suc_eq])));
   343 by (ALLGOALS (asm_simp_tac (simpset() addsimps [less_Suc_eq])));
   370 Addsimps [diff_Suc_less];
   370 Addsimps [diff_Suc_less];
   371 
   371 
   372 Goal "i<n ==> n - Suc i < n - i";
   372 Goal "i<n ==> n - Suc i < n - i";
   373 by (exhaust_tac "n" 1);
   373 by (exhaust_tac "n" 1);
   374 by Safe_tac;
   374 by Safe_tac;
   375 by (asm_simp_tac (simpset() addsimps [Suc_diff_n]) 1);
   375 by (asm_simp_tac (simpset() addsimps [le_eq_less_Suc, Suc_diff_le]) 1);
   376 qed "diff_Suc_less_diff";
   376 qed "diff_Suc_less_diff";
   377 
   377 
   378 Goal "m - n <= Suc m - n";
   378 Goal "m - n <= Suc m - n";
   379 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   379 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   380 by (ALLGOALS Asm_simp_tac);
   380 by (ALLGOALS Asm_simp_tac);
   386 qed "diff_commute";
   386 qed "diff_commute";
   387 
   387 
   388 Goal "!!i j k:: nat. k<=j --> j<=i --> i - (j - k) = i - j + k";
   388 Goal "!!i j k:: nat. k<=j --> j<=i --> i - (j - k) = i - j + k";
   389 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1);
   389 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1);
   390 by (ALLGOALS Asm_simp_tac);
   390 by (ALLGOALS Asm_simp_tac);
   391 by (asm_simp_tac
   391 by (asm_simp_tac (simpset() addsimps [Suc_diff_le, le_Suc_eq]) 1);
   392     (simpset() addsimps [Suc_diff_n, le_imp_less_Suc, le_Suc_eq]) 1);
       
   393 qed_spec_mp "diff_diff_right";
   392 qed_spec_mp "diff_diff_right";
   394 
   393 
   395 Goal "!!i j k:: nat. k<=j --> (i + j) - k = i + (j - k)";
   394 Goal "!!i j k:: nat. k<=j --> (i + j) - k = i + (j - k)";
   396 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1);
   395 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1);
   397 by (ALLGOALS Asm_simp_tac);
   396 by (ALLGOALS Asm_simp_tac);
   438 by (res_inst_tac [("x","j - i")] exI 1);
   437 by (res_inst_tac [("x","j - i")] exI 1);
   439 by (asm_simp_tac (simpset() addsimps [add_diff_inverse, less_not_sym]) 1);
   438 by (asm_simp_tac (simpset() addsimps [add_diff_inverse, less_not_sym]) 1);
   440 qed "less_imp_add_positive";
   439 qed "less_imp_add_positive";
   441 
   440 
   442 Goal "Suc(m)-n = (if m<n then 0 else Suc(m-n))";
   441 Goal "Suc(m)-n = (if m<n then 0 else Suc(m-n))";
   443 by (simp_tac (simpset() addsimps [leI, Suc_le_eq, 
   442 by (simp_tac (simpset() addsimps [leI, Suc_le_eq, Suc_diff_le]) 1);
   444 				  le_imp_less_Suc RS Suc_diff_n]) 1);
   443 qed "if_Suc_diff_le";
   445 qed "if_Suc_diff_n";
       
   446 
   444 
   447 Goal "Suc(m)-n <= Suc(m-n)";
   445 Goal "Suc(m)-n <= Suc(m-n)";
   448 by (simp_tac (simpset() addsimps [if_Suc_diff_n]) 1);
   446 by (simp_tac (simpset() addsimps [if_Suc_diff_le]) 1);
   449 qed "diff_Suc_le_Suc_diff";
   447 qed "diff_Suc_le_Suc_diff";
   450 
   448 
   451 Goal "P(k) --> (!n. P(Suc(n))--> P(n)) --> P(k-i)";
   449 Goal "P(k) --> (!n. P(Suc(n))--> P(n)) --> P(k-i)";
   452 by (res_inst_tac [("m","k"),("n","i")] diff_induct 1);
   450 by (res_inst_tac [("m","k"),("n","i")] diff_induct 1);
   453 by (ALLGOALS (Clarify_tac THEN' Simp_tac THEN' TRY o Blast_tac));
   451 by (ALLGOALS (Clarify_tac THEN' Simp_tac THEN' TRY o Blast_tac));
   469 val add_commute_k = read_instantiate [("n","k")] add_commute;
   467 val add_commute_k = read_instantiate [("n","k")] add_commute;
   470 by (asm_simp_tac (simpset() addsimps ([add_commute_k])) 1);
   468 by (asm_simp_tac (simpset() addsimps ([add_commute_k])) 1);
   471 qed "diff_cancel2";
   469 qed "diff_cancel2";
   472 Addsimps [diff_cancel2];
   470 Addsimps [diff_cancel2];
   473 
   471 
   474 (*From Clemens Ballarin*)
   472 (*From Clemens Ballarin, proof by lcp*)
   475 Goal "!!n::nat. [| k<=n; n<=m |] ==> (m-k) - (n-k) = m-n";
   473 Goal "!!n::nat. [| k<=n; n<=m |] ==> (m-k) - (n-k) = m-n";
   476 by (subgoal_tac "k<=n --> n<=m --> (m-k) - (n-k) = m-n" 1);
   474 by (REPEAT (etac rev_mp 1));
   477 by (Asm_full_simp_tac 1);
   475 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   478 by (induct_tac "k" 1);
   476 by (ALLGOALS Asm_simp_tac);
   479 by (Simp_tac 1);
   477 (*a confluence problem*)
   480 (* Induction step *)
   478 by (asm_simp_tac (simpset() addsimps [Suc_diff_le, le_Suc_eq]) 1);
   481 by (subgoal_tac "Suc na <= m --> n <= m --> Suc na <= n --> \
       
   482 \                Suc (m - Suc na) - Suc (n - Suc na) = m-n" 1);
       
   483 by (Asm_full_simp_tac 1);
       
   484 by (blast_tac (claset() addIs [le_trans]) 1);
       
   485 by (auto_tac (claset() addIs [Suc_leD], simpset() delsimps [diff_Suc_Suc]));
       
   486 by (asm_full_simp_tac (simpset() delsimps [Suc_less_eq] 
       
   487 		       addsimps [le_imp_less_Suc RS Suc_diff_n RS sym]) 1);
       
   488 qed "diff_right_cancel";
   479 qed "diff_right_cancel";
   489 
   480 
   490 Goal "!!n::nat. n - (n+m) = 0";
   481 Goal "!!n::nat. n - (n+m) = 0";
   491 by (induct_tac "n" 1);
   482 by (induct_tac "n" 1);
   492 by (ALLGOALS Asm_simp_tac);
   483 by (ALLGOALS Asm_simp_tac);
   620 by (dtac diff_less_mono 1);
   611 by (dtac diff_less_mono 1);
   621 by (rtac le_add2 1);
   612 by (rtac le_add2 1);
   622 by (Asm_full_simp_tac 1);
   613 by (Asm_full_simp_tac 1);
   623 qed "add_less_imp_less_diff";
   614 qed "add_less_imp_less_diff";
   624 
   615 
   625 Goal "n <= m ==> Suc m - n = Suc (m - n)";
       
   626 by (asm_full_simp_tac (simpset() addsimps [le_imp_less_Suc RS Suc_diff_n]) 1);
       
   627 qed "Suc_diff_le";
       
   628 
       
   629 Goal "Suc i <= n ==> Suc (n - Suc i) = n - i";
   616 Goal "Suc i <= n ==> Suc (n - Suc i) = n - i";
   630 by (asm_full_simp_tac
   617 by (asm_simp_tac (simpset() addsimps [Suc_diff_le RS sym]) 1);
   631     (simpset() addsimps [Suc_diff_n RS sym, le_eq_less_Suc]) 1);
       
   632 qed "Suc_diff_Suc";
   618 qed "Suc_diff_Suc";
   633 
   619 
   634 Goal "!! i::nat. i <= n ==> n - (n - i) = i";
   620 Goal "!! i::nat. i <= n ==> n - (n - i) = i";
   635 by (etac rev_mp 1);
   621 by (etac rev_mp 1);
   636 by (res_inst_tac [("m","n"),("n","i")] diff_induct 1);
   622 by (res_inst_tac [("m","n"),("n","i")] diff_induct 1);
   685 Goal "0 < n ==> (m-1 < n) = (m<=n)";
   671 Goal "0 < n ==> (m-1 < n) = (m<=n)";
   686 by (exhaust_tac "m" 1);
   672 by (exhaust_tac "m" 1);
   687 by (auto_tac (claset(), simpset() addsimps [Suc_le_eq]));
   673 by (auto_tac (claset(), simpset() addsimps [Suc_le_eq]));
   688 qed "less_pred_eq";
   674 qed "less_pred_eq";
   689 
   675 
       
   676 (*In ordinary notation: if 0<n and n<=m then m-n < m *)
       
   677 Goal "[| 0<n; ~ m<n |] ==> m - n < m";
       
   678 by (subgoal_tac "0<n --> ~ m<n --> m - n < m" 1);
       
   679 by (Blast_tac 1);
       
   680 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
       
   681 by (ALLGOALS(asm_simp_tac(simpset() addsimps [diff_less_Suc])));
       
   682 qed "diff_less";
       
   683 
       
   684 Goal "[| 0<n; n<=m |] ==> m - n < m";
       
   685 by (asm_simp_tac (simpset() addsimps [diff_less, not_less_iff_le]) 1);
       
   686 qed "le_diff_less";
       
   687 
   690 
   688 
   691 
   689 
   692 (** (Anti)Monotonicity of subtraction -- by Stefan Merz **)
   690 (** (Anti)Monotonicity of subtraction -- by Stefan Merz **)
   693 
   691 
   694 (* Monotonicity of subtraction in first argument *)
   692 (* Monotonicity of subtraction in first argument *)
   705 by (case_tac "n <= na" 1);
   703 by (case_tac "n <= na" 1);
   706 by (subgoal_tac "m <= na" 1);
   704 by (subgoal_tac "m <= na" 1);
   707 by (asm_simp_tac (simpset() addsimps [Suc_diff_le]) 1);
   705 by (asm_simp_tac (simpset() addsimps [Suc_diff_le]) 1);
   708 by (fast_tac (claset() addEs [le_trans]) 1);
   706 by (fast_tac (claset() addEs [le_trans]) 1);
   709 by (dtac not_leE 1);
   707 by (dtac not_leE 1);
   710 by (asm_simp_tac (simpset() addsimps [if_Suc_diff_n]) 1);
   708 by (asm_simp_tac (simpset() addsimps [if_Suc_diff_le]) 1);
   711 qed_spec_mp "diff_le_mono2";
   709 qed_spec_mp "diff_le_mono2";