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"; |