src/HOL/Arith.ML
changeset 7945 3aca6352f063
parent 7622 dcb93b295683
child 8100 6186ee807f2e
equal deleted inserted replaced
7944:cc1930ad1a88 7945:3aca6352f063
   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";