| author | wenzelm | 
| Fri, 10 Nov 2000 19:02:37 +0100 | |
| changeset 10432 | 3dfbc913d184 | 
| parent 9907 | 473a6604da94 | 
| child 11386 | cf8d81cf8034 | 
| permissions | -rw-r--r-- | 
| 9548 | 1 | (* Title: ZF/ArithSimp.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Lawrence C Paulson, Cambridge University Computer Laboratory | |
| 4 | Copyright 2000 University of Cambridge | |
| 5 | ||
| 6 | Arithmetic with simplification | |
| 7 | *) | |
| 8 | ||
| 9 | ||
| 10 | Addsimprocs ArithData.nat_cancel; | |
| 11 | ||
| 12 | ||
| 13 | (*** Difference ***) | |
| 14 | ||
| 15 | Goal "m #- m = 0"; | |
| 16 | by (subgoal_tac "natify(m) #- natify(m) = 0" 1); | |
| 17 | by (rtac (natify_in_nat RS nat_induct) 2); | |
| 18 | by Auto_tac; | |
| 19 | qed "diff_self_eq_0"; | |
| 20 | ||
| 21 | (**Addition is the inverse of subtraction**) | |
| 22 | ||
| 23 | (*We need m:nat even if we replace the RHS by natify(m), for consider e.g. | |
| 24 | n=2, m=omega; then n + (m-n) = 2 + (0-2) = 2 ~= 0 = natify(m).*) | |
| 25 | Goal "[| n le m; m:nat |] ==> n #+ (m#-n) = m"; | |
| 26 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 27 | by (etac rev_mp 1); | |
| 28 | by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
 | |
| 29 | by Auto_tac; | |
| 30 | qed "add_diff_inverse"; | |
| 31 | ||
| 32 | Goal "[| n le m; m:nat |] ==> (m#-n) #+ n = m"; | |
| 33 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 34 | by (asm_simp_tac (simpset() addsimps [add_commute, add_diff_inverse]) 1); | |
| 35 | qed "add_diff_inverse2"; | |
| 36 | ||
| 37 | (*Proof is IDENTICAL to that of add_diff_inverse*) | |
| 38 | Goal "[| n le m; m:nat |] ==> succ(m) #- n = succ(m#-n)"; | |
| 39 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 40 | by (etac rev_mp 1); | |
| 41 | by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
 | |
| 42 | by (ALLGOALS Asm_simp_tac); | |
| 43 | qed "diff_succ"; | |
| 44 | ||
| 45 | Goal "[| m: nat; n: nat |] ==> 0 < (n #- m) <-> m<n"; | |
| 46 | by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
 | |
| 47 | by (ALLGOALS Asm_simp_tac); | |
| 48 | qed "zero_less_diff"; | |
| 49 | Addsimps [zero_less_diff]; | |
| 50 | ||
| 51 | ||
| 52 | (** Difference distributes over multiplication **) | |
| 53 | ||
| 54 | Goal "(m #- n) #* k = (m #* k) #- (n #* k)"; | |
| 55 | by (subgoal_tac "(natify(m) #- natify(n)) #* natify(k) = \ | |
| 56 | \ (natify(m) #* natify(k)) #- (natify(n) #* natify(k))" 1); | |
| 57 | by (res_inst_tac [("m","natify(m)"),("n","natify(n)")] diff_induct 2);
 | |
| 58 | by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [diff_cancel]))); | |
| 59 | qed "diff_mult_distrib" ; | |
| 60 | ||
| 61 | Goal "k #* (m #- n) = (k #* m) #- (k #* n)"; | |
| 62 | by (simp_tac | |
| 63 | (simpset() addsimps [inst "m" "k" mult_commute, diff_mult_distrib]) 1); | |
| 64 | qed "diff_mult_distrib2"; | |
| 65 | ||
| 66 | ||
| 67 | (*** Remainder ***) | |
| 68 | ||
| 69 | (*We need m:nat even with natify*) | |
| 70 | Goal "[| 0<n; n le m; m:nat |] ==> m #- n < m"; | |
| 71 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 72 | by (etac rev_mp 1); | |
| 73 | by (etac rev_mp 1); | |
| 74 | by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
 | |
| 75 | by (ALLGOALS (asm_simp_tac (simpset() addsimps [diff_le_self]))); | |
| 76 | qed "div_termination"; | |
| 77 | ||
| 9907 | 78 | bind_thms ("div_rls",   (*for mod and div*)
 | 
| 9548 | 79 | nat_typechecks @ | 
| 80 | [Ord_transrec_type, apply_funtype, div_termination RS ltD, | |
| 9907 | 81 | nat_into_Ord, not_lt_iff_le RS iffD1]); | 
| 9548 | 82 | |
| 83 | val div_ss = simpset() addsimps [div_termination RS ltD, | |
| 84 | not_lt_iff_le RS iffD2]; | |
| 85 | ||
| 86 | Goalw [raw_mod_def] "[| m:nat; n:nat |] ==> raw_mod (m, n) : nat"; | |
| 87 | by (rtac Ord_transrec_type 1); | |
| 88 | by (auto_tac(claset(), simpset() addsimps [nat_into_Ord RS Ord_0_lt_iff])); | |
| 89 | by (REPEAT (ares_tac div_rls 1)); | |
| 90 | qed "raw_mod_type"; | |
| 91 | ||
| 92 | Goalw [mod_def] "m mod n : nat"; | |
| 93 | by (simp_tac (simpset() addsimps [mod_def, raw_mod_type]) 1); | |
| 94 | qed "mod_type"; | |
| 95 | AddTCs [mod_type]; | |
| 96 | AddIffs [mod_type]; | |
| 97 | ||
| 98 | ||
| 99 | (** Aribtrary definitions for division by zero. Useful to simplify | |
| 100 | certain equations **) | |
| 101 | ||
| 102 | Goalw [div_def] "a div 0 = 0"; | |
| 103 | by (rtac (raw_div_def RS def_transrec RS trans) 1); | |
| 104 | by (Asm_simp_tac 1); | |
| 105 | qed "DIVISION_BY_ZERO_DIV"; (*NOT for adding to default simpset*) | |
| 106 | ||
| 107 | Goalw [mod_def] "a mod 0 = natify(a)"; | |
| 108 | by (rtac (raw_mod_def RS def_transrec RS trans) 1); | |
| 109 | by (Asm_simp_tac 1); | |
| 110 | qed "DIVISION_BY_ZERO_MOD"; (*NOT for adding to default simpset*) | |
| 111 | ||
| 112 | fun div_undefined_case_tac s i = | |
| 113 | case_tac s i THEN | |
| 114 | asm_full_simp_tac | |
| 115 | (simpset() addsimps [nat_into_Ord RS Ord_0_lt_iff]) (i+1) THEN | |
| 116 | asm_simp_tac (simpset() addsimps [DIVISION_BY_ZERO_DIV, | |
| 117 | DIVISION_BY_ZERO_MOD]) i; | |
| 118 | ||
| 119 | Goal "m<n ==> raw_mod (m,n) = m"; | |
| 120 | by (rtac (raw_mod_def RS def_transrec RS trans) 1); | |
| 121 | by (asm_simp_tac (simpset() addsimps [div_termination RS ltD]) 1); | |
| 122 | qed "raw_mod_less"; | |
| 123 | ||
| 124 | Goal "[| m<n; n : nat |] ==> m mod n = m"; | |
| 125 | by (ftac lt_nat_in_nat 1 THEN assume_tac 1); | |
| 126 | by (asm_simp_tac (simpset() addsimps [mod_def, raw_mod_less]) 1); | |
| 127 | qed "mod_less"; | |
| 128 | ||
| 129 | Goal "[| 0<n; n le m; m:nat |] ==> raw_mod (m, n) = raw_mod (m#-n, n)"; | |
| 130 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 131 | by (rtac (raw_mod_def RS def_transrec RS trans) 1); | |
| 132 | by (asm_simp_tac div_ss 1); | |
| 133 | by (Blast_tac 1); | |
| 134 | qed "raw_mod_geq"; | |
| 135 | ||
| 136 | Goal "[| n le m; m:nat |] ==> m mod n = (m#-n) mod n"; | |
| 137 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 138 | by (div_undefined_case_tac "n=0" 1); | |
| 139 | by (asm_simp_tac (simpset() addsimps [mod_def, raw_mod_geq]) 1); | |
| 140 | qed "mod_geq"; | |
| 141 | ||
| 142 | Addsimps [mod_less]; | |
| 143 | ||
| 144 | ||
| 145 | (*** Division ***) | |
| 146 | ||
| 147 | Goalw [raw_div_def] "[| m:nat; n:nat |] ==> raw_div (m, n) : nat"; | |
| 148 | by (rtac Ord_transrec_type 1); | |
| 149 | by (auto_tac(claset(), simpset() addsimps [nat_into_Ord RS Ord_0_lt_iff])); | |
| 150 | by (REPEAT (ares_tac div_rls 1)); | |
| 151 | qed "raw_div_type"; | |
| 152 | ||
| 153 | Goalw [div_def] "m div n : nat"; | |
| 154 | by (simp_tac (simpset() addsimps [div_def, raw_div_type]) 1); | |
| 155 | qed "div_type"; | |
| 156 | AddTCs [div_type]; | |
| 157 | AddIffs [div_type]; | |
| 158 | ||
| 159 | Goal "m<n ==> raw_div (m,n) = 0"; | |
| 160 | by (rtac (raw_div_def RS def_transrec RS trans) 1); | |
| 161 | by (asm_simp_tac (simpset() addsimps [div_termination RS ltD]) 1); | |
| 162 | qed "raw_div_less"; | |
| 163 | ||
| 164 | Goal "[| m<n; n : nat |] ==> m div n = 0"; | |
| 165 | by (ftac lt_nat_in_nat 1 THEN assume_tac 1); | |
| 166 | by (asm_simp_tac (simpset() addsimps [div_def, raw_div_less]) 1); | |
| 167 | qed "div_less"; | |
| 168 | ||
| 169 | Goal "[| 0<n; n le m; m:nat |] ==> raw_div(m,n) = succ(raw_div(m#-n, n))"; | |
| 170 | by (subgoal_tac "n ~= 0" 1); | |
| 171 | by (Blast_tac 2); | |
| 172 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 173 | by (rtac (raw_div_def RS def_transrec RS trans) 1); | |
| 174 | by (asm_simp_tac div_ss 1); | |
| 175 | qed "raw_div_geq"; | |
| 176 | ||
| 177 | Goal "[| 0<n; n le m; m:nat |] ==> m div n = succ ((m#-n) div n)"; | |
| 178 | by (ftac lt_nat_in_nat 1 THEN etac nat_succI 1); | |
| 179 | by (asm_simp_tac (simpset() addsimps [div_def, raw_div_geq]) 1); | |
| 180 | qed "div_geq"; | |
| 181 | ||
| 182 | Addsimps [div_less, div_geq]; | |
| 183 | ||
| 184 | ||
| 185 | (*A key result*) | |
| 186 | Goal "[| m: nat; n: nat |] ==> (m div n)#*n #+ m mod n = m"; | |
| 187 | by (div_undefined_case_tac "n=0" 1); | |
| 188 | by (etac complete_induct 1); | |
| 189 | by (case_tac "x<n" 1); | |
| 190 | (*case n le x*) | |
| 191 | by (asm_full_simp_tac | |
| 192 | (simpset() addsimps [not_lt_iff_le, add_assoc, mod_geq, | |
| 193 | div_termination RS ltD, add_diff_inverse]) 2); | |
| 194 | (*case x<n*) | |
| 195 | by (Asm_simp_tac 1); | |
| 196 | val lemma = result(); | |
| 197 | ||
| 198 | Goal "(m div n)#*n #+ m mod n = natify(m)"; | |
| 199 | by (subgoal_tac | |
| 200 | "(natify(m) div natify(n))#*natify(n) #+ natify(m) mod natify(n) = \ | |
| 201 | \ natify(m)" 1); | |
| 202 | by (stac lemma 2); | |
| 203 | by Auto_tac; | |
| 204 | qed "mod_div_equality_natify"; | |
| 205 | ||
| 206 | Goal "m: nat ==> (m div n)#*n #+ m mod n = m"; | |
| 207 | by (asm_simp_tac (simpset() addsimps [mod_div_equality_natify]) 1); | |
| 208 | qed "mod_div_equality"; | |
| 209 | ||
| 210 | ||
| 211 | (*** Further facts about mod (mainly for mutilated chess board) ***) | |
| 212 | ||
| 213 | Goal "[| 0<n; m:nat; n:nat |] \ | |
| 214 | \ ==> succ(m) mod n = (if succ(m mod n) = n then 0 else succ(m mod n))"; | |
| 215 | by (etac complete_induct 1); | |
| 216 | by (excluded_middle_tac "succ(x)<n" 1); | |
| 217 | (* case succ(x) < n *) | |
| 218 | by (asm_simp_tac (simpset() addsimps [nat_le_refl RS lt_trans, | |
| 219 | succ_neq_self]) 2); | |
| 220 | by (asm_simp_tac (simpset() addsimps [ltD RS mem_imp_not_eq]) 2); | |
| 221 | (* case n le succ(x) *) | |
| 222 | by (asm_full_simp_tac (simpset() addsimps [mod_geq, not_lt_iff_le]) 1); | |
| 223 | by (etac leE 1); | |
| 224 | (*equality case*) | |
| 225 | by (asm_full_simp_tac (simpset() addsimps [diff_self_eq_0]) 2); | |
| 226 | by (asm_simp_tac (simpset() addsimps [mod_geq, div_termination RS ltD, | |
| 227 | diff_succ]) 1); | |
| 228 | val lemma = result(); | |
| 229 | ||
| 230 | Goal "n:nat ==> \ | |
| 231 | \ succ(m) mod n = (if succ(m mod n) = n then 0 else succ(m mod n))"; | |
| 232 | by (case_tac "n=0" 1); | |
| 233 | by (asm_simp_tac (simpset() addsimps [natify_succ, DIVISION_BY_ZERO_MOD]) 1); | |
| 234 | by (subgoal_tac | |
| 235 | "natify(succ(m)) mod n = \ | |
| 236 | \ (if succ(natify(m) mod n) = n then 0 else succ(natify(m) mod n))" 1); | |
| 237 | by (stac natify_succ 2); | |
| 238 | by (rtac lemma 2); | |
| 239 | by (auto_tac(claset(), | |
| 240 | simpset() delsimps [natify_succ] | |
| 241 | addsimps [nat_into_Ord RS Ord_0_lt_iff])); | |
| 242 | qed "mod_succ"; | |
| 243 | ||
| 244 | Goal "[| 0<n; n:nat |] ==> m mod n < n"; | |
| 245 | by (subgoal_tac "natify(m) mod n < n" 1); | |
| 246 | by (res_inst_tac [("i","natify(m)")] complete_induct 2);
 | |
| 247 | by (case_tac "x<n" 3); | |
| 248 | (*case x<n*) | |
| 249 | by (Asm_simp_tac 3); | |
| 250 | (*case n le x*) | |
| 251 | by (asm_full_simp_tac | |
| 252 | (simpset() addsimps [mod_geq, not_lt_iff_le, div_termination RS ltD]) 3); | |
| 253 | by Auto_tac; | |
| 254 | qed "mod_less_divisor"; | |
| 255 | ||
| 256 | Goal "b<2 ==> k mod 2 = b | k mod 2 = (if b=1 then 0 else 1)"; | |
| 257 | by (subgoal_tac "k mod 2: 2" 1); | |
| 258 | by (asm_simp_tac (simpset() addsimps [mod_less_divisor RS ltD]) 2); | |
| 259 | by (dtac ltD 1); | |
| 260 | by Auto_tac; | |
| 261 | qed "mod2_cases"; | |
| 262 | ||
| 263 | Goal "succ(succ(m)) mod 2 = m mod 2"; | |
| 264 | by (subgoal_tac "m mod 2: 2" 1); | |
| 265 | by (asm_simp_tac (simpset() addsimps [mod_less_divisor RS ltD]) 2); | |
| 266 | by (auto_tac (claset(), simpset() addsimps [mod_succ])); | |
| 267 | qed "mod2_succ_succ"; | |
| 268 | ||
| 269 | Addsimps [mod2_succ_succ]; | |
| 270 | ||
| 271 | Goal "(m#+m#+n) mod 2 = n mod 2"; | |
| 272 | by (subgoal_tac "(natify(m)#+natify(m)#+n) mod 2 = n mod 2" 1); | |
| 273 | by (res_inst_tac [("n","natify(m)")] nat_induct 2);
 | |
| 274 | by Auto_tac; | |
| 275 | qed "mod2_add_more"; | |
| 276 | ||
| 277 | Goal "(m#+m) mod 2 = 0"; | |
| 278 | by (cut_inst_tac [("n","0")] mod2_add_more 1);
 | |
| 279 | by Auto_tac; | |
| 280 | qed "mod2_add_self"; | |
| 281 | ||
| 282 | Addsimps [mod2_add_more, mod2_add_self]; | |
| 283 | ||
| 284 | ||
| 285 | (**** Additional theorems about "le" ****) | |
| 286 | ||
| 287 | Goal "m:nat ==> m le (m #+ n)"; | |
| 9873 | 288 | by (Asm_simp_tac 1); | 
| 9548 | 289 | qed "add_le_self"; | 
| 290 | ||
| 291 | Goal "m:nat ==> m le (n #+ m)"; | |
| 9873 | 292 | by (Asm_simp_tac 1); | 
| 9548 | 293 | qed "add_le_self2"; | 
| 294 | ||
| 295 | (*** Monotonicity of Multiplication ***) | |
| 296 | ||
| 297 | Goal "[| i le j; j:nat |] ==> (i#*k) le (j#*k)"; | |
| 298 | by (subgoal_tac "natify(i)#*natify(k) le j#*natify(k)" 1); | |
| 299 | by (ftac lt_nat_in_nat 2); | |
| 300 | by (res_inst_tac [("n","natify(k)")] nat_induct 3);
 | |
| 301 | by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [add_le_mono]))); | |
| 302 | qed "mult_le_mono1"; | |
| 303 | ||
| 304 | (* le monotonicity, BOTH arguments*) | |
| 305 | Goal "[| i le j; k le l; j:nat; l:nat |] ==> i#*k le j#*l"; | |
| 306 | by (rtac (mult_le_mono1 RS le_trans) 1); | |
| 307 | by (REPEAT (assume_tac 1)); | |
| 308 | by (EVERY [stac mult_commute 1, | |
| 309 | stac mult_commute 1, | |
| 310 | rtac mult_le_mono1 1]); | |
| 311 | by (REPEAT (assume_tac 1)); | |
| 312 | qed "mult_le_mono"; | |
| 313 | ||
| 314 | (*strict, in 1st argument; proof is by induction on k>0. | |
| 315 | I can't see how to relax the typing conditions.*) | |
| 316 | Goal "[| i<j; 0<k; j:nat; k:nat |] ==> k#*i < k#*j"; | |
| 317 | by (etac zero_lt_natE 1); | |
| 318 | by (ftac lt_nat_in_nat 2); | |
| 319 | by (ALLGOALS Asm_simp_tac); | |
| 320 | by (induct_tac "x" 1); | |
| 321 | by (ALLGOALS (asm_simp_tac (simpset() addsimps [add_lt_mono]))); | |
| 322 | qed "mult_lt_mono2"; | |
| 323 | ||
| 324 | Goal "[| i<j; 0<k; j:nat; k:nat |] ==> i#*k < j#*k"; | |
| 325 | by (asm_simp_tac (simpset() addsimps [mult_lt_mono2, | |
| 326 | inst "n" "k" mult_commute]) 1); | |
| 327 | qed "mult_lt_mono1"; | |
| 328 | ||
| 329 | Goal "m#+n = 0 <-> natify(m)=0 & natify(n)=0"; | |
| 330 | by (subgoal_tac "natify(m) #+ natify(n) = 0 <-> natify(m)=0 & natify(n)=0" 1); | |
| 331 | by (res_inst_tac [("n","natify(m)")] natE 2);
 | |
| 332 |  by (res_inst_tac [("n","natify(n)")] natE 4);
 | |
| 333 | by Auto_tac; | |
| 334 | qed "add_eq_0_iff"; | |
| 335 | AddIffs [add_eq_0_iff]; | |
| 336 | ||
| 337 | Goal "0 < m#*n <-> 0 < natify(m) & 0 < natify(n)"; | |
| 338 | by (subgoal_tac "0 < natify(m)#*natify(n) <-> \ | |
| 339 | \ 0 < natify(m) & 0 < natify(n)" 1); | |
| 340 | by (res_inst_tac [("n","natify(m)")] natE 2);
 | |
| 341 |  by (res_inst_tac [("n","natify(n)")] natE 4);
 | |
| 342 |   by (res_inst_tac [("n","natify(n)")] natE 3);
 | |
| 343 | by Auto_tac; | |
| 344 | qed "zero_lt_mult_iff"; | |
| 345 | ||
| 346 | Goal "m#*n = 1 <-> natify(m)=1 & natify(n)=1"; | |
| 347 | by (subgoal_tac "natify(m) #* natify(n) = 1 <-> natify(m)=1 & natify(n)=1" 1); | |
| 348 | by (res_inst_tac [("n","natify(m)")] natE 2);
 | |
| 349 |  by (res_inst_tac [("n","natify(n)")] natE 4);
 | |
| 350 | by Auto_tac; | |
| 351 | qed "mult_eq_1_iff"; | |
| 352 | AddIffs [zero_lt_mult_iff, mult_eq_1_iff]; | |
| 353 | ||
| 9648 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 354 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 355 | (** Cancellation laws for common factors in comparisons **) | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 356 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 357 | Goal "[| k: nat; m: nat; n: nat |] ==> (m#*k < n#*k) <-> (0<k & m<n)"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 358 | by (safe_tac (claset() addSIs [mult_lt_mono1])); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 359 | by (etac natE 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 360 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 361 | by (rtac (not_le_iff_lt RS iffD1) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 362 | by (dtac (not_le_iff_lt RSN (2,rev_iffD2)) 3); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 363 | by (blast_tac (claset() addIs [mult_le_mono1]) 5); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 364 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 365 | val lemma = result(); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 366 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 367 | Goal "(m#*k < n#*k) <-> (0 < natify(k) & natify(m) < natify(n))"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 368 | by (rtac iff_trans 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 369 | by (rtac lemma 2); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 370 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 371 | qed "mult_less_cancel2"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 372 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 373 | Goal "(k#*m < k#*n) <-> (0 < natify(k) & natify(m) < natify(n))"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 374 | by (simp_tac (simpset() addsimps [mult_less_cancel2, | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 375 | inst "m" "k" mult_commute]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 376 | qed "mult_less_cancel1"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 377 | Addsimps [mult_less_cancel1, mult_less_cancel2]; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 378 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 379 | Goal "(m#*k le n#*k) <-> (0 < natify(k) --> natify(m) le natify(n))"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 380 | by (asm_simp_tac (simpset() addsimps [not_lt_iff_le RS iff_sym]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 381 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 382 | qed "mult_le_cancel2"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 383 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 384 | Goal "(k#*m le k#*n) <-> (0 < natify(k) --> natify(m) le natify(n))"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 385 | by (asm_simp_tac (simpset() addsimps [not_lt_iff_le RS iff_sym]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 386 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 387 | qed "mult_le_cancel1"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 388 | Addsimps [mult_le_cancel1, mult_le_cancel2]; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 389 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 390 | Goal "[| Ord(m); Ord(n) |] ==> m=n <-> (m le n & n le m)"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 391 | by (blast_tac (claset() addIs [le_anti_sym]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 392 | qed "Ord_eq_iff_le"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 393 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 394 | Goal "[| k: nat; m: nat; n: nat |] ==> (m#*k = n#*k) <-> (m=n | k=0)"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 395 | by (asm_simp_tac (simpset() addsimps [inst "m" "m#*k" Ord_eq_iff_le, | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 396 | inst "m" "m" Ord_eq_iff_le]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 397 | by (auto_tac (claset(), simpset() addsimps [Ord_0_lt_iff])); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 398 | val lemma = result(); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 399 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 400 | Goal "(m#*k = n#*k) <-> (natify(m) = natify(n) | natify(k) = 0)"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 401 | by (rtac iff_trans 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 402 | by (rtac lemma 2); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 403 | by Auto_tac; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 404 | qed "mult_cancel2"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 405 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 406 | Goal "(k#*m = k#*n) <-> (natify(m) = natify(n) | natify(k) = 0)"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 407 | by (simp_tac (simpset() addsimps [mult_cancel2, inst "m" "k" mult_commute]) 1); | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 408 | qed "mult_cancel1"; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 409 | Addsimps [mult_cancel1, mult_cancel2]; | 
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 410 | |
| 
35d761c7d934
better rules for cancellation of common factors across comparisons
 paulson parents: 
9548diff
changeset | 411 | |
| 9548 | 412 | (*Cancellation law for division*) | 
| 413 | Goal "[| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> (k#*m) div (k#*n) = m div n"; | |
| 414 | by (eres_inst_tac [("i","m")] complete_induct 1);
 | |
| 415 | by (excluded_middle_tac "x<n" 1); | |
| 416 | by (asm_simp_tac (simpset() addsimps [div_less, zero_lt_mult_iff, | |
| 417 | mult_lt_mono2]) 2); | |
| 418 | by (asm_full_simp_tac | |
| 419 | (simpset() addsimps [not_lt_iff_le, | |
| 420 | zero_lt_mult_iff, le_refl RS mult_le_mono, div_geq, | |
| 421 | diff_mult_distrib2 RS sym, | |
| 422 | div_termination RS ltD]) 1); | |
| 423 | qed "div_cancel"; | |
| 424 | ||
| 425 | Goal "[| 0<n; 0<k; k:nat; m:nat; n:nat |] ==> \ | |
| 426 | \ (k#*m) mod (k#*n) = k #* (m mod n)"; | |
| 427 | by (eres_inst_tac [("i","m")] complete_induct 1);
 | |
| 428 | by (excluded_middle_tac "x<n" 1); | |
| 429 | by (asm_simp_tac (simpset() addsimps [mod_less, zero_lt_mult_iff, | |
| 430 | mult_lt_mono2]) 2); | |
| 431 | by (asm_full_simp_tac | |
| 432 | (simpset() addsimps [not_lt_iff_le, | |
| 433 | zero_lt_mult_iff, le_refl RS mult_le_mono, mod_geq, | |
| 434 | diff_mult_distrib2 RS sym, | |
| 435 | div_termination RS ltD]) 1); | |
| 436 | qed "mult_mod_distrib"; | |
| 437 | ||
| 438 | (*Lemma for gcd*) | |
| 439 | Goal "m = m#*n ==> natify(n)=1 | m=0"; | |
| 440 | by (subgoal_tac "m: nat" 1); | |
| 441 | by (etac ssubst 2); | |
| 442 | by (rtac disjCI 1); | |
| 443 | by (dtac sym 1); | |
| 444 | by (rtac Ord_linear_lt 1 THEN REPEAT_SOME (ares_tac [nat_into_Ord,nat_1I])); | |
| 445 | by (dtac (nat_into_Ord RS Ord_0_lt RSN (2,mult_lt_mono2)) 3); | |
| 446 | by Auto_tac; | |
| 447 | by (subgoal_tac "m #* n = 0" 1); | |
| 448 | by (stac (mult_natify2 RS sym) 2); | |
| 449 | by (auto_tac (claset(), simpset() delsimps [mult_natify2])); | |
| 450 | qed "mult_eq_self_implies_10"; | |
| 451 | ||
| 452 | Goal "[| m<n; n: nat |] ==> EX k: nat. n = succ(m#+k)"; | |
| 453 | by (ftac lt_nat_in_nat 1 THEN assume_tac 1); | |
| 454 | by (etac rev_mp 1); | |
| 455 | by (induct_tac "n" 1); | |
| 456 | by (ALLGOALS (simp_tac (simpset() addsimps [le_iff]))); | |
| 457 | by (blast_tac (claset() addSEs [leE] | |
| 458 | addSIs [add_0_right RS sym, add_succ_right RS sym]) 1); | |
| 459 | qed_spec_mp "less_imp_succ_add"; | |
| 460 | ||
| 9883 | 461 | Goal "[| m: nat; n: nat |] ==> (m<n) <-> (EX k: nat. n = succ(m#+k))"; | 
| 462 | by (auto_tac (claset() addIs [less_imp_succ_add], simpset())); | |
| 463 | qed "less_iff_succ_add"; |