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