src/HOL/Integ/Int.ML
author paulson
Wed, 02 Jan 2002 16:06:31 +0100
changeset 12613 279facb4253a
parent 11868 56db9f3a6b3e
permissions -rw-r--r--
Literal arithmetic: raising numbers to powers (nat, int, real, hypreal)
     1 (*  Title:      HOL/Integ/Int.ML
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1998  University of Cambridge
     5 
     6 Type "int" is a linear order
     7 
     8 And many further lemmas
     9 *)
    10 
    11 
    12 Goal "int 0 = (0::int)";
    13 by (simp_tac (simpset() addsimps [Zero_int_def]) 1);
    14 qed "int_0";
    15 
    16 Goal "int 1 = 1";
    17 by (simp_tac (simpset() addsimps [One_int_def]) 1); 
    18 qed "int_1";
    19 
    20 Goal "int (Suc 0) = 1";
    21 by (simp_tac (simpset() addsimps [One_int_def, One_nat_def]) 1); 
    22 qed "int_Suc0_eq_1";
    23 
    24 Goalw [zdiff_def,zless_def] "neg x = (x < 0)";
    25 by Auto_tac; 
    26 qed "neg_eq_less_0"; 
    27 
    28 Goalw [zle_def] "(~neg x) = (0 <= x)";
    29 by (simp_tac (simpset() addsimps [neg_eq_less_0]) 1); 
    30 qed "not_neg_eq_ge_0"; 
    31 
    32 (** Needed to simplify inequalities when Numeral1 can get simplified to 1 **)
    33 
    34 Goal "~ neg 0";
    35 by (simp_tac (simpset() addsimps [One_int_def, neg_eq_less_0]) 1);  
    36 qed "not_neg_0"; 
    37 
    38 Goal "~ neg 1";
    39 by (simp_tac (simpset() addsimps [One_int_def, neg_eq_less_0]) 1);  
    40 qed "not_neg_1"; 
    41 
    42 Goal "iszero 0";
    43 by (simp_tac (simpset() addsimps [iszero_def]) 1);
    44 qed "iszero_0"; 
    45 
    46 Goal "~ iszero 1";
    47 by (simp_tac (simpset() addsimps [Zero_int_def, One_int_def, One_nat_def, 
    48                                   iszero_def]) 1);
    49 qed "not_iszero_1"; 
    50 
    51 Goal "0 < (1::int)";
    52 by (simp_tac (simpset() addsimps [Zero_int_def, One_int_def, One_nat_def]) 1); 
    53 qed "int_0_less_1";
    54 
    55 Goal "0 \\<noteq> (1::int)";
    56 by (simp_tac (simpset() addsimps [Zero_int_def, One_int_def, One_nat_def]) 1); 
    57 qed "int_0_neq_1";
    58 
    59 Addsimps [int_0, int_1, int_0_neq_1];
    60 
    61 
    62 (*** Abel_Cancel simproc on the integers ***)
    63 
    64 (* Lemmas needed for the simprocs *)
    65 
    66 (*Deletion of other terms in the formula, seeking the -x at the front of z*)
    67 Goal "((x::int) + (y + z) = y + u) = ((x + z) = u)";
    68 by (stac zadd_left_commute 1);
    69 by (rtac zadd_left_cancel 1);
    70 qed "zadd_cancel_21";
    71 
    72 (*A further rule to deal with the case that
    73   everything gets cancelled on the right.*)
    74 Goal "((x::int) + (y + z) = y) = (x = -z)";
    75 by (stac zadd_left_commute 1);
    76 by (res_inst_tac [("t", "y")] (zadd_0_right RS subst) 1
    77     THEN stac zadd_left_cancel 1);
    78 by (simp_tac (simpset() addsimps [eq_zdiff_eq RS sym]) 1);
    79 qed "zadd_cancel_end";
    80 
    81 
    82 structure Int_Cancel_Data =
    83 struct
    84   val ss		= HOL_ss
    85   val eq_reflection	= eq_reflection
    86 
    87   val sg_ref 		= Sign.self_ref (Theory.sign_of (the_context ()))
    88   val T		= HOLogic.intT
    89   val zero		= Const ("0", HOLogic.intT)
    90   val restrict_to_left  = restrict_to_left
    91   val add_cancel_21	= zadd_cancel_21
    92   val add_cancel_end	= zadd_cancel_end
    93   val add_left_cancel	= zadd_left_cancel
    94   val add_assoc		= zadd_assoc
    95   val add_commute	= zadd_commute
    96   val add_left_commute	= zadd_left_commute
    97   val add_0		= zadd_0
    98   val add_0_right	= zadd_0_right
    99 
   100   val eq_diff_eq	= eq_zdiff_eq
   101   val eqI_rules		= [zless_eqI, zeq_eqI, zle_eqI]
   102   fun dest_eqI th = 
   103       #1 (HOLogic.dest_bin "op =" HOLogic.boolT
   104 	      (HOLogic.dest_Trueprop (concl_of th)))
   105 
   106   val diff_def		= zdiff_def
   107   val minus_add_distrib	= zminus_zadd_distrib
   108   val minus_minus	= zminus_zminus
   109   val minus_0		= zminus_0
   110   val add_inverses	= [zadd_zminus_inverse, zadd_zminus_inverse2]
   111   val cancel_simps	= [zadd_zminus_cancel, zminus_zadd_cancel]
   112 end;
   113 
   114 structure Int_Cancel = Abel_Cancel (Int_Cancel_Data);
   115 
   116 Addsimprocs [Int_Cancel.sum_conv, Int_Cancel.rel_conv];
   117 
   118 
   119 
   120 (*** misc ***)
   121 
   122 Goal "- (z - y) = y - (z::int)";
   123 by (Simp_tac 1);
   124 qed "zminus_zdiff_eq";
   125 Addsimps [zminus_zdiff_eq];
   126 
   127 Goal "(w<z) = neg(w-z)";
   128 by (simp_tac (simpset() addsimps [zless_def]) 1);
   129 qed "zless_eq_neg";
   130 
   131 Goal "(w=z) = iszero(w-z)";
   132 by (simp_tac (simpset() addsimps [iszero_def, zdiff_eq_eq]) 1);
   133 qed "eq_eq_iszero";
   134 
   135 Goal "(w<=z) = (~ neg(z-w))";
   136 by (simp_tac (simpset() addsimps [zle_def, zless_def]) 1);
   137 qed "zle_eq_not_neg";
   138 
   139 (** Inequality reasoning **)
   140 
   141 Goal "(w < z + (1::int)) = (w<z | w=z)";
   142 by (auto_tac (claset(),
   143 	      simpset() addsimps [zless_iff_Suc_zadd, int_Suc,
   144                                   gr0_conv_Suc, zero_reorient]));
   145 by (res_inst_tac [("x","Suc n")] exI 1); 
   146 by (simp_tac (simpset() addsimps [int_Suc]) 1); 
   147 qed "zless_add1_eq";
   148 
   149 Goal "(w + (1::int) <= z) = (w<z)";
   150 by (asm_full_simp_tac (simpset() addsimps [zle_def, zless_add1_eq]) 1); 
   151 by (auto_tac (claset() addIs [zle_anti_sym],
   152 	      simpset() addsimps [order_less_imp_le, symmetric zle_def]));
   153 qed "add1_zle_eq";
   154 
   155 Goal "((1::int) + w <= z) = (w<z)";
   156 by (stac zadd_commute 1);
   157 by (rtac add1_zle_eq 1);
   158 qed "add1_left_zle_eq";
   159 
   160 
   161 (*** Monotonicity results ***)
   162 
   163 Goal "(v+z < w+z) = (v < (w::int))";
   164 by (Simp_tac 1);
   165 qed "zadd_right_cancel_zless";
   166 
   167 Goal "(z+v < z+w) = (v < (w::int))";
   168 by (Simp_tac 1);
   169 qed "zadd_left_cancel_zless";
   170 
   171 Addsimps [zadd_right_cancel_zless, zadd_left_cancel_zless];
   172 
   173 Goal "(v+z <= w+z) = (v <= (w::int))";
   174 by (Simp_tac 1);
   175 qed "zadd_right_cancel_zle";
   176 
   177 Goal "(z+v <= z+w) = (v <= (w::int))";
   178 by (Simp_tac 1);
   179 qed "zadd_left_cancel_zle";
   180 
   181 Addsimps [zadd_right_cancel_zle, zadd_left_cancel_zle];
   182 
   183 (*"v<=w ==> v+z <= w+z"*)
   184 bind_thm ("zadd_zless_mono1", zadd_right_cancel_zless RS iffD2);
   185 
   186 (*"v<=w ==> z+v <= z+w"*)
   187 bind_thm ("zadd_zless_mono2", zadd_left_cancel_zless RS iffD2);
   188 
   189 (*"v<=w ==> v+z <= w+z"*)
   190 bind_thm ("zadd_zle_mono1", zadd_right_cancel_zle RS iffD2);
   191 
   192 (*"v<=w ==> z+v <= z+w"*)
   193 bind_thm ("zadd_zle_mono2", zadd_left_cancel_zle RS iffD2);
   194 
   195 Goal "[| w'<=w; z'<=z |] ==> w' + z' <= w + (z::int)";
   196 by (etac (zadd_zle_mono1 RS zle_trans) 1);
   197 by (Simp_tac 1);
   198 qed "zadd_zle_mono";
   199 
   200 Goal "[| w'<w; z'<=z |] ==> w' + z' < w + (z::int)";
   201 by (etac (zadd_zless_mono1 RS order_less_le_trans) 1);
   202 by (Simp_tac 1);
   203 qed "zadd_zless_mono";
   204 
   205 
   206 (*** Comparison laws ***)
   207 
   208 Goal "(- x < - y) = (y < (x::int))";
   209 by (simp_tac (simpset() addsimps [zless_def, zdiff_def] @ zadd_ac) 1);
   210 qed "zminus_zless_zminus"; 
   211 Addsimps [zminus_zless_zminus];
   212 
   213 Goal "(- x <= - y) = (y <= (x::int))";
   214 by (simp_tac (simpset() addsimps [zle_def]) 1);
   215 qed "zminus_zle_zminus"; 
   216 Addsimps [zminus_zle_zminus];
   217 
   218 (** The next several equations can make the simplifier loop! **)
   219 
   220 Goal "(x < - y) = (y < - (x::int))";
   221 by (simp_tac (simpset() addsimps [zless_def, zdiff_def] @ zadd_ac) 1);
   222 qed "zless_zminus"; 
   223 
   224 Goal "(- x < y) = (- y < (x::int))";
   225 by (simp_tac (simpset() addsimps [zless_def, zdiff_def] @ zadd_ac) 1);
   226 qed "zminus_zless"; 
   227 
   228 Goal "(x <= - y) = (y <= - (x::int))";
   229 by (simp_tac (simpset() addsimps [zle_def, zminus_zless]) 1);
   230 qed "zle_zminus"; 
   231 
   232 Goal "(- x <= y) = (- y <= (x::int))";
   233 by (simp_tac (simpset() addsimps [zle_def, zless_zminus]) 1);
   234 qed "zminus_zle"; 
   235 
   236 Goal "(x = - y) = (y = - (x::int))";
   237 by Auto_tac;
   238 qed "equation_zminus";
   239 
   240 Goal "(- x = y) = (- (y::int) = x)";
   241 by Auto_tac;
   242 qed "zminus_equation";
   243 
   244 
   245 (** Instances of the equations above, for zero **)
   246 
   247 (*instantiate a variable to zero and simplify*)
   248 fun zero_instance v th = simplify (simpset()) (inst v "0" th);
   249 
   250 Addsimps [zero_instance "x" zless_zminus,
   251           zero_instance "y" zminus_zless,
   252           zero_instance "x" zle_zminus,
   253           zero_instance "y" zminus_zle,
   254           zero_instance "x" equation_zminus,
   255           zero_instance "y" zminus_equation];
   256 
   257 
   258 Goal "- (int (Suc n)) < 0";
   259 by (simp_tac (simpset() addsimps [zless_def]) 1);
   260 qed "negative_zless_0"; 
   261 
   262 Goal "- (int (Suc n)) < int m";
   263 by (rtac (negative_zless_0 RS order_less_le_trans) 1);
   264 by (Simp_tac 1); 
   265 qed "negative_zless"; 
   266 AddIffs [negative_zless]; 
   267 
   268 Goal "- int n <= 0";
   269 by (simp_tac (simpset() addsimps [zminus_zle]) 1);
   270 qed "negative_zle_0"; 
   271 
   272 Goal "- int n <= int m";
   273 by (simp_tac (simpset() addsimps [zless_def, zle_def, zdiff_def, zadd_int]) 1);
   274 qed "negative_zle"; 
   275 AddIffs [negative_zle]; 
   276 
   277 Goal "~(0 <= - (int (Suc n)))";
   278 by (stac zle_zminus 1);
   279 by (Simp_tac 1);
   280 qed "not_zle_0_negative"; 
   281 Addsimps [not_zle_0_negative]; 
   282 
   283 Goal "(int n <= - int m) = (n = 0 & m = 0)"; 
   284 by Safe_tac; 
   285 by (Simp_tac 3); 
   286 by (dtac (zle_zminus RS iffD1) 2); 
   287 by (ALLGOALS (dtac (negative_zle_0 RSN(2,zle_trans)))); 
   288 by (ALLGOALS Asm_full_simp_tac); 
   289 qed "int_zle_neg"; 
   290 
   291 Goal "~(int n < - int m)";
   292 by (simp_tac (simpset() addsimps [symmetric zle_def]) 1); 
   293 qed "not_int_zless_negative"; 
   294 
   295 Goal "(- int n = int m) = (n = 0 & m = 0)"; 
   296 by (rtac iffI 1);
   297 by (rtac (int_zle_neg RS iffD1) 1); 
   298 by (dtac sym 1); 
   299 by (ALLGOALS Asm_simp_tac); 
   300 qed "negative_eq_positive"; 
   301 
   302 Addsimps [negative_eq_positive, not_int_zless_negative]; 
   303 
   304 
   305 Goal "(w <= z) = (EX n. z = w + int n)";
   306 by (auto_tac (claset() addIs [inst "x" "0::nat" exI]
   307 		       addSIs [not_sym RS not0_implies_Suc],
   308 	      simpset() addsimps [zless_iff_Suc_zadd, int_le_less]));
   309 qed "zle_iff_zadd";
   310 
   311 Goal "abs (int m) = int m";
   312 by (simp_tac (simpset() addsimps [zabs_def]) 1); 
   313 qed "abs_int_eq";
   314 Addsimps [abs_int_eq];
   315 
   316 
   317 (**** nat: magnitide of an integer, as a natural number ****)
   318 
   319 Goalw [nat_def] "nat(int n) = n";
   320 by Auto_tac;
   321 qed "nat_int";
   322 Addsimps [nat_int];
   323 
   324 Goalw [nat_def] "nat(- (int n)) = 0";
   325 by (auto_tac (claset(),
   326      simpset() addsimps [neg_eq_less_0, zero_reorient, zminus_zless])); 
   327 qed "nat_zminus_int";
   328 Addsimps [nat_zminus_int];
   329 
   330 Goalw [Zero_int_def] "nat 0 = 0";
   331 by (rtac nat_int 1);
   332 qed "nat_zero";
   333 Addsimps [nat_zero];
   334 
   335 Goal "~ neg z ==> int (nat z) = z"; 
   336 by (dtac (not_neg_eq_ge_0 RS iffD1) 1); 
   337 by (dtac zle_imp_zless_or_eq 1); 
   338 by (auto_tac (claset(), simpset() addsimps [zless_iff_Suc_zadd])); 
   339 qed "not_neg_nat"; 
   340 
   341 Goal "neg x ==> EX n. x = - (int (Suc n))"; 
   342 by (auto_tac (claset(), 
   343 	      simpset() addsimps [neg_eq_less_0, zless_iff_Suc_zadd,
   344 				  zdiff_eq_eq RS sym, zdiff_def])); 
   345 qed "negD"; 
   346 
   347 Goalw [nat_def] "neg z ==> nat z = 0"; 
   348 by Auto_tac; 
   349 qed "neg_nat"; 
   350 
   351 Goal "(m < nat z) = (int m < z)";
   352 by (case_tac "neg z" 1);
   353 by (etac (not_neg_nat RS subst) 2);
   354 by (auto_tac (claset(), simpset() addsimps [neg_nat])); 
   355 by (auto_tac (claset() addDs [order_less_trans], 
   356 	      simpset() addsimps [neg_eq_less_0])); 
   357 qed "zless_nat_eq_int_zless";
   358 
   359 Goal "0 <= z ==> int (nat z) = z"; 
   360 by (asm_full_simp_tac
   361     (simpset() addsimps [neg_eq_less_0, zle_def, not_neg_nat]) 1); 
   362 qed "nat_0_le"; 
   363 
   364 Goal "z <= 0 ==> nat z = 0"; 
   365 by (auto_tac (claset(), 
   366 	      simpset() addsimps [order_le_less, neg_eq_less_0, 
   367 				  zle_def, neg_nat])); 
   368 qed "nat_le_0"; 
   369 Addsimps [nat_0_le, nat_le_0];
   370 
   371 (*An alternative condition is  0 <= w  *)
   372 Goal "0 < z ==> (nat w < nat z) = (w < z)";
   373 by (stac (zless_int RS sym) 1);
   374 by (asm_simp_tac (simpset() addsimps [not_neg_nat, not_neg_eq_ge_0, 
   375 				      order_le_less]) 1);
   376 by (case_tac "neg w" 1);
   377 by (asm_simp_tac (simpset() addsimps [not_neg_nat]) 2);
   378 by (asm_full_simp_tac (simpset() addsimps [neg_eq_less_0, neg_nat]) 1);
   379 by (blast_tac (claset() addIs [order_less_trans]) 1);
   380 val lemma = result();
   381 
   382 Goal "(nat w < nat z) = (0 < z & w < z)";
   383 by (case_tac "0 < z" 1);
   384 by (auto_tac (claset(), simpset() addsimps [lemma, linorder_not_less])); 
   385 qed "zless_nat_conj";
   386 
   387 
   388 (* a case theorem distinguishing non-negative and negative int *)  
   389 
   390 val prems = Goal
   391      "[|!! n. z = int n ==> P;  !! n. z =  - (int (Suc n)) ==> P |] ==> P"; 
   392 by (case_tac "neg z" 1); 
   393 by (fast_tac (claset() addSDs [negD] addSEs prems) 1); 
   394 by (dtac (not_neg_nat RS sym) 1);
   395 by (eresolve_tac prems 1);
   396 qed "int_cases"; 
   397 
   398 fun int_case_tac x = res_inst_tac [("z",x)] int_cases; 
   399 
   400 
   401 (*** Monotonicity of Multiplication ***)
   402 
   403 Goal "i <= (j::int) ==> i * int k <= j * int k";
   404 by (induct_tac "k" 1);
   405 by (stac int_Suc 2);
   406 by (ALLGOALS 
   407     (asm_simp_tac (simpset() addsimps [zadd_zmult_distrib2, zadd_zle_mono, 
   408                                        int_Suc0_eq_1])));
   409 val lemma = result();
   410 
   411 Goal "[| i <= j;  (0::int) <= k |] ==> i*k <= j*k";
   412 by (res_inst_tac [("t", "k")] (not_neg_nat RS subst) 1);
   413 by (etac lemma 2);
   414 by (full_simp_tac (simpset() addsimps [not_neg_eq_ge_0]) 1);
   415 qed "zmult_zle_mono1";
   416 
   417 Goal "[| i <= j;  k <= (0::int) |] ==> j*k <= i*k";
   418 by (rtac (zminus_zle_zminus RS iffD1) 1);
   419 by (asm_simp_tac (simpset() addsimps [zmult_zminus_right RS sym,
   420 				      zmult_zle_mono1, zle_zminus]) 1);
   421 qed "zmult_zle_mono1_neg";
   422 
   423 Goal "[| i <= j;  (0::int) <= k |] ==> k*i <= k*j";
   424 by (dtac zmult_zle_mono1 1);
   425 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [zmult_commute])));
   426 qed "zmult_zle_mono2";
   427 
   428 Goal "[| i <= j;  k <= (0::int) |] ==> k*j <= k*i";
   429 by (dtac zmult_zle_mono1_neg 1);
   430 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [zmult_commute])));
   431 qed "zmult_zle_mono2_neg";
   432 
   433 (* <= monotonicity, BOTH arguments*)
   434 Goal "[| i <= j;  k <= l;  (0::int) <= j;  (0::int) <= k |] ==> i*k <= j*l";
   435 by (etac (zmult_zle_mono1 RS order_trans) 1);
   436 by (assume_tac 1);
   437 by (etac zmult_zle_mono2 1);
   438 by (assume_tac 1);
   439 qed "zmult_zle_mono";
   440 
   441 
   442 (** strict, in 1st argument; proof is by induction on k>0 **)
   443 
   444 Goal "i<j ==> 0<k --> int k * i < int k * j";
   445 by (induct_tac "k" 1);
   446 by (stac int_Suc 2);
   447 by (case_tac "n=0" 2);
   448 by (ALLGOALS (asm_full_simp_tac
   449 	      (simpset() addsimps [zadd_zmult_distrib, zadd_zless_mono, 
   450 				   int_Suc0_eq_1, order_le_less])));
   451 val lemma = result();
   452 
   453 Goal "[| i<j;  (0::int) < k |] ==> k*i < k*j";
   454 by (res_inst_tac [("t", "k")] (not_neg_nat RS subst) 1);
   455 by (etac (lemma RS mp) 2);
   456 by (asm_simp_tac (simpset() addsimps [not_neg_eq_ge_0, 
   457 				      order_le_less]) 1);
   458 by (forward_tac [conjI RS (zless_nat_conj RS iffD2)] 1);
   459 by Auto_tac;
   460 qed "zmult_zless_mono2";
   461 
   462 Goal "[| i<j;  (0::int) < k |] ==> i*k < j*k";
   463 by (dtac zmult_zless_mono2 1);
   464 by (ALLGOALS (asm_full_simp_tac (simpset() addsimps [zmult_commute])));
   465 qed "zmult_zless_mono1";
   466 
   467 (* < monotonicity, BOTH arguments*)
   468 Goal "[| i < j;  k < l;  (0::int) < j;  (0::int) < k |] ==> i*k < j*l";
   469 by (etac (zmult_zless_mono1 RS order_less_trans) 1);
   470 by (assume_tac 1);
   471 by (etac zmult_zless_mono2 1);
   472 by (assume_tac 1);
   473 qed "zmult_zless_mono";
   474 
   475 Goal "[| i<j;  k < (0::int) |] ==> j*k < i*k";
   476 by (rtac (zminus_zless_zminus RS iffD1) 1);
   477 by (asm_simp_tac (simpset() addsimps [zmult_zminus_right RS sym,
   478 				      zmult_zless_mono1, zless_zminus]) 1);
   479 qed "zmult_zless_mono1_neg";
   480 
   481 Goal "[| i<j;  k < (0::int) |] ==> k*j < k*i";
   482 by (rtac (zminus_zless_zminus RS iffD1) 1);
   483 by (asm_simp_tac (simpset() addsimps [zmult_zminus RS sym,
   484 				      zmult_zless_mono2, zless_zminus]) 1);
   485 qed "zmult_zless_mono2_neg";
   486 
   487 
   488 Goal "(m*n = (0::int)) = (m = 0 | n = 0)";
   489 by (case_tac "m < (0::int)" 1);
   490 by (auto_tac (claset(), 
   491 	      simpset() addsimps [linorder_not_less, order_le_less, 
   492 				  linorder_neq_iff])); 
   493 by (REPEAT 
   494     (force_tac (claset() addDs [zmult_zless_mono1_neg, zmult_zless_mono1], 
   495 		simpset()) 1));
   496 qed "zmult_eq_0_iff";
   497 AddIffs [zmult_eq_0_iff];
   498 
   499 
   500 (** Cancellation laws for k*m < k*n and m*k < n*k, also for <= and =,
   501     but not (yet?) for k*m < n*k. **)
   502 
   503 Goal "(m*k < n*k) = (((0::int) < k & m<n) | (k < 0 & n<m))";
   504 by (case_tac "k = (0::int)" 1);
   505 by (auto_tac (claset(), simpset() addsimps [linorder_neq_iff, 
   506                               zmult_zless_mono1, zmult_zless_mono1_neg]));  
   507 by (auto_tac (claset(), 
   508               simpset() addsimps [linorder_not_less,
   509 				  inst "y1" "m*k" (linorder_not_le RS sym),
   510                                   inst "y1" "m" (linorder_not_le RS sym)]));
   511 by (ALLGOALS (etac notE));
   512 by (auto_tac (claset(), simpset() addsimps [order_less_imp_le, zmult_zle_mono1,
   513                                             zmult_zle_mono1_neg]));  
   514 qed "zmult_zless_cancel2";
   515 
   516 
   517 Goal "(k*m < k*n) = (((0::int) < k & m<n) | (k < 0 & n<m))";
   518 by (simp_tac (simpset() addsimps [inst "z" "k" zmult_commute, 
   519                                   zmult_zless_cancel2]) 1);
   520 qed "zmult_zless_cancel1";
   521 
   522 Goal "(m*k <= n*k) = (((0::int) < k --> m<=n) & (k < 0 --> n<=m))";
   523 by (simp_tac (simpset() addsimps [linorder_not_less RS sym, 
   524                                   zmult_zless_cancel2]) 1);
   525 qed "zmult_zle_cancel2";
   526 
   527 Goal "(k*m <= k*n) = (((0::int) < k --> m<=n) & (k < 0 --> n<=m))";
   528 by (simp_tac (simpset() addsimps [linorder_not_less RS sym, 
   529                                   zmult_zless_cancel1]) 1);
   530 qed "zmult_zle_cancel1";
   531 
   532 Goal "(m*k = n*k) = (k = (0::int) | m=n)";
   533 by (cut_facts_tac [linorder_less_linear] 1);
   534 by Safe_tac;
   535 by Auto_tac;  
   536 by (REPEAT 
   537     (force_tac (claset() addD2 ("mono_neg", zmult_zless_mono1_neg)
   538                          addD2 ("mono_pos", zmult_zless_mono1), 
   539 		simpset() addsimps [linorder_neq_iff]) 1));
   540 
   541 qed "zmult_cancel2";
   542 
   543 Goal "(k*m = k*n) = (k = (0::int) | m=n)";
   544 by (simp_tac (simpset() addsimps [inst "z" "k" zmult_commute, 
   545                                   zmult_cancel2]) 1);
   546 qed "zmult_cancel1";
   547 Addsimps [zmult_cancel1, zmult_cancel2];
   548 
   549 
   550 (*Analogous to zadd_int*)
   551 Goal "n<=m --> int m - int n = int (m-n)";
   552 by (induct_thm_tac diff_induct "m n" 1);
   553 by (auto_tac (claset(), simpset() addsimps [int_Suc, symmetric zdiff_def])); 
   554 qed_spec_mp "zdiff_int";