src/HOL/Hoare/Arith2.ML
changeset 1465 5d7a7e439cec
parent 1335 5e1c0540f285
child 1476 608483c2122a
equal deleted inserted replaced
1464:a608f83e3421 1465:5d7a7e439cec
     1 (*  Title: 	HOL/Hoare/Arith2.ML
     1 (*  Title:      HOL/Hoare/Arith2.ML
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Norbert Galm
     3     Author:     Norbert Galm
     4     Copyright   1995 TUM
     4     Copyright   1995 TUM
     5 
     5 
     6 More arithmetic lemmas.
     6 More arithmetic lemmas.
     7 *)
     7 *)
     8 
     8 
    28 \       !!x z. [| P x 0 z |] ==> P (Suc x) 0 (Suc z);  \
    28 \       !!x z. [| P x 0 z |] ==> P (Suc x) 0 (Suc z);  \
    29 \       !!y z. [| P 0 y z |] ==> P 0 (Suc y) (Suc z);  \
    29 \       !!y z. [| P 0 y z |] ==> P 0 (Suc y) (Suc z);  \
    30 \       !!x y z. [| P x y z |] ==> P (Suc x) (Suc y) (Suc z)  \
    30 \       !!x y z. [| P x y z |] ==> P (Suc x) (Suc y) (Suc z)  \
    31 \    |] ==> P m n k";
    31 \    |] ==> P m n k";
    32 by (res_inst_tac [("x","m")] spec 1);
    32 by (res_inst_tac [("x","m")] spec 1);
    33 br diff_induct 1;
    33 by (rtac diff_induct 1);
    34 br allI 1;
    34 by (rtac allI 1);
    35 br allI 2;
    35 by (rtac allI 2);
    36 by (res_inst_tac [("m","xa"),("n","x")] diff_induct 1);
    36 by (res_inst_tac [("m","xa"),("n","x")] diff_induct 1);
    37 by (res_inst_tac [("m","x"),("n","Suc y")] diff_induct 4);
    37 by (res_inst_tac [("m","x"),("n","Suc y")] diff_induct 4);
    38 br allI 7;
    38 by (rtac allI 7);
    39 by (nat_ind_tac "xa" 7);
    39 by (nat_ind_tac "xa" 7);
    40 by (ALLGOALS (resolve_tac prems));
    40 by (ALLGOALS (resolve_tac prems));
    41 ba 1;
    41 by (assume_tac 1);
    42 ba 1;
    42 by (assume_tac 1);
    43 by (fast_tac HOL_cs 1);
    43 by (fast_tac HOL_cs 1);
    44 by (fast_tac HOL_cs 1);
    44 by (fast_tac HOL_cs 1);
    45 qed "diff_induct3";
    45 qed "diff_induct3";
    46 
    46 
    47 (*** interaction of + and - ***)
    47 (*** interaction of + and - ***)
    48 
    48 
    49 val prems=goal Arith.thy "~m<n+k ==> (m - n) - k = m - ((n + k)::nat)";
    49 val prems=goal Arith.thy "~m<n+k ==> (m - n) - k = m - ((n + k)::nat)";
    50 by (cut_facts_tac prems 1);
    50 by (cut_facts_tac prems 1);
    51 br mp 1;
    51 by (rtac mp 1);
    52 ba 2;
    52 by (assume_tac 2);
    53 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
    53 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
    54 by (ALLGOALS Asm_simp_tac);
    54 by (ALLGOALS Asm_simp_tac);
    55 qed "diff_not_assoc";
    55 qed "diff_not_assoc";
    56 
    56 
    57 val prems=goal Arith.thy "[|~m<n; ~n<k|] ==> (m - n) + k = m - ((n - k)::nat)";
    57 val prems=goal Arith.thy "[|~m<n; ~n<k|] ==> (m - n) + k = m - ((n - k)::nat)";
    58 by (cut_facts_tac prems 1);
    58 by (cut_facts_tac prems 1);
    59 bd conjI 1;
    59 by (dtac conjI 1);
    60 ba 1;
    60 by (assume_tac 1);
    61 by (res_inst_tac [("P","~m<n & ~n<k")] mp 1);
    61 by (res_inst_tac [("P","~m<n & ~n<k")] mp 1);
    62 ba 2;
    62 by (assume_tac 2);
    63 by (res_inst_tac [("m","m"),("n","n"),("k","k")] diff_induct3 1);
    63 by (res_inst_tac [("m","m"),("n","n"),("k","k")] diff_induct3 1);
    64 by (ALLGOALS Asm_simp_tac);
    64 by (ALLGOALS Asm_simp_tac);
    65 br impI 1;
    65 by (rtac impI 1);
    66 by (dres_inst_tac [("P","~x<y")] conjE 1);
    66 by (dres_inst_tac [("P","~x<y")] conjE 1);
    67 ba 2;
    67 by (assume_tac 2);
    68 br (Suc_diff_n RS sym) 1;
    68 by (rtac (Suc_diff_n RS sym) 1);
    69 br le_less_trans 1;
    69 by (rtac le_less_trans 1);
    70 be (not_less_eq RS subst) 2;
    70 by (etac (not_less_eq RS subst) 2);
    71 br (hd ([diff_less_Suc RS lessD] RL [Suc_le_mono RS subst])) 1;
    71 by (rtac (hd ([diff_less_Suc RS lessD] RL [Suc_le_mono RS subst])) 1);
    72 qed "diff_add_not_assoc";
    72 qed "diff_add_not_assoc";
    73 
    73 
    74 val prems=goal Arith.thy "~n<k ==> (m + n) - k = m + ((n - k)::nat)";
    74 val prems=goal Arith.thy "~n<k ==> (m + n) - k = m + ((n - k)::nat)";
    75 by (cut_facts_tac prems 1);
    75 by (cut_facts_tac prems 1);
    76 br mp 1;
    76 by (rtac mp 1);
    77 ba 2;
    77 by (assume_tac 2);
    78 by (res_inst_tac [("m","n"),("n","k")] diff_induct 1);
    78 by (res_inst_tac [("m","n"),("n","k")] diff_induct 1);
    79 by (ALLGOALS Asm_simp_tac);
    79 by (ALLGOALS Asm_simp_tac);
    80 qed "add_diff_assoc";
    80 qed "add_diff_assoc";
    81 
    81 
    82 (*** more ***)
    82 (*** more ***)
    83 
    83 
    84 val prems = goal Arith.thy "m~=(n::nat) = (m<n | n<m)";
    84 val prems = goal Arith.thy "m~=(n::nat) = (m<n | n<m)";
    85 br iffI 1;
    85 by (rtac iffI 1);
    86 by (cut_inst_tac [("m","m"),("n","n")] less_linear 1);
    86 by (cut_inst_tac [("m","m"),("n","n")] less_linear 1);
    87 by (Asm_full_simp_tac 1);
    87 by (Asm_full_simp_tac 1);
    88 be disjE 1;
    88 by (etac disjE 1);
    89 be (less_not_refl2 RS not_sym) 1;
    89 by (etac (less_not_refl2 RS not_sym) 1);
    90 be less_not_refl2 1;
    90 by (etac less_not_refl2 1);
    91 qed "not_eq_eq_less_or_gr";
    91 qed "not_eq_eq_less_or_gr";
    92 
    92 
    93 val [prem] = goal Arith.thy "m<n ==> n-m~=0";
    93 val [prem] = goal Arith.thy "m<n ==> n-m~=0";
    94 by (rtac (prem RS rev_mp) 1);
    94 by (rtac (prem RS rev_mp) 1);
    95 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
    95 by (res_inst_tac [("m","m"),("n","n")] diff_induct 1);
   113 val prems = goal Arith.thy "[|0<k; m<(n::nat)|] ==> m*k<n*k";
   113 val prems = goal Arith.thy "[|0<k; m<(n::nat)|] ==> m*k<n*k";
   114 by (cut_facts_tac prems 1);
   114 by (cut_facts_tac prems 1);
   115 by (res_inst_tac [("n","k")] natE 1);
   115 by (res_inst_tac [("n","k")] natE 1);
   116 by (ALLGOALS Asm_full_simp_tac);
   116 by (ALLGOALS Asm_full_simp_tac);
   117 by (nat_ind_tac "x" 1);
   117 by (nat_ind_tac "x" 1);
   118 be add_less_mono 2;
   118 by (etac add_less_mono 2);
   119 by (ALLGOALS Asm_full_simp_tac);
   119 by (ALLGOALS Asm_full_simp_tac);
   120 qed "mult_less_mono_r";
   120 qed "mult_less_mono_r";
   121 
   121 
   122 val prems = goal Arith.thy "~m<(n::nat) ==> ~m*k<n*k";
   122 val prems = goal Arith.thy "~m<(n::nat) ==> ~m*k<n*k";
   123 by (cut_facts_tac prems 1);
   123 by (cut_facts_tac prems 1);
   124 by (nat_ind_tac "k" 1);
   124 by (nat_ind_tac "k" 1);
   125 by (ALLGOALS Simp_tac);
   125 by (ALLGOALS Simp_tac);
   126 by (fold_goals_tac [le_def]);
   126 by (fold_goals_tac [le_def]);
   127 be add_le_mono 1;
   127 by (etac add_le_mono 1);
   128 ba 1;
   128 by (assume_tac 1);
   129 qed "mult_not_less_mono_r";
   129 qed "mult_not_less_mono_r";
   130 
   130 
   131 val prems = goal Arith.thy "m=(n::nat) ==> m*k=n*k";
   131 val prems = goal Arith.thy "m=(n::nat) ==> m*k=n*k";
   132 by (cut_facts_tac prems 1);
   132 by (cut_facts_tac prems 1);
   133 by (nat_ind_tac "k" 1);
   133 by (nat_ind_tac "k" 1);
   135 qed "mult_eq_mono_r";
   135 qed "mult_eq_mono_r";
   136 
   136 
   137 val prems = goal Arith.thy "[|0<k; m~=(n::nat)|] ==> m*k~=n*k";
   137 val prems = goal Arith.thy "[|0<k; m~=(n::nat)|] ==> m*k~=n*k";
   138 by (cut_facts_tac prems 1);
   138 by (cut_facts_tac prems 1);
   139 by (res_inst_tac [("P","m<n"),("Q","n<m")] disjE 1);
   139 by (res_inst_tac [("P","m<n"),("Q","n<m")] disjE 1);
   140 br (less_not_refl2 RS not_sym) 2;
   140 by (rtac (less_not_refl2 RS not_sym) 2);
   141 be mult_less_mono_r 2;
   141 by (etac mult_less_mono_r 2);
   142 br less_not_refl2 3;
   142 by (rtac less_not_refl2 3);
   143 be mult_less_mono_r 3;
   143 by (etac mult_less_mono_r 3);
   144 by (ALLGOALS (asm_full_simp_tac ((simpset_of "Arith") addsimps [not_eq_eq_less_or_gr])));
   144 by (ALLGOALS (asm_full_simp_tac ((simpset_of "Arith") addsimps [not_eq_eq_less_or_gr])));
   145 qed "mult_not_eq_mono_r";
   145 qed "mult_not_eq_mono_r";
   146 
   146 
   147 (******************************************************************)
   147 (******************************************************************)
   148 
   148 
   149 val prems = goal Arith.thy "(m - n)*k = (m*k) - ((n*k)::nat)";
   149 val prems = goal Arith.thy "(m - n)*k = (m*k) - ((n*k)::nat)";
   150 by (res_inst_tac [("P","m*k<n*k")] case_split_thm 1);
   150 by (res_inst_tac [("P","m*k<n*k")] case_split_thm 1);
   151 by (forward_tac [mult_not_less_mono_r COMP not_imp_swap] 1);
   151 by (forward_tac [mult_not_less_mono_r COMP not_imp_swap] 1);
   152 bd (less_not_sym RS (not_less_eq RS iffD1) RS less_imp_diff_is_0) 1;
   152 by (dtac (less_not_sym RS (not_less_eq RS iffD1) RS less_imp_diff_is_0) 1);
   153 bd (less_not_sym RS (not_less_eq RS iffD1) RS less_imp_diff_is_0) 1;
   153 by (dtac (less_not_sym RS (not_less_eq RS iffD1) RS less_imp_diff_is_0) 1);
   154 br mp 2;
   154 by (rtac mp 2);
   155 ba 3;
   155 by (assume_tac 3);
   156 by (res_inst_tac [("m","m"),("n","n")] diff_induct 2);
   156 by (res_inst_tac [("m","m"),("n","n")] diff_induct 2);
   157 by (ALLGOALS Asm_simp_tac);
   157 by (ALLGOALS Asm_simp_tac);
   158 br impI 1;
   158 by (rtac impI 1);
   159 bd (refl RS iffD1) 1;
   159 by (dtac (refl RS iffD1) 1);
   160 by (dres_inst_tac [("k","k")] add_not_less_mono_l 1);
   160 by (dres_inst_tac [("k","k")] add_not_less_mono_l 1);
   161 bd (refl RS iffD1) 1;
   161 by (dtac (refl RS iffD1) 1);
   162 bd (refl RS iffD1) 1;
   162 by (dtac (refl RS iffD1) 1);
   163 bd diff_not_assoc 1;
   163 by (dtac diff_not_assoc 1);
   164 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [diff_add_inverse]) 1);
   164 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [diff_add_inverse]) 1);
   165 qed "diff_mult_distrib_r";
   165 qed "diff_mult_distrib_r";
   166 
   166 
   167 
   167 
   168 (*** mod ***)
   168 (*** mod ***)
   176 by (fast_tac HOL_cs 1);
   176 by (fast_tac HOL_cs 1);
   177 *)
   177 *)
   178 
   178 
   179 val prems=goal thy "0<n ==> n mod n = 0";
   179 val prems=goal thy "0<n ==> n mod n = 0";
   180 by (cut_facts_tac prems 1);
   180 by (cut_facts_tac prems 1);
   181 br (mod_def RS wf_less_trans) 1;
   181 by (rtac (mod_def RS wf_less_trans) 1);
   182 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [diff_self_eq_0,cut_def,less_eq]) 1);
   182 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [diff_self_eq_0,cut_def,less_eq]) 1);
   183 be mod_less 1;
   183 by (etac mod_less 1);
   184 qed "mod_nn_is_0";
   184 qed "mod_nn_is_0";
   185 
   185 
   186 val prems=goal thy "0<n ==> m mod n = (m+n) mod n";
   186 val prems=goal thy "0<n ==> m mod n = (m+n) mod n";
   187 by (cut_facts_tac prems 1);
   187 by (cut_facts_tac prems 1);
   188 by (res_inst_tac [("s","n+m"),("t","m+n")] subst 1);
   188 by (res_inst_tac [("s","n+m"),("t","m+n")] subst 1);
   189 br add_commute 1;
   189 by (rtac add_commute 1);
   190 by (res_inst_tac [("s","n+m-n"),("P","%x.x mod n = (n + m) mod n")] subst 1);
   190 by (res_inst_tac [("s","n+m-n"),("P","%x.x mod n = (n + m) mod n")] subst 1);
   191 br diff_add_inverse 1;
   191 by (rtac diff_add_inverse 1);
   192 br sym 1;
   192 by (rtac sym 1);
   193 be mod_geq 1;
   193 by (etac mod_geq 1);
   194 by (res_inst_tac [("s","n<=n+m"),("t","~n+m<n")] subst 1);
   194 by (res_inst_tac [("s","n<=n+m"),("t","~n+m<n")] subst 1);
   195 by (simp_tac ((simpset_of "Arith") addsimps [le_def]) 1);
   195 by (simp_tac ((simpset_of "Arith") addsimps [le_def]) 1);
   196 br le_add1 1;
   196 by (rtac le_add1 1);
   197 qed "mod_eq_add";
   197 qed "mod_eq_add";
   198 
   198 
   199 val prems=goal thy "0<n ==> m*n mod n = 0";
   199 val prems=goal thy "0<n ==> m*n mod n = 0";
   200 by (cut_facts_tac prems 1);
   200 by (cut_facts_tac prems 1);
   201 by (nat_ind_tac "m" 1);
   201 by (nat_ind_tac "m" 1);
   202 by (Simp_tac 1);
   202 by (Simp_tac 1);
   203 be mod_less 1;
   203 by (etac mod_less 1);
   204 by (dres_inst_tac [("n","n"),("m","m1*n")] mod_eq_add 1);
   204 by (dres_inst_tac [("n","n"),("m","m1*n")] mod_eq_add 1);
   205 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [add_commute]) 1);
   205 by (asm_full_simp_tac ((simpset_of "Arith") addsimps [add_commute]) 1);
   206 qed "mod_prod_nn_is_0";
   206 qed "mod_prod_nn_is_0";
   207 
   207 
   208 val prems=goal thy "[|0<x; m mod x = 0; n mod x = 0|] ==> (m+n) mod x = 0";
   208 val prems=goal thy "[|0<x; m mod x = 0; n mod x = 0|] ==> (m+n) mod x = 0";
   209 by (cut_facts_tac prems 1);
   209 by (cut_facts_tac prems 1);
   210 by (res_inst_tac [("s","m div x * x + m mod x"),("t","m")] subst 1);
   210 by (res_inst_tac [("s","m div x * x + m mod x"),("t","m")] subst 1);
   211 be mod_div_equality 1;
   211 by (etac mod_div_equality 1);
   212 by (res_inst_tac [("s","n div x * x + n mod x"),("t","n")] subst 1);
   212 by (res_inst_tac [("s","n div x * x + n mod x"),("t","n")] subst 1);
   213 be mod_div_equality 1;
   213 by (etac mod_div_equality 1);
   214 by (Asm_simp_tac 1);
   214 by (Asm_simp_tac 1);
   215 by (res_inst_tac [("s","(m div x + n div x) * x"),("t","m div x * x + n div x * x")] subst 1);
   215 by (res_inst_tac [("s","(m div x + n div x) * x"),("t","m div x * x + n div x * x")] subst 1);
   216 br add_mult_distrib 1;
   216 by (rtac add_mult_distrib 1);
   217 be mod_prod_nn_is_0 1;
   217 by (etac mod_prod_nn_is_0 1);
   218 qed "mod0_sum";
   218 qed "mod0_sum";
   219 
   219 
   220 val prems=goal thy "[|0<x; m mod x = 0; n mod x = 0; n<=m|] ==> (m-n) mod x = 0";
   220 val prems=goal thy "[|0<x; m mod x = 0; n mod x = 0; n<=m|] ==> (m-n) mod x = 0";
   221 by (cut_facts_tac prems 1);
   221 by (cut_facts_tac prems 1);
   222 by (res_inst_tac [("s","m div x * x + m mod x"),("t","m")] subst 1);
   222 by (res_inst_tac [("s","m div x * x + m mod x"),("t","m")] subst 1);
   223 be mod_div_equality 1;
   223 by (etac mod_div_equality 1);
   224 by (res_inst_tac [("s","n div x * x + n mod x"),("t","n")] subst 1);
   224 by (res_inst_tac [("s","n div x * x + n mod x"),("t","n")] subst 1);
   225 be mod_div_equality 1;
   225 by (etac mod_div_equality 1);
   226 by (Asm_simp_tac 1);
   226 by (Asm_simp_tac 1);
   227 by (res_inst_tac [("s","(m div x - n div x) * x"),("t","m div x * x - n div x * x")] subst 1);
   227 by (res_inst_tac [("s","(m div x - n div x) * x"),("t","m div x * x - n div x * x")] subst 1);
   228 br diff_mult_distrib_r 1;
   228 by (rtac diff_mult_distrib_r 1);
   229 be mod_prod_nn_is_0 1;
   229 by (etac mod_prod_nn_is_0 1);
   230 qed "mod0_diff";
   230 qed "mod0_diff";
   231 
   231 
   232 
   232 
   233 (*** div ***)
   233 (*** div ***)
   234 
   234 
   235 val prems = goal thy "0<n ==> m*n div n = m";
   235 val prems = goal thy "0<n ==> m*n div n = m";
   236 by (cut_facts_tac prems 1);
   236 by (cut_facts_tac prems 1);
   237 br (mult_not_eq_mono_r RS not_imp_swap) 1;
   237 by (rtac (mult_not_eq_mono_r RS not_imp_swap) 1);
   238 ba 1;
   238 by (assume_tac 1);
   239 ba 1;
   239 by (assume_tac 1);
   240 by (res_inst_tac [("P","%x.m*n div n * n = x")] (mod_div_equality RS subst) 1);
   240 by (res_inst_tac [("P","%x.m*n div n * n = x")] (mod_div_equality RS subst) 1);
   241 ba 1;
   241 by (assume_tac 1);
   242 by (dres_inst_tac [("m","m")] mod_prod_nn_is_0 1);
   242 by (dres_inst_tac [("m","m")] mod_prod_nn_is_0 1);
   243 by (Asm_simp_tac 1);
   243 by (Asm_simp_tac 1);
   244 qed "div_prod_nn_is_m";
   244 qed "div_prod_nn_is_m";
   245 
   245 
   246 
   246 
   252 by (Asm_simp_tac 1);
   252 by (Asm_simp_tac 1);
   253 qed "divides_nn";
   253 qed "divides_nn";
   254 
   254 
   255 val prems=goalw thy [divides_def] "x divides n ==> x<=n";
   255 val prems=goalw thy [divides_def] "x divides n ==> x<=n";
   256 by (cut_facts_tac prems 1);
   256 by (cut_facts_tac prems 1);
   257 br ((mod_less COMP rev_contrapos) RS (le_def RS meta_eq_to_obj_eq RS iffD2)) 1;
   257 by (rtac ((mod_less COMP rev_contrapos) RS (le_def RS meta_eq_to_obj_eq RS iffD2)) 1);
   258 by (Asm_simp_tac 1);
   258 by (Asm_simp_tac 1);
   259 br (less_not_refl2 RS not_sym) 1;
   259 by (rtac (less_not_refl2 RS not_sym) 1);
   260 by (Asm_simp_tac 1);
   260 by (Asm_simp_tac 1);
   261 qed "divides_le";
   261 qed "divides_le";
   262 
   262 
   263 val prems=goalw thy [divides_def] "[|x divides m; x divides n|] ==> x divides (m+n)";
   263 val prems=goalw thy [divides_def] "[|x divides m; x divides n|] ==> x divides (m+n)";
   264 by (cut_facts_tac prems 1);
   264 by (cut_facts_tac prems 1);
   265 by (REPEAT ((dtac conjE 1) THEN (atac 2)));
   265 by (REPEAT ((dtac conjE 1) THEN (atac 2)));
   266 br conjI 1;
   266 by (rtac conjI 1);
   267 by (dres_inst_tac [("m","0"),("n","m")] less_imp_add_less 1);
   267 by (dres_inst_tac [("m","0"),("n","m")] less_imp_add_less 1);
   268 ba 1;
   268 by (assume_tac 1);
   269 be conjI 1;
   269 by (etac conjI 1);
   270 br mod0_sum 1;
   270 by (rtac mod0_sum 1);
   271 by (ALLGOALS atac);
   271 by (ALLGOALS atac);
   272 qed "divides_sum";
   272 qed "divides_sum";
   273 
   273 
   274 val prems=goalw thy [divides_def] "[|x divides m; x divides n; n<m|] ==> x divides (m-n)";
   274 val prems=goalw thy [divides_def] "[|x divides m; x divides n; n<m|] ==> x divides (m-n)";
   275 by (cut_facts_tac prems 1);
   275 by (cut_facts_tac prems 1);
   276 by (REPEAT ((dtac conjE 1) THEN (atac 2)));
   276 by (REPEAT ((dtac conjE 1) THEN (atac 2)));
   277 br conjI 1;
   277 by (rtac conjI 1);
   278 be less_imp_diff_positive 1;
   278 by (etac less_imp_diff_positive 1);
   279 be conjI 1;
   279 by (etac conjI 1);
   280 br mod0_diff 1;
   280 by (rtac mod0_diff 1);
   281 by (ALLGOALS (asm_simp_tac ((simpset_of "Arith") addsimps [le_def])));
   281 by (ALLGOALS (asm_simp_tac ((simpset_of "Arith") addsimps [le_def])));
   282 be less_not_sym 1;
   282 by (etac less_not_sym 1);
   283 qed "divides_diff";
   283 qed "divides_diff";
   284 
   284 
   285 
   285 
   286 (*** cd ***)
   286 (*** cd ***)
   287 
   287 
   288 
   288 
   289 val prems=goalw thy [cd_def] "0<n ==> cd n n n";
   289 val prems=goalw thy [cd_def] "0<n ==> cd n n n";
   290 by (cut_facts_tac prems 1);
   290 by (cut_facts_tac prems 1);
   291 bd divides_nn 1;
   291 by (dtac divides_nn 1);
   292 by (Asm_simp_tac 1);
   292 by (Asm_simp_tac 1);
   293 qed "cd_nnn";
   293 qed "cd_nnn";
   294 
   294 
   295 val prems=goalw thy [cd_def] "cd x m n ==> x<=m & x<=n";
   295 val prems=goalw thy [cd_def] "cd x m n ==> x<=m & x<=n";
   296 by (cut_facts_tac prems 1);
   296 by (cut_facts_tac prems 1);
   297 bd conjE 1;
   297 by (dtac conjE 1);
   298 ba 2;
   298 by (assume_tac 2);
   299 bd divides_le 1;
   299 by (dtac divides_le 1);
   300 bd divides_le 1;
   300 by (dtac divides_le 1);
   301 by (Asm_simp_tac 1);
   301 by (Asm_simp_tac 1);
   302 qed "cd_le";
   302 qed "cd_le";
   303 
   303 
   304 val prems=goalw thy [cd_def] "cd x m n = cd x n m";
   304 val prems=goalw thy [cd_def] "cd x m n = cd x n m";
   305 by (fast_tac HOL_cs 1);
   305 by (fast_tac HOL_cs 1);
   306 qed "cd_swap";
   306 qed "cd_swap";
   307 
   307 
   308 val prems=goalw thy [cd_def] "n<m ==> cd x m n = cd x (m-n) n";
   308 val prems=goalw thy [cd_def] "n<m ==> cd x m n = cd x (m-n) n";
   309 by (cut_facts_tac prems 1);
   309 by (cut_facts_tac prems 1);
   310 br iffI 1;
   310 by (rtac iffI 1);
   311 bd conjE 1;
   311 by (dtac conjE 1);
   312 ba 2;
   312 by (assume_tac 2);
   313 br conjI 1;
   313 by (rtac conjI 1);
   314 br divides_diff 1;
   314 by (rtac divides_diff 1);
   315 bd conjE 5;
   315 by (dtac conjE 5);
   316 ba 6;
   316 by (assume_tac 6);
   317 br conjI 5;
   317 by (rtac conjI 5);
   318 bd less_not_sym 5;
   318 by (dtac less_not_sym 5);
   319 bd add_diff_inverse 5;
   319 by (dtac add_diff_inverse 5);
   320 by (dres_inst_tac [("m","n"),("n","m-n")] divides_sum 5);
   320 by (dres_inst_tac [("m","n"),("n","m-n")] divides_sum 5);
   321 by (ALLGOALS Asm_full_simp_tac);
   321 by (ALLGOALS Asm_full_simp_tac);
   322 qed "cd_diff_l";
   322 qed "cd_diff_l";
   323 
   323 
   324 val prems=goalw thy [cd_def] "m<n ==> cd x m n = cd x m (n-m)";
   324 val prems=goalw thy [cd_def] "m<n ==> cd x m n = cd x m (n-m)";
   325 by (cut_facts_tac prems 1);
   325 by (cut_facts_tac prems 1);
   326 br iffI 1;
   326 by (rtac iffI 1);
   327 bd conjE 1;
   327 by (dtac conjE 1);
   328 ba 2;
   328 by (assume_tac 2);
   329 br conjI 1;
   329 by (rtac conjI 1);
   330 br divides_diff 2;
   330 by (rtac divides_diff 2);
   331 bd conjE 5;
   331 by (dtac conjE 5);
   332 ba 6;
   332 by (assume_tac 6);
   333 br conjI 5;
   333 by (rtac conjI 5);
   334 bd less_not_sym 6;
   334 by (dtac less_not_sym 6);
   335 bd add_diff_inverse 6;
   335 by (dtac add_diff_inverse 6);
   336 by (dres_inst_tac [("n","n-m")] divides_sum 6);
   336 by (dres_inst_tac [("n","n-m")] divides_sum 6);
   337 by (ALLGOALS Asm_full_simp_tac);
   337 by (ALLGOALS Asm_full_simp_tac);
   338 qed "cd_diff_r";
   338 qed "cd_diff_r";
   339 
   339 
   340 
   340 
   341 (*** gcd ***)
   341 (*** gcd ***)
   342 
   342 
   343 val prems = goalw thy [gcd_def] "0<n ==> n = gcd n n";
   343 val prems = goalw thy [gcd_def] "0<n ==> n = gcd n n";
   344 by (cut_facts_tac prems 1);
   344 by (cut_facts_tac prems 1);
   345 bd cd_nnn 1;
   345 by (dtac cd_nnn 1);
   346 br (select_equality RS sym) 1;
   346 by (rtac (select_equality RS sym) 1);
   347 be conjI 1;
   347 by (etac conjI 1);
   348 br allI 1;
   348 by (rtac allI 1);
   349 br impI 1;
   349 by (rtac impI 1);
   350 bd cd_le 1;
   350 by (dtac cd_le 1);
   351 bd conjE 2;
   351 by (dtac conjE 2);
   352 ba 3;
   352 by (assume_tac 3);
   353 br le_anti_sym 2;
   353 by (rtac le_anti_sym 2);
   354 by (dres_inst_tac [("x","x")] cd_le 2);
   354 by (dres_inst_tac [("x","x")] cd_le 2);
   355 by (dres_inst_tac [("x","n")] spec 3);
   355 by (dres_inst_tac [("x","n")] spec 3);
   356 by (ALLGOALS Asm_full_simp_tac);
   356 by (ALLGOALS Asm_full_simp_tac);
   357 qed "gcd_nnn";
   357 qed "gcd_nnn";
   358 
   358 
   362 
   362 
   363 val prems=goalw thy [gcd_def] "n<m ==> gcd m n = gcd (m-n) n";
   363 val prems=goalw thy [gcd_def] "n<m ==> gcd m n = gcd (m-n) n";
   364 by (cut_facts_tac prems 1);
   364 by (cut_facts_tac prems 1);
   365 by (subgoal_tac "n<m ==> !x.cd x m n = cd x (m-n) n" 1);
   365 by (subgoal_tac "n<m ==> !x.cd x m n = cd x (m-n) n" 1);
   366 by (Asm_simp_tac 1);
   366 by (Asm_simp_tac 1);
   367 br allI 1;
   367 by (rtac allI 1);
   368 be cd_diff_l 1;
   368 by (etac cd_diff_l 1);
   369 qed "gcd_diff_l";
   369 qed "gcd_diff_l";
   370 
   370 
   371 val prems=goalw thy [gcd_def] "m<n ==> gcd m n = gcd m (n-m)";
   371 val prems=goalw thy [gcd_def] "m<n ==> gcd m n = gcd m (n-m)";
   372 by (cut_facts_tac prems 1);
   372 by (cut_facts_tac prems 1);
   373 by (subgoal_tac "m<n ==> !x.cd x m n = cd x m (n-m)" 1);
   373 by (subgoal_tac "m<n ==> !x.cd x m n = cd x m (n-m)" 1);
   374 by (Asm_simp_tac 1);
   374 by (Asm_simp_tac 1);
   375 br allI 1;
   375 by (rtac allI 1);
   376 be cd_diff_r 1;
   376 by (etac cd_diff_r 1);
   377 qed "gcd_diff_r";
   377 qed "gcd_diff_r";
   378 
   378 
   379 
   379 
   380 (*** pow ***)
   380 (*** pow ***)
   381 
   381 
   390 
   390 
   391 goalw thy [pow_def] "m pow n pow k = m pow (n*k)";
   391 goalw thy [pow_def] "m pow n pow k = m pow (n*k)";
   392 by (nat_ind_tac "k" 1);
   392 by (nat_ind_tac "k" 1);
   393 by (ALLGOALS Asm_simp_tac);
   393 by (ALLGOALS Asm_simp_tac);
   394 by (fold_goals_tac [pow_def]);
   394 by (fold_goals_tac [pow_def]);
   395 br (pow_add_reduce RS sym) 1;
   395 by (rtac (pow_add_reduce RS sym) 1);
   396 qed "pow_pow_reduce";
   396 qed "pow_pow_reduce";
   397 
   397 
   398 (*** fac ***)
   398 (*** fac ***)
   399 
   399 
   400 Addsimps(nat_recs fac_def);
   400 Addsimps(nat_recs fac_def);