src/HOL/Divides.ML
changeset 8935 548901d05a0e
parent 8860 6bbb93189de6
child 9108 9fff97d29837
equal deleted inserted replaced
8934:39d0cc787d47 8935:548901d05a0e
    24 
    24 
    25 
    25 
    26 (** Aribtrary definitions for division by zero.  Useful to simplify 
    26 (** Aribtrary definitions for division by zero.  Useful to simplify 
    27     certain equations **)
    27     certain equations **)
    28 
    28 
    29 Goal "a div 0 = 0";
    29 Goal "a div 0 = (0::nat)";
    30 by (rtac (div_eq RS wf_less_trans) 1);
    30 by (rtac (div_eq RS wf_less_trans) 1);
    31 by (Asm_simp_tac 1);
    31 by (Asm_simp_tac 1);
    32 qed "DIVISION_BY_ZERO_DIV";  (*NOT for adding to default simpset*)
    32 qed "DIVISION_BY_ZERO_DIV";  (*NOT for adding to default simpset*)
    33 
    33 
    34 Goal "a mod 0 = a";
    34 Goal "a mod 0 = (a::nat)";
    35 by (rtac (mod_eq RS wf_less_trans) 1);
    35 by (rtac (mod_eq RS wf_less_trans) 1);
    36 by (Asm_simp_tac 1);
    36 by (Asm_simp_tac 1);
    37 qed "DIVISION_BY_ZERO_MOD";  (*NOT for adding to default simpset*)
    37 qed "DIVISION_BY_ZERO_MOD";  (*NOT for adding to default simpset*)
    38 
    38 
    39 fun div_undefined_case_tac s i =
    39 fun div_undefined_case_tac s i =
    63 
    63 
    64 Goal "m mod (n::nat) = (if m<n then m else (m-n) mod n)";
    64 Goal "m mod (n::nat) = (if m<n then m else (m-n) mod n)";
    65 by (asm_simp_tac (simpset() addsimps [mod_geq]) 1);
    65 by (asm_simp_tac (simpset() addsimps [mod_geq]) 1);
    66 qed "mod_if";
    66 qed "mod_if";
    67 
    67 
    68 Goal "m mod 1 = 0";
    68 Goal "m mod 1 = (0::nat)";
    69 by (induct_tac "m" 1);
    69 by (induct_tac "m" 1);
    70 by (ALLGOALS (asm_simp_tac (simpset() addsimps [mod_geq])));
    70 by (ALLGOALS (asm_simp_tac (simpset() addsimps [mod_geq])));
    71 qed "mod_1";
    71 qed "mod_1";
    72 Addsimps [mod_1];
    72 Addsimps [mod_1];
    73 
    73 
    74 Goal "n mod n = 0";
    74 Goal "n mod n = (0::nat)";
    75 by (div_undefined_case_tac "n=0" 1);
    75 by (div_undefined_case_tac "n=0" 1);
    76 by (asm_simp_tac (simpset() addsimps [mod_geq]) 1);
    76 by (asm_simp_tac (simpset() addsimps [mod_geq]) 1);
    77 qed "mod_self";
    77 qed "mod_self";
    78 
    78 
    79 Goal "(m+n) mod n = m mod (n::nat)";
    79 Goal "(m+n) mod n = m mod (n::nat)";
   115 by (asm_simp_tac 
   115 by (asm_simp_tac 
   116     (simpset() addsimps [read_instantiate [("m","k")] mult_commute, 
   116     (simpset() addsimps [read_instantiate [("m","k")] mult_commute, 
   117 			 mod_mult_distrib]) 1);
   117 			 mod_mult_distrib]) 1);
   118 qed "mod_mult_distrib2";
   118 qed "mod_mult_distrib2";
   119 
   119 
   120 Goal "(m*n) mod n = 0";
   120 Goal "(m*n) mod n = (0::nat)";
   121 by (div_undefined_case_tac "n=0" 1);
   121 by (div_undefined_case_tac "n=0" 1);
   122 by (induct_tac "m" 1);
   122 by (induct_tac "m" 1);
   123 by (Asm_simp_tac 1);
   123 by (Asm_simp_tac 1);
   124 by (rename_tac "k" 1);
   124 by (rename_tac "k" 1);
   125 by (cut_inst_tac [("m","k*n"),("n","n")] mod_add_self2 1);
   125 by (cut_inst_tac [("m","k*n"),("n","n")] mod_add_self2 1);
   126 by (asm_full_simp_tac (simpset() addsimps [add_commute]) 1);
   126 by (asm_full_simp_tac (simpset() addsimps [add_commute]) 1);
   127 qed "mod_mult_self_is_0";
   127 qed "mod_mult_self_is_0";
   128 
   128 
   129 Goal "(n*m) mod n = 0";
   129 Goal "(n*m) mod n = (0::nat)";
   130 by (simp_tac (simpset() addsimps [mult_commute, mod_mult_self_is_0]) 1);
   130 by (simp_tac (simpset() addsimps [mult_commute, mod_mult_self_is_0]) 1);
   131 qed "mod_mult_self1_is_0";
   131 qed "mod_mult_self1_is_0";
   132 Addsimps [mod_mult_self_is_0, mod_mult_self1_is_0];
   132 Addsimps [mod_mult_self_is_0, mod_mult_self1_is_0];
   133 
   133 
   134 
   134 
   135 (*** Quotient ***)
   135 (*** Quotient ***)
   136 
   136 
   137 Goal "m<n ==> m div n = 0";
   137 Goal "m<n ==> m div n = (0::nat)";
   138 by (rtac (div_eq RS wf_less_trans) 1);
   138 by (rtac (div_eq RS wf_less_trans) 1);
   139 by (Asm_simp_tac 1);
   139 by (Asm_simp_tac 1);
   140 qed "div_less";
   140 qed "div_less";
   141 Addsimps [div_less];
   141 Addsimps [div_less];
   142 
   142 
   176 by (induct_tac "m" 1);
   176 by (induct_tac "m" 1);
   177 by (ALLGOALS (asm_simp_tac (simpset() addsimps [div_geq])));
   177 by (ALLGOALS (asm_simp_tac (simpset() addsimps [div_geq])));
   178 qed "div_1";
   178 qed "div_1";
   179 Addsimps [div_1];
   179 Addsimps [div_1];
   180 
   180 
   181 Goal "0<n ==> n div n = 1";
   181 Goal "0<n ==> n div n = (1::nat)";
   182 by (asm_simp_tac (simpset() addsimps [div_geq]) 1);
   182 by (asm_simp_tac (simpset() addsimps [div_geq]) 1);
   183 qed "div_self";
   183 qed "div_self";
   184 
   184 
   185 
   185 
   186 Goal "0<n ==> (m+n) div n = Suc (m div n)";
   186 Goal "0<n ==> (m+n) div n = Suc (m div n)";
   191 
   191 
   192 Goal "0<n ==> (n+m) div n = Suc (m div n)";
   192 Goal "0<n ==> (n+m) div n = Suc (m div n)";
   193 by (asm_simp_tac (simpset() addsimps [add_commute, div_add_self2]) 1);
   193 by (asm_simp_tac (simpset() addsimps [add_commute, div_add_self2]) 1);
   194 qed "div_add_self1";
   194 qed "div_add_self1";
   195 
   195 
   196 Goal "!!n. 0<n ==> (m + k*n) div n = k + m div n";
   196 Goal "!!n::nat. 0<n ==> (m + k*n) div n = k + m div n";
   197 by (induct_tac "k" 1);
   197 by (induct_tac "k" 1);
   198 by (ALLGOALS (asm_simp_tac (simpset() addsimps add_ac @ [div_add_self1])));
   198 by (ALLGOALS (asm_simp_tac (simpset() addsimps add_ac @ [div_add_self1])));
   199 qed "div_mult_self1";
   199 qed "div_mult_self1";
   200 
   200 
   201 Goal "0<n ==> (m + n*k) div n = k + m div n";
   201 Goal "0<n ==> (m + n*k) div n = k + m div (n::nat)";
   202 by (asm_simp_tac (simpset() addsimps [mult_commute, div_mult_self1]) 1);
   202 by (asm_simp_tac (simpset() addsimps [mult_commute, div_mult_self1]) 1);
   203 qed "div_mult_self2";
   203 qed "div_mult_self2";
   204 
   204 
   205 Addsimps [div_mult_self1, div_mult_self2];
   205 Addsimps [div_mult_self1, div_mult_self2];
   206 
   206 
   207 (** A dividend of zero **)
   207 (** A dividend of zero **)
   208 
   208 
   209 Goal "0 div m = 0";
   209 Goal "0 div m = (0::nat)";
   210 by (div_undefined_case_tac "m=0" 1);
   210 by (div_undefined_case_tac "m=0" 1);
   211 by (Asm_simp_tac 1);
   211 by (Asm_simp_tac 1);
   212 qed "div_0"; 
   212 qed "div_0"; 
   213 
   213 
   214 Goal "0 mod m = 0";
   214 Goal "0 mod m = (0::nat)";
   215 by (div_undefined_case_tac "m=0" 1);
   215 by (div_undefined_case_tac "m=0" 1);
   216 by (Asm_simp_tac 1);
   216 by (Asm_simp_tac 1);
   217 qed "mod_0"; 
   217 qed "mod_0"; 
   218 Addsimps [div_0, mod_0];
   218 Addsimps [div_0, mod_0];
   219 
   219 
   232 (* 2.2  case m>=k *)
   232 (* 2.2  case m>=k *)
   233 by (asm_simp_tac (simpset() addsimps [div_geq, diff_less, diff_le_mono]) 1);
   233 by (asm_simp_tac (simpset() addsimps [div_geq, diff_less, diff_le_mono]) 1);
   234 qed_spec_mp "div_le_mono";
   234 qed_spec_mp "div_le_mono";
   235 
   235 
   236 (* Antimonotonicity of div in second argument *)
   236 (* Antimonotonicity of div in second argument *)
   237 Goal "[| 0<m; m<=n |] ==> (k div n) <= (k div m)";
   237 Goal "!!m::nat. [| 0<m; m<=n |] ==> (k div n) <= (k div m)";
   238 by (subgoal_tac "0<n" 1);
   238 by (subgoal_tac "0<n" 1);
   239  by (Asm_simp_tac 2);
   239  by (Asm_simp_tac 2);
   240 by (res_inst_tac [("n","k")] less_induct 1);
   240 by (res_inst_tac [("n","k")] less_induct 1);
   241 by (rename_tac "k" 1);
   241 by (rename_tac "k" 1);
   242 by (case_tac "k<n" 1);
   242 by (case_tac "k<n" 1);
   259 by (ALLGOALS Asm_simp_tac);
   259 by (ALLGOALS Asm_simp_tac);
   260 qed "div_le_dividend";
   260 qed "div_le_dividend";
   261 Addsimps [div_le_dividend];
   261 Addsimps [div_le_dividend];
   262 
   262 
   263 (* Similar for "less than" *)
   263 (* Similar for "less than" *)
   264 Goal "1<n ==> (0 < m) --> (m div n < m)";
   264 Goal "!!n::nat. 1<n ==> (0 < m) --> (m div n < m)";
   265 by (res_inst_tac [("n","m")] less_induct 1);
   265 by (res_inst_tac [("n","m")] less_induct 1);
   266 by (rename_tac "m" 1);
   266 by (rename_tac "m" 1);
   267 by (case_tac "m<n" 1);
   267 by (case_tac "m<n" 1);
   268  by (Asm_full_simp_tac 1);
   268  by (Asm_full_simp_tac 1);
   269 by (subgoal_tac "0<n" 1);
   269 by (subgoal_tac "0<n" 1);
   294 					   mod_geq]) 1);
   294 					   mod_geq]) 1);
   295 by (auto_tac (claset(), 
   295 by (auto_tac (claset(), 
   296 	      simpset() addsimps [Suc_diff_le, diff_less, le_mod_geq]));
   296 	      simpset() addsimps [Suc_diff_le, diff_less, le_mod_geq]));
   297 qed "mod_Suc";
   297 qed "mod_Suc";
   298 
   298 
   299 Goal "0<n ==> m mod n < n";
   299 Goal "0<n ==> m mod n < (n::nat)";
   300 by (res_inst_tac [("n","m")] less_induct 1);
   300 by (res_inst_tac [("n","m")] less_induct 1);
   301 by (case_tac "na<n" 1);
   301 by (case_tac "na<n" 1);
   302 (*case n le na*)
   302 (*case n le na*)
   303 by (asm_full_simp_tac (simpset() addsimps [mod_geq, diff_less]) 2);
   303 by (asm_full_simp_tac (simpset() addsimps [mod_geq, diff_less]) 2);
   304 (*case na<n*)
   304 (*case na<n*)
   306 qed "mod_less_divisor";
   306 qed "mod_less_divisor";
   307 Addsimps [mod_less_divisor];
   307 Addsimps [mod_less_divisor];
   308 
   308 
   309 (*** More division laws ***)
   309 (*** More division laws ***)
   310 
   310 
   311 Goal "0<n ==> (m*n) div n = m";
   311 Goal "0<n ==> (m*n) div n = (m::nat)";
   312 by (cut_inst_tac [("m", "m*n"),("n","n")] mod_div_equality 1);
   312 by (cut_inst_tac [("m", "m*n"),("n","n")] mod_div_equality 1);
   313 by (asm_full_simp_tac (simpset() addsimps [mod_mult_self_is_0]) 1);
   313 by (asm_full_simp_tac (simpset() addsimps [mod_mult_self_is_0]) 1);
   314 qed "div_mult_self_is_m";
   314 qed "div_mult_self_is_m";
   315 
   315 
   316 Goal "0<n ==> (n*m) div n = m";
   316 Goal "0<n ==> (n*m) div n = (m::nat)";
   317 by (asm_simp_tac (simpset() addsimps [mult_commute, div_mult_self_is_m]) 1);
   317 by (asm_simp_tac (simpset() addsimps [mult_commute, div_mult_self_is_m]) 1);
   318 qed "div_mult_self1_is_m";
   318 qed "div_mult_self1_is_m";
   319 Addsimps [div_mult_self_is_m, div_mult_self1_is_m];
   319 Addsimps [div_mult_self_is_m, div_mult_self1_is_m];
   320 
   320 
   321 (*Cancellation law for division*)
   321 (*Cancellation law for division*)
   322 Goal "0<k ==> (k*m) div (k*n) = m div n";
   322 Goal "0<k ==> (k*m) div (k*n) = m div (n::nat)";
   323 by (div_undefined_case_tac "n=0" 1);
   323 by (div_undefined_case_tac "n=0" 1);
   324 by (res_inst_tac [("n","m")] less_induct 1);
   324 by (res_inst_tac [("n","m")] less_induct 1);
   325 by (case_tac "na<n" 1);
   325 by (case_tac "na<n" 1);
   326 by (asm_simp_tac (simpset() addsimps [zero_less_mult_iff, mult_less_mono2]) 1);
   326 by (asm_simp_tac (simpset() addsimps [zero_less_mult_iff, mult_less_mono2]) 1);
   327 by (subgoal_tac "~ k*na < k*n" 1);
   327 by (subgoal_tac "~ k*na < k*n" 1);
   338 
   338 
   339 (************************************************)
   339 (************************************************)
   340 (** Divides Relation                           **)
   340 (** Divides Relation                           **)
   341 (************************************************)
   341 (************************************************)
   342 
   342 
   343 Goalw [dvd_def] "m dvd 0";
   343 Goalw [dvd_def] "m dvd (0::nat)";
   344 by (blast_tac (claset() addIs [mult_0_right RS sym]) 1);
   344 by (blast_tac (claset() addIs [mult_0_right RS sym]) 1);
   345 qed "dvd_0_right";
   345 qed "dvd_0_right";
   346 AddIffs [dvd_0_right];
   346 AddIffs [dvd_0_right];
   347 
   347 
   348 Goalw [dvd_def] "0 dvd m ==> m = 0";
   348 Goalw [dvd_def] "0 dvd m ==> m = (0::nat)";
   349 by Auto_tac;
   349 by Auto_tac;
   350 qed "dvd_0_left";
   350 qed "dvd_0_left";
   351 
   351 
   352 Goalw [dvd_def] "1 dvd k";
   352 Goalw [dvd_def] "1 dvd (k::nat)";
   353 by (Simp_tac 1);
   353 by (Simp_tac 1);
   354 qed "dvd_1_left";
   354 qed "dvd_1_left";
   355 AddIffs [dvd_1_left];
   355 AddIffs [dvd_1_left];
   356 
   356 
   357 Goalw [dvd_def] "m dvd (m::nat)";
   357 Goalw [dvd_def] "m dvd (m::nat)";
   402 by (etac ssubst 1);
   402 by (etac ssubst 1);
   403 by (etac dvd_diff 1);
   403 by (etac dvd_diff 1);
   404 by (rtac dvd_refl 1);
   404 by (rtac dvd_refl 1);
   405 qed "dvd_reduce";
   405 qed "dvd_reduce";
   406 
   406 
   407 Goalw [dvd_def] "[| f dvd m; f dvd n; 0<n |] ==> f dvd (m mod n)";
   407 Goalw [dvd_def] "!!n::nat. [| f dvd m; f dvd n; 0<n |] ==> f dvd (m mod n)";
   408 by (Clarify_tac 1);
   408 by (Clarify_tac 1);
   409 by (Full_simp_tac 1);
   409 by (Full_simp_tac 1);
   410 by (res_inst_tac 
   410 by (res_inst_tac 
   411     [("x", "(((k div ka)*ka + k mod ka) - ((f*k) div (f*ka)) * ka)")] 
   411     [("x", "(((k div ka)*ka + k mod ka) - ((f*k) div (f*ka)) * ka)")] 
   412     exI 1);
   412     exI 1);
   436 Goalw [dvd_def] "(i*j :: nat) dvd k ==> i dvd k";
   436 Goalw [dvd_def] "(i*j :: nat) dvd k ==> i dvd k";
   437 by (full_simp_tac (simpset() addsimps [mult_assoc]) 1);
   437 by (full_simp_tac (simpset() addsimps [mult_assoc]) 1);
   438 by (Blast_tac 1);
   438 by (Blast_tac 1);
   439 qed "dvd_mult_left";
   439 qed "dvd_mult_left";
   440 
   440 
   441 Goalw [dvd_def] "[| k dvd n; 0 < n |] ==> k <= n";
   441 Goalw [dvd_def] "[| k dvd n; 0 < n |] ==> k <= (n::nat)";
   442 by (Clarify_tac 1);
   442 by (Clarify_tac 1);
   443 by (ALLGOALS (full_simp_tac (simpset() addsimps [zero_less_mult_iff])));
   443 by (ALLGOALS (full_simp_tac (simpset() addsimps [zero_less_mult_iff])));
   444 by (etac conjE 1);
   444 by (etac conjE 1);
   445 by (rtac le_trans 1);
   445 by (rtac le_trans 1);
   446 by (rtac (le_refl RS mult_le_mono) 2);
   446 by (rtac (le_refl RS mult_le_mono) 2);
   447 by (etac Suc_leI 2);
   447 by (etac Suc_leI 2);
   448 by (Simp_tac 1);
   448 by (Simp_tac 1);
   449 qed "dvd_imp_le";
   449 qed "dvd_imp_le";
   450 
   450 
   451 Goalw [dvd_def] "(k dvd n) = (n mod k = 0)";
   451 Goalw [dvd_def] "!!k::nat. (k dvd n) = (n mod k = 0)";
   452 by (div_undefined_case_tac "k=0" 1);
   452 by (div_undefined_case_tac "k=0" 1);
   453 by Safe_tac;
   453 by Safe_tac;
   454 by (asm_simp_tac (simpset() addsimps [mult_commute]) 1);
   454 by (asm_simp_tac (simpset() addsimps [mult_commute]) 1);
   455 by (res_inst_tac [("t","n"),("n1","k")] (mod_div_equality RS subst) 1);
   455 by (res_inst_tac [("t","n"),("n1","k")] (mod_div_equality RS subst) 1);
   456 by (stac mult_commute 1);
   456 by (stac mult_commute 1);