src/HOL/Integ/IntArith.thy
author obua
Tue, 11 May 2004 20:11:08 +0200
changeset 14738 83f1a514dcb4
parent 14479 0eca4aabf371
child 15003 6145dd7538d7
permissions -rw-r--r--
changes made due to new Ring_and_Field theory
     1 (*  Title:      HOL/Integ/IntArith.thy
     2     ID:         $Id$
     3     Authors:    Larry Paulson and Tobias Nipkow
     4 *)
     5 
     6 header {* Integer arithmetic *}
     7 
     8 theory IntArith = Bin
     9 files ("int_arith1.ML"):
    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 
    40 
    41 subsection{*Inequality Reasoning for the Arithmetic Simproc*}
    42 
    43 lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)"
    44 by simp 
    45 
    46 lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)"
    47 by simp
    48 
    49 lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)"
    50 by simp 
    51 
    52 lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)"
    53 by simp
    54 
    55 text{*Theorem lists for the cancellation simprocs. The use of binary numerals
    56 for 0 and 1 reduces the number of special cases.*}
    57 
    58 lemmas add_0s = add_numeral_0 add_numeral_0_right
    59 lemmas mult_1s = mult_numeral_1 mult_numeral_1_right 
    60                  mult_minus1 mult_minus1_right
    61 
    62 
    63 subsection{*Special Arithmetic Rules for Abstract 0 and 1*}
    64 
    65 text{*Arithmetic computations are defined for binary literals, which leaves 0
    66 and 1 as special cases. Addition already has rules for 0, but not 1.
    67 Multiplication and unary minus already have rules for both 0 and 1.*}
    68 
    69 
    70 lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'"
    71 by simp
    72 
    73 
    74 lemmas add_number_of_eq = number_of_add [symmetric]
    75 
    76 text{*Allow 1 on either or both sides*}
    77 lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)"
    78 by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq)
    79 
    80 lemmas add_special =
    81     one_add_one_is_two
    82     binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard]
    83     binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard]
    84 
    85 text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*}
    86 lemmas diff_special =
    87     binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard]
    88     binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard]
    89 
    90 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    91 lemmas eq_special =
    92     binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard]
    93     binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard]
    94     binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard]
    95     binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard]
    96 
    97 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    98 lemmas less_special =
    99   binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard]
   100   binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard]
   101   binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard]
   102   binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard]
   103 
   104 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
   105 lemmas le_special =
   106     binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard]
   107     binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard]
   108     binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard]
   109     binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard]
   110 
   111 lemmas arith_special = 
   112        add_special diff_special eq_special less_special le_special
   113 
   114 
   115 use "int_arith1.ML"
   116 setup int_arith_setup
   117 
   118 
   119 subsection{*Lemmas About Small Numerals*}
   120 
   121 lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)"
   122 proof -
   123   have "(of_int -1 :: 'a) = of_int (- 1)" by simp
   124   also have "... = - of_int 1" by (simp only: of_int_minus)
   125   also have "... = -1" by simp
   126   finally show ?thesis .
   127 qed
   128 
   129 lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_idom,number_ring})"
   130 by (simp add: abs_if)
   131 
   132 lemma abs_power_minus_one [simp]:
   133      "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring,ringpower})"
   134 by (simp add: power_abs)
   135 
   136 lemma of_int_number_of_eq:
   137      "of_int (number_of v) = (number_of v :: 'a :: number_ring)"
   138 apply (induct v)
   139 apply (simp_all only: number_of of_int_add, simp_all) 
   140 done
   141 
   142 text{*Lemmas for specialist use, NOT as default simprules*}
   143 lemma mult_2: "2 * z = (z+z::'a::number_ring)"
   144 proof -
   145   have "2*z = (1 + 1)*z" by simp
   146   also have "... = z+z" by (simp add: left_distrib)
   147   finally show ?thesis .
   148 qed
   149 
   150 lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)"
   151 by (subst mult_commute, rule mult_2)
   152 
   153 
   154 subsection{*More Inequality Reasoning*}
   155 
   156 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
   157 by arith
   158 
   159 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
   160 by arith
   161 
   162 lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<z)"
   163 by arith
   164 
   165 lemma zle_add1_eq_le [simp]: "(w < z + (1::int)) = (w\<le>z)"
   166 by arith
   167 
   168 lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
   169 by arith
   170 
   171 
   172 subsection{*The Functions @{term nat} and @{term int}*}
   173 
   174 text{*Simplify the terms @{term "int 0"}, @{term "int(Suc 0)"} and
   175   @{term "w + - z"}*}
   176 declare Zero_int_def [symmetric, simp]
   177 declare One_int_def [symmetric, simp]
   178 
   179 text{*cooper.ML refers to this theorem*}
   180 lemmas diff_int_def_symmetric = diff_int_def [symmetric, simp]
   181 
   182 lemma nat_0: "nat 0 = 0"
   183 by (simp add: nat_eq_iff)
   184 
   185 lemma nat_1: "nat 1 = Suc 0"
   186 by (subst nat_eq_iff, simp)
   187 
   188 lemma nat_2: "nat 2 = Suc (Suc 0)"
   189 by (subst nat_eq_iff, simp)
   190 
   191 text{*This simplifies expressions of the form @{term "int n = z"} where
   192       z is an integer literal.*}
   193 declare int_eq_iff [of _ "number_of v", standard, simp]
   194 
   195 lemma split_nat [arith_split]:
   196   "P(nat(i::int)) = ((\<forall>n. i = int n \<longrightarrow> P n) & (i < 0 \<longrightarrow> P 0))"
   197   (is "?P = (?L & ?R)")
   198 proof (cases "i < 0")
   199   case True thus ?thesis by simp
   200 next
   201   case False
   202   have "?P = ?L"
   203   proof
   204     assume ?P thus ?L using False by clarsimp
   205   next
   206     assume ?L thus ?P using False by simp
   207   qed
   208   with False show ?thesis by simp
   209 qed
   210 
   211 
   212 (*Analogous to zadd_int*)
   213 lemma zdiff_int: "n \<le> m ==> int m - int n = int (m-n)"
   214 by (induct m n rule: diff_induct, simp_all)
   215 
   216 lemma nat_mult_distrib: "(0::int) \<le> z ==> nat (z*z') = nat z * nat z'"
   217 apply (case_tac "0 \<le> z'")
   218 apply (rule inj_int [THEN injD])
   219 apply (simp add: zmult_int [symmetric] zero_le_mult_iff)
   220 apply (simp add: mult_le_0_iff)
   221 done
   222 
   223 lemma nat_mult_distrib_neg: "z \<le> (0::int) ==> nat(z*z') = nat(-z) * nat(-z')"
   224 apply (rule trans)
   225 apply (rule_tac [2] nat_mult_distrib, auto)
   226 done
   227 
   228 lemma nat_abs_mult_distrib: "nat (abs (w * z)) = nat (abs w) * nat (abs z)"
   229 apply (case_tac "z=0 | w=0")
   230 apply (auto simp add: zabs_def nat_mult_distrib [symmetric] 
   231                       nat_mult_distrib_neg [symmetric] mult_less_0_iff)
   232 done
   233 
   234 
   235 subsubsection "Induction principles for int"
   236 
   237                      (* `set:int': dummy construction *)
   238 theorem int_ge_induct[case_names base step,induct set:int]:
   239   assumes ge: "k \<le> (i::int)" and
   240         base: "P(k)" and
   241         step: "\<And>i. \<lbrakk>k \<le> i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   242   shows "P i"
   243 proof -
   244   { fix n have "\<And>i::int. n = nat(i-k) \<Longrightarrow> k \<le> i \<Longrightarrow> P i"
   245     proof (induct n)
   246       case 0
   247       hence "i = k" by arith
   248       thus "P i" using base by simp
   249     next
   250       case (Suc n)
   251       hence "n = nat((i - 1) - k)" by arith
   252       moreover
   253       have ki1: "k \<le> i - 1" using Suc.prems by arith
   254       ultimately
   255       have "P(i - 1)" by(rule Suc.hyps)
   256       from step[OF ki1 this] show ?case by simp
   257     qed
   258   }
   259   with ge show ?thesis by fast
   260 qed
   261 
   262                      (* `set:int': dummy construction *)
   263 theorem int_gr_induct[case_names base step,induct set:int]:
   264   assumes gr: "k < (i::int)" and
   265         base: "P(k+1)" and
   266         step: "\<And>i. \<lbrakk>k < i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   267   shows "P i"
   268 apply(rule int_ge_induct[of "k + 1"])
   269   using gr apply arith
   270  apply(rule base)
   271 apply (rule step, simp+)
   272 done
   273 
   274 theorem int_le_induct[consumes 1,case_names base step]:
   275   assumes le: "i \<le> (k::int)" and
   276         base: "P(k)" and
   277         step: "\<And>i. \<lbrakk>i \<le> k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   278   shows "P i"
   279 proof -
   280   { fix n have "\<And>i::int. n = nat(k-i) \<Longrightarrow> i \<le> k \<Longrightarrow> P i"
   281     proof (induct n)
   282       case 0
   283       hence "i = k" by arith
   284       thus "P i" using base by simp
   285     next
   286       case (Suc n)
   287       hence "n = nat(k - (i+1))" by arith
   288       moreover
   289       have ki1: "i + 1 \<le> k" using Suc.prems by arith
   290       ultimately
   291       have "P(i+1)" by(rule Suc.hyps)
   292       from step[OF ki1 this] show ?case by simp
   293     qed
   294   }
   295   with le show ?thesis by fast
   296 qed
   297 
   298 theorem int_less_induct [consumes 1,case_names base step]:
   299   assumes less: "(i::int) < k" and
   300         base: "P(k - 1)" and
   301         step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   302   shows "P i"
   303 apply(rule int_le_induct[of _ "k - 1"])
   304   using less apply arith
   305  apply(rule base)
   306 apply (rule step, simp+)
   307 done
   308 
   309 subsection{*Intermediate value theorems*}
   310 
   311 lemma int_val_lemma:
   312      "(\<forall>i<n::nat. abs(f(i+1) - f i) \<le> 1) -->  
   313       f 0 \<le> k --> k \<le> f n --> (\<exists>i \<le> n. f i = (k::int))"
   314 apply (induct_tac "n", simp)
   315 apply (intro strip)
   316 apply (erule impE, simp)
   317 apply (erule_tac x = n in allE, simp)
   318 apply (case_tac "k = f (n+1) ")
   319  apply force
   320 apply (erule impE)
   321  apply (simp add: zabs_def split add: split_if_asm)
   322 apply (blast intro: le_SucI)
   323 done
   324 
   325 lemmas nat0_intermed_int_val = int_val_lemma [rule_format (no_asm)]
   326 
   327 lemma nat_intermed_int_val:
   328      "[| \<forall>i. m \<le> i & i < n --> abs(f(i + 1::nat) - f i) \<le> 1; m < n;  
   329          f m \<le> k; k \<le> f n |] ==> ? i. m \<le> i & i \<le> n & f i = (k::int)"
   330 apply (cut_tac n = "n-m" and f = "%i. f (i+m) " and k = k 
   331        in int_val_lemma)
   332 apply simp
   333 apply (erule impE)
   334  apply (intro strip)
   335  apply (erule_tac x = "i+m" in allE, arith)
   336 apply (erule exE)
   337 apply (rule_tac x = "i+m" in exI, arith)
   338 done
   339 
   340 
   341 subsection{*Products and 1, by T. M. Rasmussen*}
   342 
   343 lemma zmult_eq_self_iff: "(m = m*(n::int)) = (n = 1 | m = 0)"
   344 apply auto
   345 apply (subgoal_tac "m*1 = m*n")
   346 apply (drule mult_cancel_left [THEN iffD1], auto)
   347 done
   348 
   349 text{*FIXME: tidy*}
   350 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
   351 apply auto
   352 apply (case_tac "m=1")
   353 apply (case_tac [2] "n=1")
   354 apply (case_tac [4] "m=1")
   355 apply (case_tac [5] "n=1", auto)
   356 apply (tactic"distinct_subgoals_tac")
   357 apply (subgoal_tac "1<m*n", simp)
   358 apply (rule less_1_mult, arith)
   359 apply (subgoal_tac "0<n", arith)
   360 apply (subgoal_tac "0<m*n")
   361 apply (drule zero_less_mult_iff [THEN iffD1], auto)
   362 done
   363 
   364 lemma zmult_eq_1_iff: "(m*n = (1::int)) = ((m = 1 & n = 1) | (m = -1 & n = -1))"
   365 apply (case_tac "0<m")
   366 apply (simp add: pos_zmult_eq_1_iff)
   367 apply (case_tac "m=0")
   368 apply (simp del: number_of_reorient)
   369 apply (subgoal_tac "0 < -m")
   370 apply (drule_tac n = "-n" in pos_zmult_eq_1_iff, auto)
   371 done
   372 
   373 
   374 
   375 ML
   376 {*
   377 val zle_diff1_eq = thm "zle_diff1_eq";
   378 val zle_add1_eq_le = thm "zle_add1_eq_le";
   379 val nonneg_eq_int = thm "nonneg_eq_int";
   380 val abs_minus_one = thm "abs_minus_one";
   381 val of_int_number_of_eq = thm"of_int_number_of_eq";
   382 val nat_eq_iff = thm "nat_eq_iff";
   383 val nat_eq_iff2 = thm "nat_eq_iff2";
   384 val nat_less_iff = thm "nat_less_iff";
   385 val int_eq_iff = thm "int_eq_iff";
   386 val nat_0 = thm "nat_0";
   387 val nat_1 = thm "nat_1";
   388 val nat_2 = thm "nat_2";
   389 val nat_less_eq_zless = thm "nat_less_eq_zless";
   390 val nat_le_eq_zle = thm "nat_le_eq_zle";
   391 
   392 val nat_intermed_int_val = thm "nat_intermed_int_val";
   393 val zmult_eq_self_iff = thm "zmult_eq_self_iff";
   394 val pos_zmult_eq_1_iff = thm "pos_zmult_eq_1_iff";
   395 val zmult_eq_1_iff = thm "zmult_eq_1_iff";
   396 val nat_add_distrib = thm "nat_add_distrib";
   397 val nat_diff_distrib = thm "nat_diff_distrib";
   398 val nat_mult_distrib = thm "nat_mult_distrib";
   399 val nat_mult_distrib_neg = thm "nat_mult_distrib_neg";
   400 val nat_abs_mult_distrib = thm "nat_abs_mult_distrib";
   401 *}
   402 
   403 end