129 |
129 |
130 Goal "(0<m+n) = (0<m | 0<n)"; |
130 Goal "(0<m+n) = (0<m | 0<n)"; |
131 by (simp_tac (simpset() delsimps [neq0_conv] addsimps [neq0_conv RS sym]) 1); |
131 by (simp_tac (simpset() delsimps [neq0_conv] addsimps [neq0_conv RS sym]) 1); |
132 qed "add_gr_0"; |
132 qed "add_gr_0"; |
133 AddIffs [add_gr_0]; |
133 AddIffs [add_gr_0]; |
134 |
|
135 (* FIXME: really needed?? *) |
|
136 Goal "((m+n)-1 = 0) = (m=0 & n-1 = 0 | m-1 = 0 & n=0)"; |
|
137 by (exhaust_tac "m" 1); |
|
138 by (ALLGOALS (fast_tac (claset() addss (simpset())))); |
|
139 qed "pred_add_is_0"; |
|
140 (*Addsimps [pred_add_is_0];*) |
|
141 |
134 |
142 (* Could be generalized, eg to "k<n ==> m+(n-(Suc k)) = (m+n)-(Suc k)" *) |
135 (* Could be generalized, eg to "k<n ==> m+(n-(Suc k)) = (m+n)-(Suc k)" *) |
143 Goal "0<n ==> m + (n-1) = (m+n)-1"; |
136 Goal "0<n ==> m + (n-1) = (m+n)-1"; |
144 by (exhaust_tac "m" 1); |
137 by (exhaust_tac "m" 1); |
145 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_Suc, Suc_n_not_n] |
138 by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_Suc, Suc_n_not_n] |
1011 solver all the time rather than add the additional check. *) |
1004 solver all the time rather than add the additional check. *) |
1012 |
1005 |
1013 simpset_ref () := (simpset() addSolver |
1006 simpset_ref () := (simpset() addSolver |
1014 (mk_solver "lin. arith." Fast_Arith.cut_lin_arith_tac)); |
1007 (mk_solver "lin. arith." Fast_Arith.cut_lin_arith_tac)); |
1015 |
1008 |
1016 (* Elimination of `-' on nat due to John Harrison *) |
1009 (*Elimination of `-' on nat due to John Harrison. An alternative is to |
1017 Goal "P(a - b::nat) = (!d. (b = a + d --> P 0) & (a = b + d --> P d))"; |
1010 replace b=a+d by a<b; not clear that it makes much difference. *) |
|
1011 Goal "P(a - b::nat) = (ALL d. (b = a + d --> P 0) & (a = b + d --> P d))"; |
1018 by (case_tac "a <= b" 1); |
1012 by (case_tac "a <= b" 1); |
1019 by Auto_tac; |
1013 by Auto_tac; |
1020 by (eres_inst_tac [("x","b-a")] allE 1); |
1014 by (eres_inst_tac [("x","b-a")] allE 1); |
1021 by (asm_simp_tac (simpset() addsimps [diff_is_0_eq RS iffD2]) 1); |
1015 by (asm_simp_tac (simpset() addsimps [diff_is_0_eq RS iffD2]) 1); |
1022 qed "nat_diff_split"; |
1016 qed "nat_diff_split"; |
|
1017 |
1023 |
1018 |
1024 (* FIXME: K true should be replaced by a sensible test to speed things up |
1019 (* FIXME: K true should be replaced by a sensible test to speed things up |
1025 in case there are lots of irrelevant terms involved; |
1020 in case there are lots of irrelevant terms involved; |
1026 elimination of min/max can be optimized: |
1021 elimination of min/max can be optimized: |
1027 (max m n + k <= r) = (m+k <= r & n+k <= r) |
1022 (max m n + k <= r) = (m+k <= r & n+k <= r) |
1118 qed "diff_less"; |
1113 qed "diff_less"; |
1119 |
1114 |
1120 |
1115 |
1121 (*** Reducting subtraction to addition ***) |
1116 (*** Reducting subtraction to addition ***) |
1122 |
1117 |
1123 (*Intended for use with linear arithmetic, but useful in its own right*) |
|
1124 Goal "P (x-y) = (ALL z. (x<y --> P 0) & (x = y+z --> P z))"; |
|
1125 by (case_tac "x<y" 1); |
|
1126 by (auto_tac (claset(), simpset() addsimps [diff_is_0_eq RS iffD2])); |
|
1127 qed "split_diff"; |
|
1128 |
|
1129 val remove_diff_ss = |
|
1130 simpset() |
|
1131 delsimps ex_simps@all_simps |
|
1132 addsimps [le_diff_conv2, le_diff_conv, le_imp_diff_is_add, |
|
1133 diff_diff_right] |
|
1134 addcongs [conj_cong] |
|
1135 addsplits [split_diff]; |
|
1136 |
|
1137 Goal "n<=(l::nat) --> Suc l - n + m = Suc (l - n + m)"; |
1118 Goal "n<=(l::nat) --> Suc l - n + m = Suc (l - n + m)"; |
1138 by (simp_tac remove_diff_ss 1); |
1119 by (simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1139 qed_spec_mp "Suc_diff_add_le"; |
1120 qed_spec_mp "Suc_diff_add_le"; |
1140 |
1121 |
1141 Goal "i<n ==> n - Suc i < n - i"; |
1122 Goal "i<n ==> n - Suc i < n - i"; |
1142 by (asm_simp_tac remove_diff_ss 1); |
1123 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1143 qed "diff_Suc_less_diff"; |
1124 qed "diff_Suc_less_diff"; |
1144 |
1125 |
1145 Goal "Suc(m)-n = (if m<n then 0 else Suc(m-n))"; |
1126 Goal "Suc(m)-n = (if m<n then 0 else Suc(m-n))"; |
1146 by (simp_tac remove_diff_ss 1); |
1127 by (simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1147 qed "if_Suc_diff_le"; |
1128 qed "if_Suc_diff_le"; |
1148 |
1129 |
1149 Goal "Suc(m)-n <= Suc(m-n)"; |
1130 Goal "Suc(m)-n <= Suc(m-n)"; |
1150 by (simp_tac remove_diff_ss 1); |
1131 by (simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1151 qed "diff_Suc_le_Suc_diff"; |
1132 qed "diff_Suc_le_Suc_diff"; |
1152 |
1133 |
1153 Goal "[| k<=n; n<=m |] ==> (m-k) - (n-k) = m-(n::nat)"; |
1134 Goal "[| k<=n; n<=m |] ==> (m-k) - (n-k) = m-(n::nat)"; |
1154 by (asm_simp_tac remove_diff_ss 1); |
1135 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1155 qed "diff_right_cancel"; |
1136 qed "diff_right_cancel"; |
1156 |
1137 |
1157 |
1138 |
1158 (** (Anti)Monotonicity of subtraction -- by Stephan Merz **) |
1139 (** (Anti)Monotonicity of subtraction -- by Stephan Merz **) |
1159 |
1140 |
1160 (* Monotonicity of subtraction in first argument *) |
1141 (* Monotonicity of subtraction in first argument *) |
1161 Goal "m <= (n::nat) ==> (m-l) <= (n-l)"; |
1142 Goal "m <= (n::nat) ==> (m-l) <= (n-l)"; |
1162 by (asm_simp_tac remove_diff_ss 1); |
1143 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1163 qed "diff_le_mono"; |
1144 qed "diff_le_mono"; |
1164 |
1145 |
1165 Goal "m <= (n::nat) ==> (l-n) <= (l-m)"; |
1146 Goal "m <= (n::nat) ==> (l-n) <= (l-m)"; |
1166 by (asm_simp_tac remove_diff_ss 1); |
1147 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1167 qed "diff_le_mono2"; |
1148 qed "diff_le_mono2"; |
1168 |
1149 |
1169 (*This proof requires natdiff_cancel_sums*) |
|
1170 Goal "[| m < (n::nat); m<l |] ==> (l-n) < (l-m)"; |
1150 Goal "[| m < (n::nat); m<l |] ==> (l-n) < (l-m)"; |
1171 by (asm_simp_tac remove_diff_ss 1); |
1151 by (asm_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1172 qed "diff_less_mono2"; |
1152 qed "diff_less_mono2"; |
1173 |
1153 |
1174 Goal "[| m-n = 0; n-m = 0 |] ==> m=n"; |
1154 Goal "[| m-n = 0; n-m = 0 |] ==> m=n"; |
1175 by (asm_full_simp_tac remove_diff_ss 1); |
1155 by (asm_full_simp_tac (simpset() addsplits [nat_diff_split]) 1); |
1176 qed "diffs0_imp_equal"; |
1156 qed "diffs0_imp_equal"; |