src/HOL/Integ/IntArith.thy
changeset 14387 e96d5c42c4b0
parent 14378 69c4d5997669
child 14390 55fe71faadda
equal deleted inserted replaced
14386:ad1ffcc90162 14387:e96d5c42c4b0
     6 header {* Integer arithmetic *}
     6 header {* Integer arithmetic *}
     7 
     7 
     8 theory IntArith = Bin
     8 theory IntArith = Bin
     9 files ("int_arith1.ML"):
     9 files ("int_arith1.ML"):
    10 
    10 
       
    11 text{*Duplicate: can't understand why it's necessary*}
       
    12 declare numeral_0_eq_0 [simp]
       
    13 
       
    14 subsection{*Instantiating Binary Arithmetic for the Integers*}
       
    15 
       
    16 instance
       
    17   int :: number ..
       
    18 
       
    19 primrec (*the type constraint is essential!*)
       
    20   number_of_Pls: "number_of bin.Pls = 0"
       
    21   number_of_Min: "number_of bin.Min = - (1::int)"
       
    22   number_of_BIT: "number_of(w BIT x) = (if x then 1 else 0) +
       
    23 	                               (number_of w) + (number_of w)"
       
    24 
       
    25 declare number_of_Pls [simp del]
       
    26         number_of_Min [simp del]
       
    27         number_of_BIT [simp del]
       
    28 
       
    29 instance int :: number_ring
       
    30 proof
       
    31   show "Numeral0 = (0::int)" by (rule number_of_Pls)
       
    32   show "-1 = - (1::int)" by (rule number_of_Min)
       
    33   fix w :: bin and x :: bool
       
    34   show "(number_of (w BIT x) :: int) =
       
    35         (if x then 1 else 0) + number_of w + number_of w"
       
    36     by (rule number_of_BIT)
       
    37 qed
       
    38 
       
    39 
    11 
    40 
    12 subsection{*Inequality Reasoning for the Arithmetic Simproc*}
    41 subsection{*Inequality Reasoning for the Arithmetic Simproc*}
       
    42 
       
    43 lemma zero_less_nat_eq [simp]: "(0 < nat z) = (0 < z)"
       
    44 by (cut_tac w = 0 in zless_nat_conj, auto)
    13 
    45 
    14 lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z"
    46 lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z"
    15 apply (rule eq_Abs_Integ [of z])
    47 apply (rule eq_Abs_Integ [of z])
    16 apply (rule eq_Abs_Integ [of w])
    48 apply (rule eq_Abs_Integ [of w])
    17 apply (simp add: linorder_not_le [symmetric] zle int_def zadd One_int_def)
    49 apply (simp add: linorder_not_le [symmetric] zle int_def zadd One_int_def)
    18 done
    50 done
    19 
    51 
    20 
    52 
       
    53 
       
    54 lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)"
       
    55 by simp 
       
    56 
       
    57 lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)"
       
    58 by simp
       
    59 
       
    60 lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)"
       
    61 by simp 
       
    62 
       
    63 lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)"
       
    64 by simp
       
    65 
       
    66 text{*Theorem lists for the cancellation simprocs. The use of binary numerals
       
    67 for 0 and 1 reduces the number of special cases.*}
       
    68 
       
    69 lemmas add_0s = add_numeral_0 add_numeral_0_right
       
    70 lemmas mult_1s = mult_numeral_1 mult_numeral_1_right 
       
    71                  mult_minus1 mult_minus1_right
       
    72 
       
    73 
       
    74 subsection{*Special Arithmetic Rules for Abstract 0 and 1*}
       
    75 
       
    76 text{*Arithmetic computations are defined for binary literals, which leaves 0
       
    77 and 1 as special cases. Addition already has rules for 0, but not 1.
       
    78 Multiplication and unary minus already have rules for both 0 and 1.*}
       
    79 
       
    80 
       
    81 lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'"
       
    82 by simp
       
    83 
       
    84 
       
    85 lemmas add_number_of_eq = number_of_add [symmetric]
       
    86 
       
    87 text{*Allow 1 on either or both sides*}
       
    88 lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)"
       
    89 by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq)
       
    90 
       
    91 lemmas add_special =
       
    92     one_add_one_is_two
       
    93     binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard]
       
    94     binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard]
       
    95 
       
    96 text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*}
       
    97 lemmas diff_special =
       
    98     binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard]
       
    99     binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard]
       
   100 
       
   101 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
       
   102 lemmas eq_special =
       
   103     binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard]
       
   104     binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard]
       
   105     binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard]
       
   106     binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard]
       
   107 
       
   108 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
       
   109 lemmas less_special =
       
   110   binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard]
       
   111   binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard]
       
   112   binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard]
       
   113   binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard]
       
   114 
       
   115 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
       
   116 lemmas le_special =
       
   117     binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard]
       
   118     binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard]
       
   119     binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard]
       
   120     binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard]
       
   121 
       
   122 lemmas arith_special = 
       
   123        add_special diff_special eq_special less_special le_special
       
   124 
       
   125 
    21 use "int_arith1.ML"
   126 use "int_arith1.ML"
    22 setup int_arith_setup
   127 setup int_arith_setup
    23 
   128 
    24 
   129 
    25 subsection{*More inequality reasoning*}
   130 subsection{*Lemmas About Small Numerals*}
       
   131 
       
   132 lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)"
       
   133 proof -
       
   134   have "(of_int -1 :: 'a) = of_int (- 1)" by simp
       
   135   also have "... = - of_int 1" by (simp only: of_int_minus)
       
   136   also have "... = -1" by simp
       
   137   finally show ?thesis .
       
   138 qed
       
   139 
       
   140 lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_ring,number_ring})"
       
   141 by (simp add: abs_if)
       
   142 
       
   143 lemma of_int_number_of_eq:
       
   144      "of_int (number_of v) = (number_of v :: 'a :: number_ring)"
       
   145 apply (induct v)
       
   146 apply (simp_all only: number_of of_int_add, simp_all) 
       
   147 done
       
   148 
       
   149 text{*Lemmas for specialist use, NOT as default simprules*}
       
   150 lemma mult_2: "2 * z = (z+z::'a::number_ring)"
       
   151 proof -
       
   152   have "2*z = (1 + 1)*z" by simp
       
   153   also have "... = z+z" by (simp add: left_distrib)
       
   154   finally show ?thesis .
       
   155 qed
       
   156 
       
   157 lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)"
       
   158 by (subst mult_commute, rule mult_2)
       
   159 
       
   160 
       
   161 subsection{*More Inequality Reasoning*}
    26 
   162 
    27 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
   163 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
    28 by arith
   164 by arith
    29 
   165 
    30 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
   166 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
    32 
   168 
    33 lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<(z::int))"
   169 lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<(z::int))"
    34 by arith
   170 by arith
    35 
   171 
    36 lemma zle_add1_eq_le [simp]: "(w < z + 1) = (w\<le>(z::int))"
   172 lemma zle_add1_eq_le [simp]: "(w < z + 1) = (w\<le>(z::int))"
    37 by arith
       
    38 
       
    39 lemma zadd_left_cancel0 [simp]: "(z = z + w) = (w = (0::int))"
       
    40 by arith
   173 by arith
    41 
   174 
    42 lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
   175 lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
    43 by arith
   176 by arith
    44 
   177 
    83 
   216 
    84 lemma nat_less_eq_zless: "0 \<le> w ==> (nat w < nat z) = (w<z)"
   217 lemma nat_less_eq_zless: "0 \<le> w ==> (nat w < nat z) = (w<z)"
    85 apply (case_tac "z < 0")
   218 apply (case_tac "z < 0")
    86 apply (auto simp add: nat_less_iff)
   219 apply (auto simp add: nat_less_iff)
    87 done
   220 done
    88 
       
    89 
   221 
    90 lemma nat_le_eq_zle: "0 < w | 0 \<le> z ==> (nat w \<le> nat z) = (w\<le>z)"
   222 lemma nat_le_eq_zle: "0 < w | 0 \<le> z ==> (nat w \<le> nat z) = (w\<le>z)"
    91 by (auto simp add: linorder_not_less [symmetric] zless_nat_conj)
   223 by (auto simp add: linorder_not_less [symmetric] zless_nat_conj)
    92 
   224 
    93 
   225 
   111   next
   243   next
   112     assume ?L thus ?P using False by simp
   244     assume ?L thus ?P using False by simp
   113   qed
   245   qed
   114   with False show ?thesis by simp
   246   with False show ?thesis by simp
   115 qed
   247 qed
       
   248 
   116 
   249 
   117 subsubsection "Induction principles for int"
   250 subsubsection "Induction principles for int"
   118 
   251 
   119                      (* `set:int': dummy construction *)
   252                      (* `set:int': dummy construction *)
   120 theorem int_ge_induct[case_names base step,induct set:int]:
   253 theorem int_ge_induct[case_names base step,induct set:int]:
   175     qed
   308     qed
   176   }
   309   }
   177   from this le show ?thesis by fast
   310   from this le show ?thesis by fast
   178 qed
   311 qed
   179 
   312 
   180 theorem int_less_induct[consumes 1,case_names base step]:
   313 theorem int_less_induct [consumes 1,case_names base step]:
   181   assumes less: "(i::int) < k" and
   314   assumes less: "(i::int) < k" and
   182         base: "P(k - 1)" and
   315         base: "P(k - 1)" and
   183         step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   316         step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   184   shows "P i"
   317   shows "P i"
   185 apply(rule int_le_induct[of _ "k - 1"])
   318 apply(rule int_le_induct[of _ "k - 1"])
   226 apply auto
   359 apply auto
   227 apply (subgoal_tac "m*1 = m*n")
   360 apply (subgoal_tac "m*1 = m*n")
   228 apply (drule mult_cancel_left [THEN iffD1], auto)
   361 apply (drule mult_cancel_left [THEN iffD1], auto)
   229 done
   362 done
   230 
   363 
   231 lemma zless_1_zmult: "[| 1 < m; 1 < n |] ==> 1 < m*(n::int)"
   364 text{*FIXME: tidy*}
   232 apply (rule_tac y = "1*n" in order_less_trans)
       
   233 apply (rule_tac [2] mult_strict_right_mono)
       
   234 apply (simp_all (no_asm_simp))
       
   235 done
       
   236 
       
   237 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
   365 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
   238 apply auto
   366 apply auto
   239 apply (case_tac "m=1")
   367 apply (case_tac "m=1")
   240 apply (case_tac [2] "n=1")
   368 apply (case_tac [2] "n=1")
   241 apply (case_tac [4] "m=1")
   369 apply (case_tac [4] "m=1")
   242 apply (case_tac [5] "n=1", auto)
   370 apply (case_tac [5] "n=1", auto)
   243 apply (tactic"distinct_subgoals_tac")
   371 apply (tactic"distinct_subgoals_tac")
   244 apply (subgoal_tac "1<m*n", simp)
   372 apply (subgoal_tac "1<m*n", simp)
   245 apply (rule zless_1_zmult, arith)
   373 apply (rule less_1_mult, arith)
   246 apply (subgoal_tac "0<n", arith)
   374 apply (subgoal_tac "0<n", arith)
   247 apply (subgoal_tac "0<m*n")
   375 apply (subgoal_tac "0<m*n")
   248 apply (drule zero_less_mult_iff [THEN iffD1], auto)
   376 apply (drule zero_less_mult_iff [THEN iffD1], auto)
   249 done
   377 done
   250 
   378 
   298 ML
   426 ML
   299 {*
   427 {*
   300 val zle_diff1_eq = thm "zle_diff1_eq";
   428 val zle_diff1_eq = thm "zle_diff1_eq";
   301 val zle_add1_eq_le = thm "zle_add1_eq_le";
   429 val zle_add1_eq_le = thm "zle_add1_eq_le";
   302 val nonneg_eq_int = thm "nonneg_eq_int";
   430 val nonneg_eq_int = thm "nonneg_eq_int";
       
   431 val abs_minus_one = thm "abs_minus_one";
   303 val nat_eq_iff = thm "nat_eq_iff";
   432 val nat_eq_iff = thm "nat_eq_iff";
   304 val nat_eq_iff2 = thm "nat_eq_iff2";
   433 val nat_eq_iff2 = thm "nat_eq_iff2";
   305 val nat_less_iff = thm "nat_less_iff";
   434 val nat_less_iff = thm "nat_less_iff";
   306 val int_eq_iff = thm "int_eq_iff";
   435 val int_eq_iff = thm "int_eq_iff";
   307 val nat_0 = thm "nat_0";
   436 val nat_0 = thm "nat_0";
   310 val nat_less_eq_zless = thm "nat_less_eq_zless";
   439 val nat_less_eq_zless = thm "nat_less_eq_zless";
   311 val nat_le_eq_zle = thm "nat_le_eq_zle";
   440 val nat_le_eq_zle = thm "nat_le_eq_zle";
   312 
   441 
   313 val nat_intermed_int_val = thm "nat_intermed_int_val";
   442 val nat_intermed_int_val = thm "nat_intermed_int_val";
   314 val zmult_eq_self_iff = thm "zmult_eq_self_iff";
   443 val zmult_eq_self_iff = thm "zmult_eq_self_iff";
   315 val zless_1_zmult = thm "zless_1_zmult";
       
   316 val pos_zmult_eq_1_iff = thm "pos_zmult_eq_1_iff";
   444 val pos_zmult_eq_1_iff = thm "pos_zmult_eq_1_iff";
   317 val zmult_eq_1_iff = thm "zmult_eq_1_iff";
   445 val zmult_eq_1_iff = thm "zmult_eq_1_iff";
   318 val nat_add_distrib = thm "nat_add_distrib";
   446 val nat_add_distrib = thm "nat_add_distrib";
   319 val nat_diff_distrib = thm "nat_diff_distrib";
   447 val nat_diff_distrib = thm "nat_diff_distrib";
   320 val nat_mult_distrib = thm "nat_mult_distrib";
   448 val nat_mult_distrib = thm "nat_mult_distrib";