src/HOL/Integ/IntArith.ML
author paulson
Mon, 22 Oct 2001 11:54:22 +0200
changeset 11868 56db9f3a6b3e
parent 11770 b6bb7a853dd2
child 12018 ec054019c910
permissions -rw-r--r--
Numerals now work for the integers: the binary numerals for 0 and 1 rewrite
to their abstract counterparts, while other binary numerals work correctly.
     1 (*  Title:      HOL/Integ/IntArith.ML
     2     ID:         $Id$
     3     Authors:    Larry Paulson and Tobias Nipkow
     4 *)
     5 
     6 
     7 Goal "abs(abs(x::int)) = abs(x)";
     8 by(arith_tac 1);
     9 qed "abs_abs";
    10 Addsimps [abs_abs];
    11 
    12 Goal "abs(-(x::int)) = abs(x)";
    13 by(arith_tac 1);
    14 qed "abs_minus";
    15 Addsimps [abs_minus];
    16 
    17 Goal "abs(x+y) <= abs(x) + abs(y::int)";
    18 by(arith_tac 1);
    19 qed "triangle_ineq";
    20 
    21 
    22 (*** Intermediate value theorems ***)
    23 
    24 Goal "(ALL i<n::nat. abs(f(i+1) - f i) <= 1) --> \
    25 \     f 0 <= k --> k <= f n --> (EX i <= n. f i = (k::int))";
    26 by(induct_tac "n" 1);
    27  by(Asm_simp_tac 1);
    28 by(strip_tac 1);
    29 by(etac impE 1);
    30  by(Asm_full_simp_tac 1);
    31 by(eres_inst_tac [("x","n")] allE 1);
    32 by(Asm_full_simp_tac 1);
    33 by(case_tac "k = f(n+1)" 1);
    34  by(Force_tac 1);
    35 by(etac impE 1);
    36  by(asm_full_simp_tac (simpset() addsimps [zabs_def] 
    37                                  addsplits [split_if_asm]) 1);
    38  by(arith_tac 1);
    39 by(blast_tac (claset() addIs [le_SucI]) 1);
    40 val lemma = result();
    41 
    42 bind_thm("nat0_intermed_int_val", ObjectLogic.rulify_no_asm lemma);
    43 
    44 Goal "[| !i. m <= i & i < n --> abs(f(i + 1::nat) - f i) <= 1; m < n; \
    45 \        f m <= k; k <= f n |] ==> ? i. m <= i & i <= n & f i = (k::int)";
    46 by(cut_inst_tac [("n","n-m"),("f", "%i. f(i+m)"),("k","k")]lemma 1);
    47 by(Asm_full_simp_tac 1);
    48 by(etac impE 1);
    49  by(strip_tac 1);
    50  by(eres_inst_tac [("x","i+m")] allE 1);
    51  by(arith_tac 1);
    52 by(etac exE 1);
    53 by(res_inst_tac [("x","i+m")] exI 1);
    54 by(arith_tac 1);
    55 qed "nat_intermed_int_val";
    56 
    57 
    58 (*** Some convenient biconditionals for products of signs ***)
    59 
    60 Goal "[| (0::int) < i; 0 < j |] ==> 0 < i*j";
    61 by (dtac zmult_zless_mono1 1);
    62 by Auto_tac; 
    63 qed "zmult_pos";
    64 
    65 Goal "[| i < (0::int); j < 0 |] ==> 0 < i*j";
    66 by (dtac zmult_zless_mono1_neg 1);
    67 by Auto_tac; 
    68 qed "zmult_neg";
    69 
    70 Goal "[| (0::int) < i; j < 0 |] ==> i*j < 0";
    71 by (dtac zmult_zless_mono1_neg 1);
    72 by Auto_tac; 
    73 qed "zmult_pos_neg";
    74 
    75 Goal "((0::int) < x*y) = (0 < x & 0 < y | x < 0 & y < 0)";
    76 by (auto_tac (claset(), 
    77               simpset() addsimps [order_le_less, linorder_not_less,
    78 	                          zmult_pos, zmult_neg]));
    79 by (ALLGOALS (rtac ccontr)); 
    80 by (auto_tac (claset(), 
    81 	      simpset() addsimps [order_le_less, linorder_not_less]));
    82 by (ALLGOALS (etac rev_mp)); 
    83 by (ALLGOALS (dtac zmult_pos_neg THEN' assume_tac));
    84 by (auto_tac (claset() addDs [order_less_not_sym], 
    85               simpset() addsimps [zmult_commute]));  
    86 qed "int_0_less_mult_iff";
    87 
    88 Goal "((0::int) <= x*y) = (0 <= x & 0 <= y | x <= 0 & y <= 0)";
    89 by (auto_tac (claset(), 
    90               simpset() addsimps [order_le_less, linorder_not_less,  
    91                                   int_0_less_mult_iff]));
    92 qed "int_0_le_mult_iff";
    93 
    94 Goal "(x*y < (0::int)) = (0 < x & y < 0 | x < 0 & 0 < y)";
    95 by (auto_tac (claset(), 
    96               simpset() addsimps [int_0_le_mult_iff, 
    97                                   linorder_not_le RS sym]));
    98 by (auto_tac (claset() addDs [order_less_not_sym],  
    99               simpset() addsimps [linorder_not_le]));
   100 qed "zmult_less_0_iff";
   101 
   102 Goal "(x*y <= (0::int)) = (0 <= x & y <= 0 | x <= 0 & 0 <= y)";
   103 by (auto_tac (claset() addDs [order_less_not_sym], 
   104               simpset() addsimps [int_0_less_mult_iff, 
   105                                   linorder_not_less RS sym]));
   106 qed "zmult_le_0_iff";
   107 
   108 Goal "abs (x * y) = abs x * abs (y::int)";
   109 by (simp_tac (simpset () delsimps [thm "number_of_reorient"] addsplits [zabs_split] 
   110                          addsplits [zabs_split] 
   111                          addsimps [zmult_less_0_iff, zle_def]) 1);
   112 qed "abs_mult";
   113 
   114 Goal "(abs x = 0) = (x = (0::int))";
   115 by (simp_tac (simpset () addsplits [zabs_split]) 1);
   116 qed "abs_eq_0";
   117 AddIffs [abs_eq_0];
   118 
   119 Goal "(0 < abs x) = (x ~= (0::int))";
   120 by (simp_tac (simpset () addsplits [zabs_split]) 1);
   121 by (arith_tac 1);
   122 qed "zero_less_abs_iff";
   123 AddIffs [zero_less_abs_iff];
   124 
   125 Goal "0 <= x * (x::int)";
   126 by (subgoal_tac "(- x) * x <= 0" 1);
   127  by (Asm_full_simp_tac 1);
   128 by (simp_tac (HOL_basic_ss addsimps [zmult_le_0_iff]) 1);
   129 by Auto_tac;
   130 qed "square_nonzero";
   131 Addsimps [square_nonzero];
   132 AddIs [square_nonzero];
   133 
   134 
   135 (*** Products and 1, by T. M. Rasmussen ***)
   136 
   137 Goal "(m = m*(n::int)) = (n = 1 | m = 0)";
   138 by Auto_tac;
   139 by (subgoal_tac "m*1 = m*n" 1);
   140 by (dtac (zmult_cancel1 RS iffD1) 1); 
   141 by Auto_tac;
   142 qed "zmult_eq_self_iff";
   143 
   144 Goal "[| 1 < m; 1 < n |] ==> 1 < m*(n::int)";
   145 by (res_inst_tac [("y","1*n")] order_less_trans 1);
   146 by (rtac zmult_zless_mono1 2);
   147 by (ALLGOALS Asm_simp_tac);
   148 qed "zless_1_zmult";
   149 
   150 Goal "[| 0 < n; n ~= 1 |] ==> 1 < (n::int)";
   151 by (arith_tac 1);
   152 val lemma = result();
   153 
   154 Goal "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)";
   155 by Auto_tac;
   156 by (case_tac "m=1" 1);
   157 by (case_tac "n=1" 2);
   158 by (case_tac "m=1" 4);
   159 by (case_tac "n=1" 5);
   160 by Auto_tac;
   161 by distinct_subgoals_tac;
   162 by (subgoal_tac "1<m*n" 1);
   163 by (Asm_full_simp_tac 1);
   164 by (rtac zless_1_zmult 1);
   165 by (ALLGOALS (rtac lemma));
   166 by Auto_tac;  
   167 by (subgoal_tac "0<m*n" 1);
   168 by (Asm_simp_tac 2);
   169 by (dtac (int_0_less_mult_iff RS iffD1) 1);
   170 by Auto_tac;  
   171 qed "pos_zmult_eq_1_iff";
   172 
   173 Goal "(m*n = (1::int)) = ((m = 1 & n = 1) | (m = -1 & n = -1))";
   174 by (case_tac "0<m" 1);
   175 by (asm_simp_tac (simpset() addsimps [pos_zmult_eq_1_iff]) 1);
   176 by (case_tac "m=0" 1);
   177 by (asm_simp_tac (simpset () delsimps [thm "number_of_reorient"]) 1);
   178 by (subgoal_tac "0 < -m" 1);
   179 by (arith_tac 2);
   180 by (dres_inst_tac [("n","-n")] pos_zmult_eq_1_iff 1); 
   181 by Auto_tac;  
   182 qed "zmult_eq_1_iff";
   183