407 (*This and the next few suggested by Florian Kammueller*) |
407 (*This and the next few suggested by Florian Kammueller*) |
408 Goal "!!i::nat. i-j-k = i-k-j"; |
408 Goal "!!i::nat. i-j-k = i-k-j"; |
409 by (simp_tac (simpset() addsimps [diff_diff_left, add_commute]) 1); |
409 by (simp_tac (simpset() addsimps [diff_diff_left, add_commute]) 1); |
410 qed "diff_commute"; |
410 qed "diff_commute"; |
411 |
411 |
412 Goal "k<=j --> j<=i --> i - (j - k) = i - j + (k::nat)"; |
|
413 by (res_inst_tac [("m","i"),("n","j")] diff_induct 1); |
|
414 by (ALLGOALS Asm_simp_tac); |
|
415 by (asm_simp_tac (simpset() addsimps [Suc_diff_le, le_Suc_eq]) 1); |
|
416 qed_spec_mp "diff_diff_right"; |
|
417 |
|
418 Goal "k <= (j::nat) --> (i + j) - k = i + (j - k)"; |
412 Goal "k <= (j::nat) --> (i + j) - k = i + (j - k)"; |
419 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1); |
413 by (res_inst_tac [("m","j"),("n","k")] diff_induct 1); |
420 by (ALLGOALS Asm_simp_tac); |
414 by (ALLGOALS Asm_simp_tac); |
421 qed_spec_mp "diff_add_assoc"; |
415 qed_spec_mp "diff_add_assoc"; |
422 |
416 |
426 |
420 |
427 Goal "(n+m) - n = (m::nat)"; |
421 Goal "(n+m) - n = (m::nat)"; |
428 by (induct_tac "n" 1); |
422 by (induct_tac "n" 1); |
429 by (ALLGOALS Asm_simp_tac); |
423 by (ALLGOALS Asm_simp_tac); |
430 qed "diff_add_inverse"; |
424 qed "diff_add_inverse"; |
431 Addsimps [diff_add_inverse]; |
|
432 |
425 |
433 Goal "(m+n) - n = (m::nat)"; |
426 Goal "(m+n) - n = (m::nat)"; |
434 by (simp_tac (simpset() addsimps [diff_add_assoc]) 1); |
427 by (simp_tac (simpset() addsimps [diff_add_assoc]) 1); |
435 qed "diff_add_inverse2"; |
428 qed "diff_add_inverse2"; |
436 Addsimps [diff_add_inverse2]; |
|
437 |
429 |
438 Goal "i <= (j::nat) ==> (j-i=k) = (j=k+i)"; |
430 Goal "i <= (j::nat) ==> (j-i=k) = (j=k+i)"; |
439 by Safe_tac; |
431 by Safe_tac; |
440 by (ALLGOALS Asm_simp_tac); |
432 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_add_inverse2]))); |
441 qed "le_imp_diff_is_add"; |
433 qed "le_imp_diff_is_add"; |
442 |
434 |
443 Goal "(m-n = 0) = (m <= n)"; |
435 Goal "(m-n = 0) = (m <= n)"; |
444 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
436 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
445 by (ALLGOALS Asm_simp_tac); |
437 by (ALLGOALS Asm_simp_tac); |
475 |
467 |
476 Goal "(k+m) - (k+n) = m - (n::nat)"; |
468 Goal "(k+m) - (k+n) = m - (n::nat)"; |
477 by (induct_tac "k" 1); |
469 by (induct_tac "k" 1); |
478 by (ALLGOALS Asm_simp_tac); |
470 by (ALLGOALS Asm_simp_tac); |
479 qed "diff_cancel"; |
471 qed "diff_cancel"; |
480 Addsimps [diff_cancel]; |
|
481 |
472 |
482 Goal "(m+k) - (n+k) = m - (n::nat)"; |
473 Goal "(m+k) - (n+k) = m - (n::nat)"; |
483 val add_commute_k = read_instantiate [("n","k")] add_commute; |
474 by (asm_simp_tac |
484 by (asm_simp_tac (simpset() addsimps [add_commute_k]) 1); |
475 (simpset() addsimps [diff_cancel, inst "n" "k" add_commute]) 1); |
485 qed "diff_cancel2"; |
476 qed "diff_cancel2"; |
486 Addsimps [diff_cancel2]; |
|
487 |
477 |
488 Goal "n - (n+m) = 0"; |
478 Goal "n - (n+m) = 0"; |
489 by (induct_tac "n" 1); |
479 by (induct_tac "n" 1); |
490 by (ALLGOALS Asm_simp_tac); |
480 by (ALLGOALS Asm_simp_tac); |
491 qed "diff_add_0"; |
481 qed "diff_add_0"; |
492 Addsimps [diff_add_0]; |
|
493 |
482 |
494 |
483 |
495 (** Difference distributes over multiplication **) |
484 (** Difference distributes over multiplication **) |
496 |
485 |
497 Goal "!!m::nat. (m - n) * k = (m * k) - (n * k)"; |
486 Goal "!!m::nat. (m - n) * k = (m * k) - (n * k)"; |
498 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
487 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1); |
499 by (ALLGOALS Asm_simp_tac); |
488 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_cancel]))); |
500 qed "diff_mult_distrib" ; |
489 qed "diff_mult_distrib" ; |
501 |
490 |
502 Goal "!!m::nat. k * (m - n) = (k * m) - (k * n)"; |
491 Goal "!!m::nat. k * (m - n) = (k * m) - (k * n)"; |
503 val mult_commute_k = read_instantiate [("m","k")] mult_commute; |
492 val mult_commute_k = read_instantiate [("m","k")] mult_commute; |
504 by (simp_tac (simpset() addsimps [diff_mult_distrib, mult_commute_k]) 1); |
493 by (simp_tac (simpset() addsimps [diff_mult_distrib, mult_commute_k]) 1); |
537 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [mult_commute]))); |
526 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [mult_commute]))); |
538 qed "mult_less_mono1"; |
527 qed "mult_less_mono1"; |
539 |
528 |
540 Goal "(0 < m*n) = (0<m & 0<n)"; |
529 Goal "(0 < m*n) = (0<m & 0<n)"; |
541 by (induct_tac "m" 1); |
530 by (induct_tac "m" 1); |
542 by (induct_tac "n" 2); |
531 by (case_tac "n" 2); |
543 by (ALLGOALS Asm_simp_tac); |
532 by (ALLGOALS Asm_simp_tac); |
544 qed "zero_less_mult_iff"; |
533 qed "zero_less_mult_iff"; |
545 Addsimps [zero_less_mult_iff]; |
534 Addsimps [zero_less_mult_iff]; |
|
535 |
|
536 Goal "(1 <= m*n) = (1<=m & 1<=n)"; |
|
537 by (induct_tac "m" 1); |
|
538 by (case_tac "n" 2); |
|
539 by (ALLGOALS Asm_simp_tac); |
|
540 qed "one_le_mult_iff"; |
|
541 Addsimps [one_le_mult_iff]; |
546 |
542 |
547 Goal "(m*n = 1) = (m=1 & n=1)"; |
543 Goal "(m*n = 1) = (m=1 & n=1)"; |
548 by (induct_tac "m" 1); |
544 by (induct_tac "m" 1); |
549 by (Simp_tac 1); |
545 by (Simp_tac 1); |
550 by (induct_tac "n" 1); |
546 by (induct_tac "n" 1); |
997 solver all the time rather than add the additional check. *) |
993 solver all the time rather than add the additional check. *) |
998 |
994 |
999 simpset_ref () := (simpset() addSolver |
995 simpset_ref () := (simpset() addSolver |
1000 (mk_solver "lin. arith." Fast_Arith.cut_lin_arith_tac)); |
996 (mk_solver "lin. arith." Fast_Arith.cut_lin_arith_tac)); |
1001 |
997 |
1002 (*Elimination of `-' on nat due to John Harrison. *) |
998 (*Elimination of `-' on nat*) |
1003 Goal "P(a - b::nat) = (ALL d. (b = a + d --> P 0) & (a = b + d --> P d))"; |
999 Goal "P(a - b::nat) = (ALL d. (a<b --> P 0) & (a = b + d --> P d))"; |
1004 by (case_tac "a <= b" 1); |
1000 by (case_tac "a < b" 1); |
1005 by Auto_tac; |
1001 by (auto_tac (claset(), simpset() addsimps [diff_is_0_eq RS iffD2])); |
1006 by (eres_inst_tac [("x","b-a")] allE 1); |
|
1007 by (asm_simp_tac (simpset() addsimps [diff_is_0_eq RS iffD2]) 1); |
|
1008 qed "nat_diff_split"; |
1002 qed "nat_diff_split"; |
1009 |
1003 |
1010 (*LCP's version, replacing b=a+d by a<b, which sometimes works better*) |
1004 val nat_diff_split = nat_diff_split; |
1011 Goal "P(a - b::nat) = (ALL d. (a<b --> P 0) & (a = b + d --> P d))"; |
|
1012 by (auto_tac (claset(), simpset() addsplits [nat_diff_split])); |
|
1013 qed "nat_diff_split'"; |
|
1014 |
|
1015 |
1005 |
1016 (* FIXME: K true should be replaced by a sensible test to speed things up |
1006 (* FIXME: K true should be replaced by a sensible test to speed things up |
1017 in case there are lots of irrelevant terms involved; |
1007 in case there are lots of irrelevant terms involved; |
1018 elimination of min/max can be optimized: |
1008 elimination of min/max can be optimized: |
1019 (max m n + k <= r) = (m+k <= r & n+k <= r) |
1009 (max m n + k <= r) = (m+k <= r & n+k <= r) |
1111 Goal "[| 0<n; 0<m |] ==> m - n < m"; |
1101 Goal "[| 0<n; 0<m |] ==> m - n < m"; |
1112 by (arith_tac 1); |
1102 by (arith_tac 1); |
1113 qed "diff_less"; |
1103 qed "diff_less"; |
1114 |
1104 |
1115 Goal "j <= (k::nat) ==> (j+i)-k = i-(k-j)"; |
1105 Goal "j <= (k::nat) ==> (j+i)-k = i-(k-j)"; |
1116 by (asm_simp_tac (simpset() addsplits [nat_diff_split']) 1); |
1106 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1117 qed "diff_add_assoc_diff"; |
1107 qed "diff_add_assoc_diff"; |
1118 |
1108 |
1119 |
1109 |
1120 (*** Reducing subtraction to addition ***) |
1110 (*** Reducing subtraction to addition ***) |
1121 |
1111 |
1136 qed "diff_Suc_le_Suc_diff"; |
1126 qed "diff_Suc_le_Suc_diff"; |
1137 |
1127 |
1138 (** Simplification of relational expressions involving subtraction **) |
1128 (** Simplification of relational expressions involving subtraction **) |
1139 |
1129 |
1140 Goal "[| k <= m; k <= (n::nat) |] ==> ((m-k) - (n-k)) = (m-n)"; |
1130 Goal "[| k <= m; k <= (n::nat) |] ==> ((m-k) - (n-k)) = (m-n)"; |
1141 by (asm_simp_tac (simpset() addsplits [nat_diff_split']) 1); |
1131 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1142 qed "diff_diff_eq"; |
1132 qed "diff_diff_eq"; |
1143 |
1133 |
1144 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k = n-k) = (m=n)"; |
1134 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k = n-k) = (m=n)"; |
1145 by (auto_tac (claset(), simpset() addsplits [nat_diff_split'])); |
1135 by (auto_tac (claset(), simpset() addsplits [nat_diff_split])); |
1146 qed "eq_diff_iff"; |
1136 qed "eq_diff_iff"; |
1147 |
1137 |
1148 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k < n-k) = (m<n)"; |
1138 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k < n-k) = (m<n)"; |
1149 by (auto_tac (claset(), simpset() addsplits [nat_diff_split'])); |
1139 by (auto_tac (claset(), simpset() addsplits [nat_diff_split])); |
1150 qed "less_diff_iff"; |
1140 qed "less_diff_iff"; |
1151 |
1141 |
1152 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k <= n-k) = (m<=n)"; |
1142 Goal "[| k <= m; k <= (n::nat) |] ==> (m-k <= n-k) = (m<=n)"; |
1153 by (auto_tac (claset(), simpset() addsplits [nat_diff_split'])); |
1143 by (auto_tac (claset(), simpset() addsplits [nat_diff_split])); |
1154 qed "le_diff_iff"; |
1144 qed "le_diff_iff"; |
1155 |
1145 |
1156 |
1146 |
1157 (** (Anti)Monotonicity of subtraction -- by Stephan Merz **) |
1147 (** (Anti)Monotonicity of subtraction -- by Stephan Merz **) |
1158 |
1148 |
1187 |
1177 |
1188 Goal "[| 1<n; 1<m |] ==> n<n*m"; |
1178 Goal "[| 1<n; 1<m |] ==> n<n*m"; |
1189 by (case_tac "m" 1); |
1179 by (case_tac "m" 1); |
1190 by Auto_tac; |
1180 by Auto_tac; |
1191 qed "n_less_n_mult_m"; |
1181 qed "n_less_n_mult_m"; |
|
1182 |
|
1183 |
|
1184 (** Rewriting to pull differences out **) |
|
1185 |
|
1186 Goal "k<=j --> i - (j - k) = i + (k::nat) - j"; |
|
1187 by (arith_tac 1); |
|
1188 qed "diff_diff_right"; |
|
1189 |
|
1190 Goal "k <= j ==> m - Suc (j - k) = m + k - Suc j"; |
|
1191 by (arith_tac 1); |
|
1192 qed "diff_Suc_diff_eq1"; |
|
1193 |
|
1194 Goal "k <= j ==> Suc (j - k) - m = Suc j - (k + m)"; |
|
1195 by (arith_tac 1); |
|
1196 qed "diff_Suc_diff_eq2"; |
|
1197 |
|
1198 (*The others are |
|
1199 i - j - k = i - (j + k), |
|
1200 k <= j ==> j - k + i = j + i - k, |
|
1201 k <= j ==> i + (j - k) = i + j - k *) |
|
1202 Addsimps [diff_diff_left, diff_diff_right, diff_add_assoc2 RS sym, |
|
1203 diff_add_assoc RS sym, diff_Suc_diff_eq1, diff_Suc_diff_eq2]; |
|
1204 |