moved Integ files to canonical place;
authorwenzelm
Thu May 31 18:16:52 2007 +0200 (2007-05-31)
changeset 2316469e55066dbca
parent 23163 eef345eff987
child 23165 5d319b0f8bf9
moved Integ files to canonical place;
src/HOL/IntArith.thy
src/HOL/IntDef.thy
src/HOL/IntDiv.thy
src/HOL/Integ/IntArith.thy
src/HOL/Integ/IntDef.thy
src/HOL/Integ/IntDiv.thy
src/HOL/Integ/NatBin.thy
src/HOL/Integ/NatSimprocs.thy
src/HOL/Integ/Numeral.thy
src/HOL/Integ/int_arith1.ML
src/HOL/Integ/int_factor_simprocs.ML
src/HOL/Integ/nat_simprocs.ML
src/HOL/IsaMakefile
src/HOL/NatBin.thy
src/HOL/NatSimprocs.thy
src/HOL/Numeral.thy
src/HOL/Presburger.thy
src/HOL/int_arith1.ML
src/HOL/int_factor_simprocs.ML
src/HOL/nat_simprocs.ML
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/HOL/IntArith.thy	Thu May 31 18:16:52 2007 +0200
     1.3 @@ -0,0 +1,411 @@
     1.4 +(*  Title:      HOL/IntArith.thy
     1.5 +    ID:         $Id$
     1.6 +    Authors:    Larry Paulson and Tobias Nipkow
     1.7 +*)
     1.8 +
     1.9 +header {* Integer arithmetic *}
    1.10 +
    1.11 +theory IntArith
    1.12 +imports Numeral Wellfounded_Relations
    1.13 +uses "~~/src/Provers/Arith/assoc_fold.ML" ("int_arith1.ML")
    1.14 +begin
    1.15 +
    1.16 +text{*Duplicate: can't understand why it's necessary*}
    1.17 +declare numeral_0_eq_0 [simp]
    1.18 +
    1.19 +
    1.20 +subsection{*Inequality Reasoning for the Arithmetic Simproc*}
    1.21 +
    1.22 +lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)"
    1.23 +by simp 
    1.24 +
    1.25 +lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)"
    1.26 +by simp
    1.27 +
    1.28 +lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)"
    1.29 +by simp 
    1.30 +
    1.31 +lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)"
    1.32 +by simp
    1.33 +
    1.34 +lemma divide_numeral_1: "a / Numeral1 = (a::'a::{number_ring,field})"
    1.35 +by simp
    1.36 +
    1.37 +lemma inverse_numeral_1:
    1.38 +  "inverse Numeral1 = (Numeral1::'a::{number_ring,field})"
    1.39 +by simp
    1.40 +
    1.41 +text{*Theorem lists for the cancellation simprocs. The use of binary numerals
    1.42 +for 0 and 1 reduces the number of special cases.*}
    1.43 +
    1.44 +lemmas add_0s = add_numeral_0 add_numeral_0_right
    1.45 +lemmas mult_1s = mult_numeral_1 mult_numeral_1_right 
    1.46 +                 mult_minus1 mult_minus1_right
    1.47 +
    1.48 +
    1.49 +subsection{*Special Arithmetic Rules for Abstract 0 and 1*}
    1.50 +
    1.51 +text{*Arithmetic computations are defined for binary literals, which leaves 0
    1.52 +and 1 as special cases. Addition already has rules for 0, but not 1.
    1.53 +Multiplication and unary minus already have rules for both 0 and 1.*}
    1.54 +
    1.55 +
    1.56 +lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'"
    1.57 +by simp
    1.58 +
    1.59 +
    1.60 +lemmas add_number_of_eq = number_of_add [symmetric]
    1.61 +
    1.62 +text{*Allow 1 on either or both sides*}
    1.63 +lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)"
    1.64 +by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq)
    1.65 +
    1.66 +lemmas add_special =
    1.67 +    one_add_one_is_two
    1.68 +    binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard]
    1.69 +    binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard]
    1.70 +
    1.71 +text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*}
    1.72 +lemmas diff_special =
    1.73 +    binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard]
    1.74 +    binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard]
    1.75 +
    1.76 +text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    1.77 +lemmas eq_special =
    1.78 +    binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard]
    1.79 +    binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard]
    1.80 +    binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard]
    1.81 +    binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard]
    1.82 +
    1.83 +text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    1.84 +lemmas less_special =
    1.85 +  binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard]
    1.86 +  binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard]
    1.87 +  binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard]
    1.88 +  binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard]
    1.89 +
    1.90 +text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    1.91 +lemmas le_special =
    1.92 +    binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard]
    1.93 +    binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard]
    1.94 +    binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard]
    1.95 +    binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard]
    1.96 +
    1.97 +lemmas arith_special[simp] = 
    1.98 +       add_special diff_special eq_special less_special le_special
    1.99 +
   1.100 +
   1.101 +lemma min_max_01: "min (0::int) 1 = 0 & min (1::int) 0 = 0 &
   1.102 +                   max (0::int) 1 = 1 & max (1::int) 0 = 1"
   1.103 +by(simp add:min_def max_def)
   1.104 +
   1.105 +lemmas min_max_special[simp] =
   1.106 + min_max_01
   1.107 + max_def[of "0::int" "number_of v", standard, simp]
   1.108 + min_def[of "0::int" "number_of v", standard, simp]
   1.109 + max_def[of "number_of u" "0::int", standard, simp]
   1.110 + min_def[of "number_of u" "0::int", standard, simp]
   1.111 + max_def[of "1::int" "number_of v", standard, simp]
   1.112 + min_def[of "1::int" "number_of v", standard, simp]
   1.113 + max_def[of "number_of u" "1::int", standard, simp]
   1.114 + min_def[of "number_of u" "1::int", standard, simp]
   1.115 +
   1.116 +use "int_arith1.ML"
   1.117 +setup int_arith_setup
   1.118 +
   1.119 +
   1.120 +subsection{*Lemmas About Small Numerals*}
   1.121 +
   1.122 +lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)"
   1.123 +proof -
   1.124 +  have "(of_int -1 :: 'a) = of_int (- 1)" by simp
   1.125 +  also have "... = - of_int 1" by (simp only: of_int_minus)
   1.126 +  also have "... = -1" by simp
   1.127 +  finally show ?thesis .
   1.128 +qed
   1.129 +
   1.130 +lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_idom,number_ring})"
   1.131 +by (simp add: abs_if)
   1.132 +
   1.133 +lemma abs_power_minus_one [simp]:
   1.134 +     "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring,recpower})"
   1.135 +by (simp add: power_abs)
   1.136 +
   1.137 +lemma of_int_number_of_eq:
   1.138 +     "of_int (number_of v) = (number_of v :: 'a :: number_ring)"
   1.139 +by (simp add: number_of_eq) 
   1.140 +
   1.141 +text{*Lemmas for specialist use, NOT as default simprules*}
   1.142 +lemma mult_2: "2 * z = (z+z::'a::number_ring)"
   1.143 +proof -
   1.144 +  have "2*z = (1 + 1)*z" by simp
   1.145 +  also have "... = z+z" by (simp add: left_distrib)
   1.146 +  finally show ?thesis .
   1.147 +qed
   1.148 +
   1.149 +lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)"
   1.150 +by (subst mult_commute, rule mult_2)
   1.151 +
   1.152 +
   1.153 +subsection{*More Inequality Reasoning*}
   1.154 +
   1.155 +lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
   1.156 +by arith
   1.157 +
   1.158 +lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
   1.159 +by arith
   1.160 +
   1.161 +lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<z)"
   1.162 +by arith
   1.163 +
   1.164 +lemma zle_add1_eq_le [simp]: "(w < z + (1::int)) = (w\<le>z)"
   1.165 +by arith
   1.166 +
   1.167 +lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
   1.168 +by arith
   1.169 +
   1.170 +
   1.171 +subsection{*The Functions @{term nat} and @{term int}*}
   1.172 +
   1.173 +text{*Simplify the terms @{term "int 0"}, @{term "int(Suc 0)"} and
   1.174 +  @{term "w + - z"}*}
   1.175 +declare Zero_int_def [symmetric, simp]
   1.176 +declare One_int_def [symmetric, simp]
   1.177 +
   1.178 +lemmas diff_int_def_symmetric = diff_int_def [symmetric, simp]
   1.179 +
   1.180 +lemma nat_0: "nat 0 = 0"
   1.181 +by (simp add: nat_eq_iff)
   1.182 +
   1.183 +lemma nat_1: "nat 1 = Suc 0"
   1.184 +by (subst nat_eq_iff, simp)
   1.185 +
   1.186 +lemma nat_2: "nat 2 = Suc (Suc 0)"
   1.187 +by (subst nat_eq_iff, simp)
   1.188 +
   1.189 +lemma one_less_nat_eq [simp]: "(Suc 0 < nat z) = (1 < z)"
   1.190 +apply (insert zless_nat_conj [of 1 z])
   1.191 +apply (auto simp add: nat_1)
   1.192 +done
   1.193 +
   1.194 +text{*This simplifies expressions of the form @{term "int n = z"} where
   1.195 +      z is an integer literal.*}
   1.196 +lemmas int_eq_iff_number_of [simp] = int_eq_iff [of _ "number_of v", standard]
   1.197 +
   1.198 +
   1.199 +lemma split_nat [arith_split]:
   1.200 +  "P(nat(i::int)) = ((\<forall>n. i = int n \<longrightarrow> P n) & (i < 0 \<longrightarrow> P 0))"
   1.201 +  (is "?P = (?L & ?R)")
   1.202 +proof (cases "i < 0")
   1.203 +  case True thus ?thesis by simp
   1.204 +next
   1.205 +  case False
   1.206 +  have "?P = ?L"
   1.207 +  proof
   1.208 +    assume ?P thus ?L using False by clarsimp
   1.209 +  next
   1.210 +    assume ?L thus ?P using False by simp
   1.211 +  qed
   1.212 +  with False show ?thesis by simp
   1.213 +qed
   1.214 +
   1.215 +
   1.216 +(*Analogous to zadd_int*)
   1.217 +lemma zdiff_int: "n \<le> m ==> int m - int n = int (m-n)" 
   1.218 +by (induct m n rule: diff_induct, simp_all)
   1.219 +
   1.220 +lemma nat_mult_distrib: "(0::int) \<le> z ==> nat (z*z') = nat z * nat z'"
   1.221 +apply (cases "0 \<le> z'")
   1.222 +apply (rule inj_int [THEN injD])
   1.223 +apply (simp add: int_mult zero_le_mult_iff)
   1.224 +apply (simp add: mult_le_0_iff)
   1.225 +done
   1.226 +
   1.227 +lemma nat_mult_distrib_neg: "z \<le> (0::int) ==> nat(z*z') = nat(-z) * nat(-z')"
   1.228 +apply (rule trans)
   1.229 +apply (rule_tac [2] nat_mult_distrib, auto)
   1.230 +done
   1.231 +
   1.232 +lemma nat_abs_mult_distrib: "nat (abs (w * z)) = nat (abs w) * nat (abs z)"
   1.233 +apply (cases "z=0 | w=0")
   1.234 +apply (auto simp add: abs_if nat_mult_distrib [symmetric] 
   1.235 +                      nat_mult_distrib_neg [symmetric] mult_less_0_iff)
   1.236 +done
   1.237 +
   1.238 +
   1.239 +subsection "Induction principles for int"
   1.240 +
   1.241 +text{*Well-founded segments of the integers*}
   1.242 +
   1.243 +definition
   1.244 +  int_ge_less_than  ::  "int => (int * int) set"
   1.245 +where
   1.246 +  "int_ge_less_than d = {(z',z). d \<le> z' & z' < z}"
   1.247 +
   1.248 +theorem wf_int_ge_less_than: "wf (int_ge_less_than d)"
   1.249 +proof -
   1.250 +  have "int_ge_less_than d \<subseteq> measure (%z. nat (z-d))"
   1.251 +    by (auto simp add: int_ge_less_than_def)
   1.252 +  thus ?thesis 
   1.253 +    by (rule wf_subset [OF wf_measure]) 
   1.254 +qed
   1.255 +
   1.256 +text{*This variant looks odd, but is typical of the relations suggested
   1.257 +by RankFinder.*}
   1.258 +
   1.259 +definition
   1.260 +  int_ge_less_than2 ::  "int => (int * int) set"
   1.261 +where
   1.262 +  "int_ge_less_than2 d = {(z',z). d \<le> z & z' < z}"
   1.263 +
   1.264 +theorem wf_int_ge_less_than2: "wf (int_ge_less_than2 d)"
   1.265 +proof -
   1.266 +  have "int_ge_less_than2 d \<subseteq> measure (%z. nat (1+z-d))" 
   1.267 +    by (auto simp add: int_ge_less_than2_def)
   1.268 +  thus ?thesis 
   1.269 +    by (rule wf_subset [OF wf_measure]) 
   1.270 +qed
   1.271 +
   1.272 +                     (* `set:int': dummy construction *)
   1.273 +theorem int_ge_induct[case_names base step,induct set:int]:
   1.274 +  assumes ge: "k \<le> (i::int)" and
   1.275 +        base: "P(k)" and
   1.276 +        step: "\<And>i. \<lbrakk>k \<le> i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   1.277 +  shows "P i"
   1.278 +proof -
   1.279 +  { fix n have "\<And>i::int. n = nat(i-k) \<Longrightarrow> k \<le> i \<Longrightarrow> P i"
   1.280 +    proof (induct n)
   1.281 +      case 0
   1.282 +      hence "i = k" by arith
   1.283 +      thus "P i" using base by simp
   1.284 +    next
   1.285 +      case (Suc n)
   1.286 +      hence "n = nat((i - 1) - k)" by arith
   1.287 +      moreover
   1.288 +      have ki1: "k \<le> i - 1" using Suc.prems by arith
   1.289 +      ultimately
   1.290 +      have "P(i - 1)" by(rule Suc.hyps)
   1.291 +      from step[OF ki1 this] show ?case by simp
   1.292 +    qed
   1.293 +  }
   1.294 +  with ge show ?thesis by fast
   1.295 +qed
   1.296 +
   1.297 +                     (* `set:int': dummy construction *)
   1.298 +theorem int_gr_induct[case_names base step,induct set:int]:
   1.299 +  assumes gr: "k < (i::int)" and
   1.300 +        base: "P(k+1)" and
   1.301 +        step: "\<And>i. \<lbrakk>k < i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   1.302 +  shows "P i"
   1.303 +apply(rule int_ge_induct[of "k + 1"])
   1.304 +  using gr apply arith
   1.305 + apply(rule base)
   1.306 +apply (rule step, simp+)
   1.307 +done
   1.308 +
   1.309 +theorem int_le_induct[consumes 1,case_names base step]:
   1.310 +  assumes le: "i \<le> (k::int)" and
   1.311 +        base: "P(k)" and
   1.312 +        step: "\<And>i. \<lbrakk>i \<le> k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   1.313 +  shows "P i"
   1.314 +proof -
   1.315 +  { fix n have "\<And>i::int. n = nat(k-i) \<Longrightarrow> i \<le> k \<Longrightarrow> P i"
   1.316 +    proof (induct n)
   1.317 +      case 0
   1.318 +      hence "i = k" by arith
   1.319 +      thus "P i" using base by simp
   1.320 +    next
   1.321 +      case (Suc n)
   1.322 +      hence "n = nat(k - (i+1))" by arith
   1.323 +      moreover
   1.324 +      have ki1: "i + 1 \<le> k" using Suc.prems by arith
   1.325 +      ultimately
   1.326 +      have "P(i+1)" by(rule Suc.hyps)
   1.327 +      from step[OF ki1 this] show ?case by simp
   1.328 +    qed
   1.329 +  }
   1.330 +  with le show ?thesis by fast
   1.331 +qed
   1.332 +
   1.333 +theorem int_less_induct [consumes 1,case_names base step]:
   1.334 +  assumes less: "(i::int) < k" and
   1.335 +        base: "P(k - 1)" and
   1.336 +        step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   1.337 +  shows "P i"
   1.338 +apply(rule int_le_induct[of _ "k - 1"])
   1.339 +  using less apply arith
   1.340 + apply(rule base)
   1.341 +apply (rule step, simp+)
   1.342 +done
   1.343 +
   1.344 +subsection{*Intermediate value theorems*}
   1.345 +
   1.346 +lemma int_val_lemma:
   1.347 +     "(\<forall>i<n::nat. abs(f(i+1) - f i) \<le> 1) -->  
   1.348 +      f 0 \<le> k --> k \<le> f n --> (\<exists>i \<le> n. f i = (k::int))"
   1.349 +apply (induct_tac "n", simp)
   1.350 +apply (intro strip)
   1.351 +apply (erule impE, simp)
   1.352 +apply (erule_tac x = n in allE, simp)
   1.353 +apply (case_tac "k = f (n+1) ")
   1.354 + apply force
   1.355 +apply (erule impE)
   1.356 + apply (simp add: abs_if split add: split_if_asm)
   1.357 +apply (blast intro: le_SucI)
   1.358 +done
   1.359 +
   1.360 +lemmas nat0_intermed_int_val = int_val_lemma [rule_format (no_asm)]
   1.361 +
   1.362 +lemma nat_intermed_int_val:
   1.363 +     "[| \<forall>i. m \<le> i & i < n --> abs(f(i + 1::nat) - f i) \<le> 1; m < n;  
   1.364 +         f m \<le> k; k \<le> f n |] ==> ? i. m \<le> i & i \<le> n & f i = (k::int)"
   1.365 +apply (cut_tac n = "n-m" and f = "%i. f (i+m) " and k = k 
   1.366 +       in int_val_lemma)
   1.367 +apply simp
   1.368 +apply (erule exE)
   1.369 +apply (rule_tac x = "i+m" in exI, arith)
   1.370 +done
   1.371 +
   1.372 +
   1.373 +subsection{*Products and 1, by T. M. Rasmussen*}
   1.374 +
   1.375 +lemma zabs_less_one_iff [simp]: "(\<bar>z\<bar> < 1) = (z = (0::int))"
   1.376 +by arith
   1.377 +
   1.378 +lemma abs_zmult_eq_1: "(\<bar>m * n\<bar> = 1) ==> \<bar>m\<bar> = (1::int)"
   1.379 +apply (cases "\<bar>n\<bar>=1") 
   1.380 +apply (simp add: abs_mult) 
   1.381 +apply (rule ccontr) 
   1.382 +apply (auto simp add: linorder_neq_iff abs_mult) 
   1.383 +apply (subgoal_tac "2 \<le> \<bar>m\<bar> & 2 \<le> \<bar>n\<bar>")
   1.384 + prefer 2 apply arith 
   1.385 +apply (subgoal_tac "2*2 \<le> \<bar>m\<bar> * \<bar>n\<bar>", simp) 
   1.386 +apply (rule mult_mono, auto) 
   1.387 +done
   1.388 +
   1.389 +lemma pos_zmult_eq_1_iff_lemma: "(m * n = 1) ==> m = (1::int) | m = -1"
   1.390 +by (insert abs_zmult_eq_1 [of m n], arith)
   1.391 +
   1.392 +lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
   1.393 +apply (auto dest: pos_zmult_eq_1_iff_lemma) 
   1.394 +apply (simp add: mult_commute [of m]) 
   1.395 +apply (frule pos_zmult_eq_1_iff_lemma, auto) 
   1.396 +done
   1.397 +
   1.398 +lemma zmult_eq_1_iff: "(m*n = (1::int)) = ((m = 1 & n = 1) | (m = -1 & n = -1))"
   1.399 +apply (rule iffI) 
   1.400 + apply (frule pos_zmult_eq_1_iff_lemma)
   1.401 + apply (simp add: mult_commute [of m]) 
   1.402 + apply (frule pos_zmult_eq_1_iff_lemma, auto) 
   1.403 +done
   1.404 +
   1.405 +
   1.406 +subsection {* Legacy ML bindings *}
   1.407 +
   1.408 +ML {*
   1.409 +val of_int_number_of_eq = @{thm of_int_number_of_eq};
   1.410 +val nat_0 = @{thm nat_0};
   1.411 +val nat_1 = @{thm nat_1};
   1.412 +*}
   1.413 +
   1.414 +end
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/HOL/IntDef.thy	Thu May 31 18:16:52 2007 +0200
     2.3 @@ -0,0 +1,890 @@
     2.4 +(*  Title:      IntDef.thy
     2.5 +    ID:         $Id$
     2.6 +    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     2.7 +    Copyright   1996  University of Cambridge
     2.8 +
     2.9 +*)
    2.10 +
    2.11 +header{*The Integers as Equivalence Classes over Pairs of Natural Numbers*} 
    2.12 +
    2.13 +theory IntDef
    2.14 +imports Equiv_Relations Nat
    2.15 +begin
    2.16 +
    2.17 +text {* the equivalence relation underlying the integers *}
    2.18 +
    2.19 +definition
    2.20 +  intrel :: "((nat \<times> nat) \<times> (nat \<times> nat)) set"
    2.21 +where
    2.22 +  "intrel = {((x, y), (u, v)) | x y u v. x + v = u +y }"
    2.23 +
    2.24 +typedef (Integ)
    2.25 +  int = "UNIV//intrel"
    2.26 +  by (auto simp add: quotient_def)
    2.27 +
    2.28 +definition
    2.29 +  int :: "nat \<Rightarrow> int"
    2.30 +where
    2.31 +  [code func del]: "int m = Abs_Integ (intrel `` {(m, 0)})"
    2.32 +
    2.33 +instance int :: zero
    2.34 +  Zero_int_def: "0 \<equiv> int 0" ..
    2.35 +
    2.36 +instance int :: one
    2.37 +  One_int_def: "1 \<equiv> int 1" ..
    2.38 +
    2.39 +instance int :: plus
    2.40 +  add_int_def: "z + w \<equiv> Abs_Integ
    2.41 +    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u, v) \<in> Rep_Integ w.
    2.42 +      intrel `` {(x + u, y + v)})" ..
    2.43 +
    2.44 +instance int :: minus
    2.45 +  minus_int_def:
    2.46 +    "- z \<equiv> Abs_Integ (\<Union>(x, y) \<in> Rep_Integ z. intrel `` {(y, x)})"
    2.47 +  diff_int_def:  "z - w \<equiv> z + (-w)" ..
    2.48 +
    2.49 +instance int :: times
    2.50 +  mult_int_def: "z * w \<equiv>  Abs_Integ
    2.51 +    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u,v ) \<in> Rep_Integ w.
    2.52 +      intrel `` {(x*u + y*v, x*v + y*u)})" ..
    2.53 +
    2.54 +instance int :: ord
    2.55 +  le_int_def:
    2.56 +   "z \<le> w \<equiv> \<exists>x y u v. x+v \<le> u+y \<and> (x, y) \<in> Rep_Integ z \<and> (u, v) \<in> Rep_Integ w"
    2.57 +  less_int_def: "z < w \<equiv> z \<le> w \<and> z \<noteq> w" ..
    2.58 +
    2.59 +lemmas [code func del] = Zero_int_def One_int_def add_int_def
    2.60 +  minus_int_def mult_int_def le_int_def less_int_def
    2.61 +
    2.62 +
    2.63 +subsection{*Construction of the Integers*}
    2.64 +
    2.65 +subsubsection{*Preliminary Lemmas about the Equivalence Relation*}
    2.66 +
    2.67 +lemma intrel_iff [simp]: "(((x,y),(u,v)) \<in> intrel) = (x+v = u+y)"
    2.68 +by (simp add: intrel_def)
    2.69 +
    2.70 +lemma equiv_intrel: "equiv UNIV intrel"
    2.71 +by (simp add: intrel_def equiv_def refl_def sym_def trans_def)
    2.72 +
    2.73 +text{*Reduces equality of equivalence classes to the @{term intrel} relation:
    2.74 +  @{term "(intrel `` {x} = intrel `` {y}) = ((x,y) \<in> intrel)"} *}
    2.75 +lemmas equiv_intrel_iff [simp] = eq_equiv_class_iff [OF equiv_intrel UNIV_I UNIV_I]
    2.76 +
    2.77 +text{*All equivalence classes belong to set of representatives*}
    2.78 +lemma [simp]: "intrel``{(x,y)} \<in> Integ"
    2.79 +by (auto simp add: Integ_def intrel_def quotient_def)
    2.80 +
    2.81 +text{*Reduces equality on abstractions to equality on representatives:
    2.82 +  @{prop "\<lbrakk>x \<in> Integ; y \<in> Integ\<rbrakk> \<Longrightarrow> (Abs_Integ x = Abs_Integ y) = (x=y)"} *}
    2.83 +declare Abs_Integ_inject [simp]  Abs_Integ_inverse [simp]
    2.84 +
    2.85 +text{*Case analysis on the representation of an integer as an equivalence
    2.86 +      class of pairs of naturals.*}
    2.87 +lemma eq_Abs_Integ [case_names Abs_Integ, cases type: int]:
    2.88 +     "(!!x y. z = Abs_Integ(intrel``{(x,y)}) ==> P) ==> P"
    2.89 +apply (rule Abs_Integ_cases [of z]) 
    2.90 +apply (auto simp add: Integ_def quotient_def) 
    2.91 +done
    2.92 +
    2.93 +
    2.94 +subsubsection{*@{term int}: Embedding the Naturals into the Integers*}
    2.95 +
    2.96 +lemma inj_int: "inj int"
    2.97 +by (simp add: inj_on_def int_def)
    2.98 +
    2.99 +lemma int_int_eq [iff]: "(int m = int n) = (m = n)"
   2.100 +by (fast elim!: inj_int [THEN injD])
   2.101 +
   2.102 +
   2.103 +subsubsection{*Integer Unary Negation*}
   2.104 +
   2.105 +lemma minus: "- Abs_Integ(intrel``{(x,y)}) = Abs_Integ(intrel `` {(y,x)})"
   2.106 +proof -
   2.107 +  have "(\<lambda>(x,y). intrel``{(y,x)}) respects intrel"
   2.108 +    by (simp add: congruent_def) 
   2.109 +  thus ?thesis
   2.110 +    by (simp add: minus_int_def UN_equiv_class [OF equiv_intrel])
   2.111 +qed
   2.112 +
   2.113 +lemma zminus_zminus: "- (- z) = (z::int)"
   2.114 +  by (cases z) (simp add: minus)
   2.115 +
   2.116 +lemma zminus_0: "- 0 = (0::int)"
   2.117 +  by (simp add: int_def Zero_int_def minus)
   2.118 +
   2.119 +
   2.120 +subsection{*Integer Addition*}
   2.121 +
   2.122 +lemma add:
   2.123 +     "Abs_Integ (intrel``{(x,y)}) + Abs_Integ (intrel``{(u,v)}) =
   2.124 +      Abs_Integ (intrel``{(x+u, y+v)})"
   2.125 +proof -
   2.126 +  have "(\<lambda>z w. (\<lambda>(x,y). (\<lambda>(u,v). intrel `` {(x+u, y+v)}) w) z) 
   2.127 +        respects2 intrel"
   2.128 +    by (simp add: congruent2_def)
   2.129 +  thus ?thesis
   2.130 +    by (simp add: add_int_def UN_UN_split_split_eq
   2.131 +                  UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   2.132 +qed
   2.133 +
   2.134 +lemma zminus_zadd_distrib: "- (z + w) = (- z) + (- w::int)"
   2.135 +  by (cases z, cases w) (simp add: minus add)
   2.136 +
   2.137 +lemma zadd_commute: "(z::int) + w = w + z"
   2.138 +  by (cases z, cases w) (simp add: add_ac add)
   2.139 +
   2.140 +lemma zadd_assoc: "((z1::int) + z2) + z3 = z1 + (z2 + z3)"
   2.141 +  by (cases z1, cases z2, cases z3) (simp add: add add_assoc)
   2.142 +
   2.143 +(*For AC rewriting*)
   2.144 +lemma zadd_left_commute: "x + (y + z) = y + ((x + z)  ::int)"
   2.145 +  apply (rule mk_left_commute [of "op +"])
   2.146 +  apply (rule zadd_assoc)
   2.147 +  apply (rule zadd_commute)
   2.148 +  done
   2.149 +
   2.150 +lemmas zadd_ac = zadd_assoc zadd_commute zadd_left_commute
   2.151 +
   2.152 +lemmas zmult_ac = OrderedGroup.mult_ac
   2.153 +
   2.154 +lemma zadd_int: "(int m) + (int n) = int (m + n)"
   2.155 +  by (simp add: int_def add)
   2.156 +
   2.157 +lemma zadd_int_left: "(int m) + (int n + z) = int (m + n) + z"
   2.158 +  by (simp add: zadd_int zadd_assoc [symmetric])
   2.159 +
   2.160 +(*also for the instance declaration int :: comm_monoid_add*)
   2.161 +lemma zadd_0: "(0::int) + z = z"
   2.162 +apply (simp add: Zero_int_def int_def)
   2.163 +apply (cases z, simp add: add)
   2.164 +done
   2.165 +
   2.166 +lemma zadd_0_right: "z + (0::int) = z"
   2.167 +by (rule trans [OF zadd_commute zadd_0])
   2.168 +
   2.169 +lemma zadd_zminus_inverse2: "(- z) + z = (0::int)"
   2.170 +by (cases z, simp add: int_def Zero_int_def minus add)
   2.171 +
   2.172 +
   2.173 +subsection{*Integer Multiplication*}
   2.174 +
   2.175 +text{*Congruence property for multiplication*}
   2.176 +lemma mult_congruent2:
   2.177 +     "(%p1 p2. (%(x,y). (%(u,v). intrel``{(x*u + y*v, x*v + y*u)}) p2) p1)
   2.178 +      respects2 intrel"
   2.179 +apply (rule equiv_intrel [THEN congruent2_commuteI])
   2.180 + apply (force simp add: mult_ac, clarify) 
   2.181 +apply (simp add: congruent_def mult_ac)  
   2.182 +apply (rename_tac u v w x y z)
   2.183 +apply (subgoal_tac "u*y + x*y = w*y + v*y  &  u*z + x*z = w*z + v*z")
   2.184 +apply (simp add: mult_ac)
   2.185 +apply (simp add: add_mult_distrib [symmetric])
   2.186 +done
   2.187 +
   2.188 +
   2.189 +lemma mult:
   2.190 +     "Abs_Integ((intrel``{(x,y)})) * Abs_Integ((intrel``{(u,v)})) =
   2.191 +      Abs_Integ(intrel `` {(x*u + y*v, x*v + y*u)})"
   2.192 +by (simp add: mult_int_def UN_UN_split_split_eq mult_congruent2
   2.193 +              UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   2.194 +
   2.195 +lemma zmult_zminus: "(- z) * w = - (z * (w::int))"
   2.196 +by (cases z, cases w, simp add: minus mult add_ac)
   2.197 +
   2.198 +lemma zmult_commute: "(z::int) * w = w * z"
   2.199 +by (cases z, cases w, simp add: mult add_ac mult_ac)
   2.200 +
   2.201 +lemma zmult_assoc: "((z1::int) * z2) * z3 = z1 * (z2 * z3)"
   2.202 +by (cases z1, cases z2, cases z3, simp add: mult add_mult_distrib2 mult_ac)
   2.203 +
   2.204 +lemma zadd_zmult_distrib: "((z1::int) + z2) * w = (z1 * w) + (z2 * w)"
   2.205 +by (cases z1, cases z2, cases w, simp add: add mult add_mult_distrib2 mult_ac)
   2.206 +
   2.207 +lemma zadd_zmult_distrib2: "(w::int) * (z1 + z2) = (w * z1) + (w * z2)"
   2.208 +by (simp add: zmult_commute [of w] zadd_zmult_distrib)
   2.209 +
   2.210 +lemma zdiff_zmult_distrib: "((z1::int) - z2) * w = (z1 * w) - (z2 * w)"
   2.211 +by (simp add: diff_int_def zadd_zmult_distrib zmult_zminus)
   2.212 +
   2.213 +lemma zdiff_zmult_distrib2: "(w::int) * (z1 - z2) = (w * z1) - (w * z2)"
   2.214 +by (simp add: zmult_commute [of w] zdiff_zmult_distrib)
   2.215 +
   2.216 +lemmas int_distrib =
   2.217 +  zadd_zmult_distrib zadd_zmult_distrib2
   2.218 +  zdiff_zmult_distrib zdiff_zmult_distrib2
   2.219 +
   2.220 +lemma int_mult: "int (m * n) = (int m) * (int n)"
   2.221 +by (simp add: int_def mult)
   2.222 +
   2.223 +text{*Compatibility binding*}
   2.224 +lemmas zmult_int = int_mult [symmetric]
   2.225 +
   2.226 +lemma zmult_1: "(1::int) * z = z"
   2.227 +by (cases z, simp add: One_int_def int_def mult)
   2.228 +
   2.229 +lemma zmult_1_right: "z * (1::int) = z"
   2.230 +by (rule trans [OF zmult_commute zmult_1])
   2.231 +
   2.232 +
   2.233 +text{*The integers form a @{text comm_ring_1}*}
   2.234 +instance int :: comm_ring_1
   2.235 +proof
   2.236 +  fix i j k :: int
   2.237 +  show "(i + j) + k = i + (j + k)" by (simp add: zadd_assoc)
   2.238 +  show "i + j = j + i" by (simp add: zadd_commute)
   2.239 +  show "0 + i = i" by (rule zadd_0)
   2.240 +  show "- i + i = 0" by (rule zadd_zminus_inverse2)
   2.241 +  show "i - j = i + (-j)" by (simp add: diff_int_def)
   2.242 +  show "(i * j) * k = i * (j * k)" by (rule zmult_assoc)
   2.243 +  show "i * j = j * i" by (rule zmult_commute)
   2.244 +  show "1 * i = i" by (rule zmult_1) 
   2.245 +  show "(i + j) * k = i * k + j * k" by (simp add: int_distrib)
   2.246 +  show "0 \<noteq> (1::int)"
   2.247 +    by (simp only: Zero_int_def One_int_def One_nat_def int_int_eq)
   2.248 +qed
   2.249 +
   2.250 +
   2.251 +subsection{*The @{text "\<le>"} Ordering*}
   2.252 +
   2.253 +lemma le:
   2.254 +  "(Abs_Integ(intrel``{(x,y)}) \<le> Abs_Integ(intrel``{(u,v)})) = (x+v \<le> u+y)"
   2.255 +by (force simp add: le_int_def)
   2.256 +
   2.257 +lemma zle_refl: "w \<le> (w::int)"
   2.258 +by (cases w, simp add: le)
   2.259 +
   2.260 +lemma zle_trans: "[| i \<le> j; j \<le> k |] ==> i \<le> (k::int)"
   2.261 +by (cases i, cases j, cases k, simp add: le)
   2.262 +
   2.263 +lemma zle_anti_sym: "[| z \<le> w; w \<le> z |] ==> z = (w::int)"
   2.264 +by (cases w, cases z, simp add: le)
   2.265 +
   2.266 +instance int :: order
   2.267 +  by intro_classes
   2.268 +    (assumption |
   2.269 +      rule zle_refl zle_trans zle_anti_sym less_int_def [THEN meta_eq_to_obj_eq])+
   2.270 +
   2.271 +lemma zle_linear: "(z::int) \<le> w \<or> w \<le> z"
   2.272 +by (cases z, cases w) (simp add: le linorder_linear)
   2.273 +
   2.274 +instance int :: linorder
   2.275 +  by intro_classes (rule zle_linear)
   2.276 +
   2.277 +lemmas zless_linear = linorder_less_linear [where 'a = int]
   2.278 +
   2.279 +
   2.280 +lemma int_eq_0_conv [simp]: "(int n = 0) = (n = 0)"
   2.281 +by (simp add: Zero_int_def)
   2.282 +
   2.283 +lemma zless_int [simp]: "(int m < int n) = (m<n)"
   2.284 +by (simp add: le add int_def linorder_not_le [symmetric]) 
   2.285 +
   2.286 +lemma int_less_0_conv [simp]: "~ (int k < 0)"
   2.287 +by (simp add: Zero_int_def)
   2.288 +
   2.289 +lemma zero_less_int_conv [simp]: "(0 < int n) = (0 < n)"
   2.290 +by (simp add: Zero_int_def)
   2.291 +
   2.292 +lemma int_0_less_1: "0 < (1::int)"
   2.293 +by (simp only: Zero_int_def One_int_def One_nat_def zless_int)
   2.294 +
   2.295 +lemma int_0_neq_1 [simp]: "0 \<noteq> (1::int)"
   2.296 +by (simp only: Zero_int_def One_int_def One_nat_def int_int_eq)
   2.297 +
   2.298 +lemma zle_int [simp]: "(int m \<le> int n) = (m\<le>n)"
   2.299 +by (simp add: linorder_not_less [symmetric])
   2.300 +
   2.301 +lemma zero_zle_int [simp]: "(0 \<le> int n)"
   2.302 +by (simp add: Zero_int_def)
   2.303 +
   2.304 +lemma int_le_0_conv [simp]: "(int n \<le> 0) = (n = 0)"
   2.305 +by (simp add: Zero_int_def)
   2.306 +
   2.307 +lemma int_0 [simp]: "int 0 = (0::int)"
   2.308 +by (simp add: Zero_int_def)
   2.309 +
   2.310 +lemma int_1 [simp]: "int 1 = 1"
   2.311 +by (simp add: One_int_def)
   2.312 +
   2.313 +lemma int_Suc0_eq_1: "int (Suc 0) = 1"
   2.314 +by (simp add: One_int_def One_nat_def)
   2.315 +
   2.316 +lemma int_Suc: "int (Suc m) = 1 + (int m)"
   2.317 +by (simp add: One_int_def zadd_int)
   2.318 +
   2.319 +
   2.320 +subsection{*Monotonicity results*}
   2.321 +
   2.322 +lemma zadd_left_mono: "i \<le> j ==> k + i \<le> k + (j::int)"
   2.323 +by (cases i, cases j, cases k, simp add: le add)
   2.324 +
   2.325 +lemma zadd_strict_right_mono: "i < j ==> i + k < j + (k::int)"
   2.326 +apply (cases i, cases j, cases k)
   2.327 +apply (simp add: linorder_not_le [where 'a = int, symmetric]
   2.328 +                 linorder_not_le [where 'a = nat]  le add)
   2.329 +done
   2.330 +
   2.331 +lemma zadd_zless_mono: "[| w'<w; z'\<le>z |] ==> w' + z' < w + (z::int)"
   2.332 +by (rule order_less_le_trans [OF zadd_strict_right_mono zadd_left_mono])
   2.333 +
   2.334 +
   2.335 +subsection{*Strict Monotonicity of Multiplication*}
   2.336 +
   2.337 +text{*strict, in 1st argument; proof is by induction on k>0*}
   2.338 +lemma zmult_zless_mono2_lemma:
   2.339 +     "i<j ==> 0<k ==> int k * i < int k * j"
   2.340 +apply (induct "k", simp)
   2.341 +apply (simp add: int_Suc)
   2.342 +apply (case_tac "k=0")
   2.343 +apply (simp_all add: zadd_zmult_distrib int_Suc0_eq_1 order_le_less)
   2.344 +apply (simp add: zadd_zless_mono int_Suc0_eq_1 order_le_less)
   2.345 +done
   2.346 +
   2.347 +lemma zero_le_imp_eq_int: "0 \<le> k ==> \<exists>n. k = int n"
   2.348 +apply (cases k)
   2.349 +apply (auto simp add: le add int_def Zero_int_def)
   2.350 +apply (rule_tac x="x-y" in exI, simp)
   2.351 +done
   2.352 +
   2.353 +lemma zmult_zless_mono2: "[| i<j;  (0::int) < k |] ==> k*i < k*j"
   2.354 +apply (frule order_less_imp_le [THEN zero_le_imp_eq_int])
   2.355 +apply (auto simp add: zmult_zless_mono2_lemma)
   2.356 +done
   2.357 +
   2.358 +instance int :: minus
   2.359 +  zabs_def: "\<bar>i\<Colon>int\<bar> \<equiv> if i < 0 then - i else i" ..
   2.360 +
   2.361 +instance int :: distrib_lattice
   2.362 +  "inf \<equiv> min"
   2.363 +  "sup \<equiv> max"
   2.364 +  by intro_classes
   2.365 +    (auto simp add: inf_int_def sup_int_def min_max.sup_inf_distrib1)
   2.366 +
   2.367 +text{*The integers form an ordered @{text comm_ring_1}*}
   2.368 +instance int :: ordered_idom
   2.369 +proof
   2.370 +  fix i j k :: int
   2.371 +  show "i \<le> j ==> k + i \<le> k + j" by (rule zadd_left_mono)
   2.372 +  show "i < j ==> 0 < k ==> k * i < k * j" by (rule zmult_zless_mono2)
   2.373 +  show "\<bar>i\<bar> = (if i < 0 then -i else i)" by (simp only: zabs_def)
   2.374 +qed
   2.375 +
   2.376 +lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z"
   2.377 +apply (cases w, cases z) 
   2.378 +apply (simp add: linorder_not_le [symmetric] le int_def add One_int_def)
   2.379 +done
   2.380 +
   2.381 +subsection{*Magnitide of an Integer, as a Natural Number: @{term nat}*}
   2.382 +
   2.383 +definition
   2.384 +  nat :: "int \<Rightarrow> nat"
   2.385 +where
   2.386 +  [code func del]: "nat z = contents (\<Union>(x, y) \<in> Rep_Integ z. {x-y})"
   2.387 +
   2.388 +lemma nat: "nat (Abs_Integ (intrel``{(x,y)})) = x-y"
   2.389 +proof -
   2.390 +  have "(\<lambda>(x,y). {x-y}) respects intrel"
   2.391 +    by (simp add: congruent_def) arith
   2.392 +  thus ?thesis
   2.393 +    by (simp add: nat_def UN_equiv_class [OF equiv_intrel])
   2.394 +qed
   2.395 +
   2.396 +lemma nat_int [simp]: "nat(int n) = n"
   2.397 +by (simp add: nat int_def) 
   2.398 +
   2.399 +lemma nat_zero [simp]: "nat 0 = 0"
   2.400 +by (simp only: Zero_int_def nat_int)
   2.401 +
   2.402 +lemma int_nat_eq [simp]: "int (nat z) = (if 0 \<le> z then z else 0)"
   2.403 +by (cases z, simp add: nat le int_def Zero_int_def)
   2.404 +
   2.405 +corollary nat_0_le: "0 \<le> z ==> int (nat z) = z"
   2.406 +by simp
   2.407 +
   2.408 +lemma nat_le_0 [simp]: "z \<le> 0 ==> nat z = 0"
   2.409 +by (cases z, simp add: nat le int_def Zero_int_def)
   2.410 +
   2.411 +lemma nat_le_eq_zle: "0 < w | 0 \<le> z ==> (nat w \<le> nat z) = (w\<le>z)"
   2.412 +apply (cases w, cases z) 
   2.413 +apply (simp add: nat le linorder_not_le [symmetric] int_def Zero_int_def, arith)
   2.414 +done
   2.415 +
   2.416 +text{*An alternative condition is @{term "0 \<le> w"} *}
   2.417 +corollary nat_mono_iff: "0 < z ==> (nat w < nat z) = (w < z)"
   2.418 +by (simp add: nat_le_eq_zle linorder_not_le [symmetric]) 
   2.419 +
   2.420 +corollary nat_less_eq_zless: "0 \<le> w ==> (nat w < nat z) = (w<z)"
   2.421 +by (simp add: nat_le_eq_zle linorder_not_le [symmetric]) 
   2.422 +
   2.423 +lemma zless_nat_conj: "(nat w < nat z) = (0 < z & w < z)"
   2.424 +apply (cases w, cases z) 
   2.425 +apply (simp add: nat le int_def Zero_int_def linorder_not_le [symmetric], arith)
   2.426 +done
   2.427 +
   2.428 +lemma nonneg_eq_int: "[| 0 \<le> z;  !!m. z = int m ==> P |] ==> P"
   2.429 +by (blast dest: nat_0_le sym)
   2.430 +
   2.431 +lemma nat_eq_iff: "(nat w = m) = (if 0 \<le> w then w = int m else m=0)"
   2.432 +by (cases w, simp add: nat le int_def Zero_int_def, arith)
   2.433 +
   2.434 +corollary nat_eq_iff2: "(m = nat w) = (if 0 \<le> w then w = int m else m=0)"
   2.435 +by (simp only: eq_commute [of m] nat_eq_iff) 
   2.436 +
   2.437 +lemma nat_less_iff: "0 \<le> w ==> (nat w < m) = (w < int m)"
   2.438 +apply (cases w)
   2.439 +apply (simp add: nat le int_def Zero_int_def linorder_not_le [symmetric], arith)
   2.440 +done
   2.441 +
   2.442 +lemma int_eq_iff: "(int m = z) = (m = nat z & 0 \<le> z)"
   2.443 +by (auto simp add: nat_eq_iff2)
   2.444 +
   2.445 +lemma zero_less_nat_eq [simp]: "(0 < nat z) = (0 < z)"
   2.446 +by (insert zless_nat_conj [of 0], auto)
   2.447 +
   2.448 +lemma nat_add_distrib:
   2.449 +     "[| (0::int) \<le> z;  0 \<le> z' |] ==> nat (z+z') = nat z + nat z'"
   2.450 +by (cases z, cases z', simp add: nat add le int_def Zero_int_def)
   2.451 +
   2.452 +lemma nat_diff_distrib:
   2.453 +     "[| (0::int) \<le> z';  z' \<le> z |] ==> nat (z-z') = nat z - nat z'"
   2.454 +by (cases z, cases z', 
   2.455 +    simp add: nat add minus diff_minus le int_def Zero_int_def)
   2.456 +
   2.457 +
   2.458 +lemma nat_zminus_int [simp]: "nat (- (int n)) = 0"
   2.459 +by (simp add: int_def minus nat Zero_int_def) 
   2.460 +
   2.461 +lemma zless_nat_eq_int_zless: "(m < nat z) = (int m < z)"
   2.462 +by (cases z, simp add: nat le int_def  linorder_not_le [symmetric], arith)
   2.463 +
   2.464 +
   2.465 +subsection{*Lemmas about the Function @{term int} and Orderings*}
   2.466 +
   2.467 +lemma negative_zless_0: "- (int (Suc n)) < 0"
   2.468 +by (simp add: order_less_le)
   2.469 +
   2.470 +lemma negative_zless [iff]: "- (int (Suc n)) < int m"
   2.471 +by (rule negative_zless_0 [THEN order_less_le_trans], simp)
   2.472 +
   2.473 +lemma negative_zle_0: "- int n \<le> 0"
   2.474 +by (simp add: minus_le_iff)
   2.475 +
   2.476 +lemma negative_zle [iff]: "- int n \<le> int m"
   2.477 +by (rule order_trans [OF negative_zle_0 zero_zle_int])
   2.478 +
   2.479 +lemma not_zle_0_negative [simp]: "~ (0 \<le> - (int (Suc n)))"
   2.480 +by (subst le_minus_iff, simp)
   2.481 +
   2.482 +lemma int_zle_neg: "(int n \<le> - int m) = (n = 0 & m = 0)"
   2.483 +by (simp add: int_def le minus Zero_int_def) 
   2.484 +
   2.485 +lemma not_int_zless_negative [simp]: "~ (int n < - int m)"
   2.486 +by (simp add: linorder_not_less)
   2.487 +
   2.488 +lemma negative_eq_positive [simp]: "(- int n = int m) = (n = 0 & m = 0)"
   2.489 +by (force simp add: order_eq_iff [of "- int n"] int_zle_neg)
   2.490 +
   2.491 +lemma zle_iff_zadd: "(w \<le> z) = (\<exists>n. z = w + int n)"
   2.492 +proof (cases w, cases z, simp add: le add int_def)
   2.493 +  fix a b c d
   2.494 +  assume "w = Abs_Integ (intrel `` {(a,b)})" "z = Abs_Integ (intrel `` {(c,d)})"
   2.495 +  show "(a+d \<le> c+b) = (\<exists>n. c+b = a+n+d)"
   2.496 +  proof
   2.497 +    assume "a + d \<le> c + b" 
   2.498 +    thus "\<exists>n. c + b = a + n + d" 
   2.499 +      by (auto intro!: exI [where x="c+b - (a+d)"])
   2.500 +  next    
   2.501 +    assume "\<exists>n. c + b = a + n + d" 
   2.502 +    then obtain n where "c + b = a + n + d" ..
   2.503 +    thus "a + d \<le> c + b" by arith
   2.504 +  qed
   2.505 +qed
   2.506 +
   2.507 +lemma abs_int_eq [simp]: "abs (int m) = int m"
   2.508 +by (simp add: abs_if)
   2.509 +
   2.510 +text{*This version is proved for all ordered rings, not just integers!
   2.511 +      It is proved here because attribute @{text arith_split} is not available
   2.512 +      in theory @{text Ring_and_Field}.
   2.513 +      But is it really better than just rewriting with @{text abs_if}?*}
   2.514 +lemma abs_split [arith_split]:
   2.515 +     "P(abs(a::'a::ordered_idom)) = ((0 \<le> a --> P a) & (a < 0 --> P(-a)))"
   2.516 +by (force dest: order_less_le_trans simp add: abs_if linorder_not_less)
   2.517 +
   2.518 +
   2.519 +subsection {* Constants @{term neg} and @{term iszero} *}
   2.520 +
   2.521 +definition
   2.522 +  neg  :: "'a\<Colon>ordered_idom \<Rightarrow> bool"
   2.523 +where
   2.524 +  [code inline]: "neg Z \<longleftrightarrow> Z < 0"
   2.525 +
   2.526 +definition (*for simplifying equalities*)
   2.527 +  iszero :: "'a\<Colon>comm_semiring_1_cancel \<Rightarrow> bool"
   2.528 +where
   2.529 +  "iszero z \<longleftrightarrow> z = 0"
   2.530 +
   2.531 +lemma not_neg_int [simp]: "~ neg(int n)"
   2.532 +by (simp add: neg_def)
   2.533 +
   2.534 +lemma neg_zminus_int [simp]: "neg(- (int (Suc n)))"
   2.535 +by (simp add: neg_def neg_less_0_iff_less)
   2.536 +
   2.537 +lemmas neg_eq_less_0 = neg_def
   2.538 +
   2.539 +lemma not_neg_eq_ge_0: "(~neg x) = (0 \<le> x)"
   2.540 +by (simp add: neg_def linorder_not_less)
   2.541 +
   2.542 +
   2.543 +subsection{*To simplify inequalities when Numeral1 can get simplified to 1*}
   2.544 +
   2.545 +lemma not_neg_0: "~ neg 0"
   2.546 +by (simp add: One_int_def neg_def)
   2.547 +
   2.548 +lemma not_neg_1: "~ neg 1"
   2.549 +by (simp add: neg_def linorder_not_less zero_le_one)
   2.550 +
   2.551 +lemma iszero_0: "iszero 0"
   2.552 +by (simp add: iszero_def)
   2.553 +
   2.554 +lemma not_iszero_1: "~ iszero 1"
   2.555 +by (simp add: iszero_def eq_commute)
   2.556 +
   2.557 +lemma neg_nat: "neg z ==> nat z = 0"
   2.558 +by (simp add: neg_def order_less_imp_le) 
   2.559 +
   2.560 +lemma not_neg_nat: "~ neg z ==> int (nat z) = z"
   2.561 +by (simp add: linorder_not_less neg_def)
   2.562 +
   2.563 +
   2.564 +subsection{*The Set of Natural Numbers*}
   2.565 +
   2.566 +constdefs
   2.567 +  Nats  :: "'a::semiring_1_cancel set"
   2.568 +  "Nats == range of_nat"
   2.569 +
   2.570 +notation (xsymbols)
   2.571 +  Nats  ("\<nat>")
   2.572 +
   2.573 +lemma of_nat_in_Nats [simp]: "of_nat n \<in> Nats"
   2.574 +by (simp add: Nats_def)
   2.575 +
   2.576 +lemma Nats_0 [simp]: "0 \<in> Nats"
   2.577 +apply (simp add: Nats_def)
   2.578 +apply (rule range_eqI)
   2.579 +apply (rule of_nat_0 [symmetric])
   2.580 +done
   2.581 +
   2.582 +lemma Nats_1 [simp]: "1 \<in> Nats"
   2.583 +apply (simp add: Nats_def)
   2.584 +apply (rule range_eqI)
   2.585 +apply (rule of_nat_1 [symmetric])
   2.586 +done
   2.587 +
   2.588 +lemma Nats_add [simp]: "[|a \<in> Nats; b \<in> Nats|] ==> a+b \<in> Nats"
   2.589 +apply (auto simp add: Nats_def)
   2.590 +apply (rule range_eqI)
   2.591 +apply (rule of_nat_add [symmetric])
   2.592 +done
   2.593 +
   2.594 +lemma Nats_mult [simp]: "[|a \<in> Nats; b \<in> Nats|] ==> a*b \<in> Nats"
   2.595 +apply (auto simp add: Nats_def)
   2.596 +apply (rule range_eqI)
   2.597 +apply (rule of_nat_mult [symmetric])
   2.598 +done
   2.599 +
   2.600 +text{*Agreement with the specific embedding for the integers*}
   2.601 +lemma int_eq_of_nat: "int = (of_nat :: nat => int)"
   2.602 +proof
   2.603 +  fix n
   2.604 +  show "int n = of_nat n"  by (induct n, simp_all add: int_Suc add_ac)
   2.605 +qed
   2.606 +
   2.607 +lemma of_nat_eq_id [simp]: "of_nat = (id :: nat => nat)"
   2.608 +proof
   2.609 +  fix n
   2.610 +  show "of_nat n = id n"  by (induct n, simp_all)
   2.611 +qed
   2.612 +
   2.613 +
   2.614 +subsection{*Embedding of the Integers into any @{text ring_1}:
   2.615 +@{term of_int}*}
   2.616 +
   2.617 +constdefs
   2.618 +   of_int :: "int => 'a::ring_1"
   2.619 +   "of_int z == contents (\<Union>(i,j) \<in> Rep_Integ z. { of_nat i - of_nat j })"
   2.620 +
   2.621 +
   2.622 +lemma of_int: "of_int (Abs_Integ (intrel `` {(i,j)})) = of_nat i - of_nat j"
   2.623 +proof -
   2.624 +  have "(\<lambda>(i,j). { of_nat i - (of_nat j :: 'a) }) respects intrel"
   2.625 +    by (simp add: congruent_def compare_rls of_nat_add [symmetric]
   2.626 +            del: of_nat_add) 
   2.627 +  thus ?thesis
   2.628 +    by (simp add: of_int_def UN_equiv_class [OF equiv_intrel])
   2.629 +qed
   2.630 +
   2.631 +lemma of_int_0 [simp]: "of_int 0 = 0"
   2.632 +by (simp add: of_int Zero_int_def int_def)
   2.633 +
   2.634 +lemma of_int_1 [simp]: "of_int 1 = 1"
   2.635 +by (simp add: of_int One_int_def int_def)
   2.636 +
   2.637 +lemma of_int_add [simp]: "of_int (w+z) = of_int w + of_int z"
   2.638 +by (cases w, cases z, simp add: compare_rls of_int add)
   2.639 +
   2.640 +lemma of_int_minus [simp]: "of_int (-z) = - (of_int z)"
   2.641 +by (cases z, simp add: compare_rls of_int minus)
   2.642 +
   2.643 +lemma of_int_diff [simp]: "of_int (w-z) = of_int w - of_int z"
   2.644 +by (simp add: diff_minus)
   2.645 +
   2.646 +lemma of_int_mult [simp]: "of_int (w*z) = of_int w * of_int z"
   2.647 +apply (cases w, cases z)
   2.648 +apply (simp add: compare_rls of_int left_diff_distrib right_diff_distrib
   2.649 +                 mult add_ac)
   2.650 +done
   2.651 +
   2.652 +lemma of_int_le_iff [simp]:
   2.653 +     "(of_int w \<le> (of_int z::'a::ordered_idom)) = (w \<le> z)"
   2.654 +apply (cases w)
   2.655 +apply (cases z)
   2.656 +apply (simp add: compare_rls of_int le diff_int_def add minus
   2.657 +                 of_nat_add [symmetric]   del: of_nat_add)
   2.658 +done
   2.659 +
   2.660 +text{*Special cases where either operand is zero*}
   2.661 +lemmas of_int_0_le_iff [simp] = of_int_le_iff [of 0, simplified]
   2.662 +lemmas of_int_le_0_iff [simp] = of_int_le_iff [of _ 0, simplified]
   2.663 +
   2.664 +
   2.665 +lemma of_int_less_iff [simp]:
   2.666 +     "(of_int w < (of_int z::'a::ordered_idom)) = (w < z)"
   2.667 +by (simp add: linorder_not_le [symmetric])
   2.668 +
   2.669 +text{*Special cases where either operand is zero*}
   2.670 +lemmas of_int_0_less_iff [simp] = of_int_less_iff [of 0, simplified]
   2.671 +lemmas of_int_less_0_iff [simp] = of_int_less_iff [of _ 0, simplified]
   2.672 +
   2.673 +text{*Class for unital rings with characteristic zero.
   2.674 + Includes non-ordered rings like the complex numbers.*}
   2.675 +axclass ring_char_0 < ring_1
   2.676 +  of_int_inject: "of_int w = of_int z ==> w = z"
   2.677 +
   2.678 +lemma of_int_eq_iff [simp]:
   2.679 +     "(of_int w = (of_int z::'a::ring_char_0)) = (w = z)"
   2.680 +by (safe elim!: of_int_inject)
   2.681 +
   2.682 +text{*Every @{text ordered_idom} has characteristic zero.*}
   2.683 +instance ordered_idom < ring_char_0
   2.684 +by intro_classes (simp add: order_eq_iff)
   2.685 +
   2.686 +text{*Special cases where either operand is zero*}
   2.687 +lemmas of_int_0_eq_iff [simp] = of_int_eq_iff [of 0, simplified]
   2.688 +lemmas of_int_eq_0_iff [simp] = of_int_eq_iff [of _ 0, simplified]
   2.689 +
   2.690 +lemma of_int_eq_id [simp]: "of_int = (id :: int => int)"
   2.691 +proof
   2.692 +  fix z
   2.693 +  show "of_int z = id z"  
   2.694 +    by (cases z)
   2.695 +      (simp add: of_int add minus int_eq_of_nat [symmetric] int_def diff_minus)
   2.696 +qed
   2.697 +
   2.698 +
   2.699 +subsection{*The Set of Integers*}
   2.700 +
   2.701 +constdefs
   2.702 +  Ints  :: "'a::ring_1 set"
   2.703 +  "Ints == range of_int"
   2.704 +
   2.705 +notation (xsymbols)
   2.706 +  Ints  ("\<int>")
   2.707 +
   2.708 +lemma Ints_0 [simp]: "0 \<in> Ints"
   2.709 +apply (simp add: Ints_def)
   2.710 +apply (rule range_eqI)
   2.711 +apply (rule of_int_0 [symmetric])
   2.712 +done
   2.713 +
   2.714 +lemma Ints_1 [simp]: "1 \<in> Ints"
   2.715 +apply (simp add: Ints_def)
   2.716 +apply (rule range_eqI)
   2.717 +apply (rule of_int_1 [symmetric])
   2.718 +done
   2.719 +
   2.720 +lemma Ints_add [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a+b \<in> Ints"
   2.721 +apply (auto simp add: Ints_def)
   2.722 +apply (rule range_eqI)
   2.723 +apply (rule of_int_add [symmetric])
   2.724 +done
   2.725 +
   2.726 +lemma Ints_minus [simp]: "a \<in> Ints ==> -a \<in> Ints"
   2.727 +apply (auto simp add: Ints_def)
   2.728 +apply (rule range_eqI)
   2.729 +apply (rule of_int_minus [symmetric])
   2.730 +done
   2.731 +
   2.732 +lemma Ints_diff [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a-b \<in> Ints"
   2.733 +apply (auto simp add: Ints_def)
   2.734 +apply (rule range_eqI)
   2.735 +apply (rule of_int_diff [symmetric])
   2.736 +done
   2.737 +
   2.738 +lemma Ints_mult [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a*b \<in> Ints"
   2.739 +apply (auto simp add: Ints_def)
   2.740 +apply (rule range_eqI)
   2.741 +apply (rule of_int_mult [symmetric])
   2.742 +done
   2.743 +
   2.744 +text{*Collapse nested embeddings*}
   2.745 +lemma of_int_of_nat_eq [simp]: "of_int (of_nat n) = of_nat n"
   2.746 +by (induct n, auto)
   2.747 +
   2.748 +lemma of_int_int_eq [simp]: "of_int (int n) = of_nat n"
   2.749 +by (simp add: int_eq_of_nat)
   2.750 +
   2.751 +lemma Ints_cases [cases set: Ints]:
   2.752 +  assumes "q \<in> \<int>"
   2.753 +  obtains (of_int) z where "q = of_int z"
   2.754 +  unfolding Ints_def
   2.755 +proof -
   2.756 +  from `q \<in> \<int>` have "q \<in> range of_int" unfolding Ints_def .
   2.757 +  then obtain z where "q = of_int z" ..
   2.758 +  then show thesis ..
   2.759 +qed
   2.760 +
   2.761 +lemma Ints_induct [case_names of_int, induct set: Ints]:
   2.762 +  "q \<in> \<int> ==> (!!z. P (of_int z)) ==> P q"
   2.763 +  by (rule Ints_cases) auto
   2.764 +
   2.765 +
   2.766 +(* int (Suc n) = 1 + int n *)
   2.767 +
   2.768 +
   2.769 +
   2.770 +subsection{*More Properties of @{term setsum} and  @{term setprod}*}
   2.771 +
   2.772 +text{*By Jeremy Avigad*}
   2.773 +
   2.774 +
   2.775 +lemma of_nat_setsum: "of_nat (setsum f A) = (\<Sum>x\<in>A. of_nat(f x))"
   2.776 +  apply (cases "finite A")
   2.777 +  apply (erule finite_induct, auto)
   2.778 +  done
   2.779 +
   2.780 +lemma of_int_setsum: "of_int (setsum f A) = (\<Sum>x\<in>A. of_int(f x))"
   2.781 +  apply (cases "finite A")
   2.782 +  apply (erule finite_induct, auto)
   2.783 +  done
   2.784 +
   2.785 +lemma int_setsum: "int (setsum f A) = (\<Sum>x\<in>A. int(f x))"
   2.786 +  by (simp add: int_eq_of_nat of_nat_setsum)
   2.787 +
   2.788 +lemma of_nat_setprod: "of_nat (setprod f A) = (\<Prod>x\<in>A. of_nat(f x))"
   2.789 +  apply (cases "finite A")
   2.790 +  apply (erule finite_induct, auto)
   2.791 +  done
   2.792 +
   2.793 +lemma of_int_setprod: "of_int (setprod f A) = (\<Prod>x\<in>A. of_int(f x))"
   2.794 +  apply (cases "finite A")
   2.795 +  apply (erule finite_induct, auto)
   2.796 +  done
   2.797 +
   2.798 +lemma int_setprod: "int (setprod f A) = (\<Prod>x\<in>A. int(f x))"
   2.799 +  by (simp add: int_eq_of_nat of_nat_setprod)
   2.800 +
   2.801 +lemma setprod_nonzero_nat:
   2.802 +    "finite A ==> (\<forall>x \<in> A. f x \<noteq> (0::nat)) ==> setprod f A \<noteq> 0"
   2.803 +  by (rule setprod_nonzero, auto)
   2.804 +
   2.805 +lemma setprod_zero_eq_nat:
   2.806 +    "finite A ==> (setprod f A = (0::nat)) = (\<exists>x \<in> A. f x = 0)"
   2.807 +  by (rule setprod_zero_eq, auto)
   2.808 +
   2.809 +lemma setprod_nonzero_int:
   2.810 +    "finite A ==> (\<forall>x \<in> A. f x \<noteq> (0::int)) ==> setprod f A \<noteq> 0"
   2.811 +  by (rule setprod_nonzero, auto)
   2.812 +
   2.813 +lemma setprod_zero_eq_int:
   2.814 +    "finite A ==> (setprod f A = (0::int)) = (\<exists>x \<in> A. f x = 0)"
   2.815 +  by (rule setprod_zero_eq, auto)
   2.816 +
   2.817 +
   2.818 +subsection {* Further properties *}
   2.819 +
   2.820 +text{*Now we replace the case analysis rule by a more conventional one:
   2.821 +whether an integer is negative or not.*}
   2.822 +
   2.823 +lemma zless_iff_Suc_zadd:
   2.824 +    "(w < z) = (\<exists>n. z = w + int(Suc n))"
   2.825 +apply (cases z, cases w)
   2.826 +apply (auto simp add: le add int_def linorder_not_le [symmetric]) 
   2.827 +apply (rename_tac a b c d) 
   2.828 +apply (rule_tac x="a+d - Suc(c+b)" in exI) 
   2.829 +apply arith
   2.830 +done
   2.831 +
   2.832 +lemma negD: "x<0 ==> \<exists>n. x = - (int (Suc n))"
   2.833 +apply (cases x)
   2.834 +apply (auto simp add: le minus Zero_int_def int_def order_less_le) 
   2.835 +apply (rule_tac x="y - Suc x" in exI, arith)
   2.836 +done
   2.837 +
   2.838 +theorem int_cases [cases type: int, case_names nonneg neg]:
   2.839 +     "[|!! n. z = int n ==> P;  !! n. z =  - (int (Suc n)) ==> P |] ==> P"
   2.840 +apply (cases "z < 0", blast dest!: negD)
   2.841 +apply (simp add: linorder_not_less)
   2.842 +apply (blast dest: nat_0_le [THEN sym])
   2.843 +done
   2.844 +
   2.845 +theorem int_induct [induct type: int, case_names nonneg neg]:
   2.846 +     "[|!! n. P (int n);  !!n. P (- (int (Suc n))) |] ==> P z"
   2.847 +  by (cases z) auto
   2.848 +
   2.849 +text{*Contributed by Brian Huffman*}
   2.850 +theorem int_diff_cases [case_names diff]:
   2.851 +assumes prem: "!!m n. z = int m - int n ==> P" shows "P"
   2.852 + apply (rule_tac z=z in int_cases)
   2.853 +  apply (rule_tac m=n and n=0 in prem, simp)
   2.854 + apply (rule_tac m=0 and n="Suc n" in prem, simp)
   2.855 +done
   2.856 +
   2.857 +lemma of_nat_nat: "0 \<le> z ==> of_nat (nat z) = of_int z"
   2.858 +apply (cases z)
   2.859 +apply (simp_all add: not_zle_0_negative del: int_Suc)
   2.860 +done
   2.861 +
   2.862 +lemmas zless_le = less_int_def [THEN meta_eq_to_obj_eq]
   2.863 +
   2.864 +lemmas [simp] = int_Suc
   2.865 +
   2.866 +
   2.867 +subsection {* Legacy ML bindings *}
   2.868 +
   2.869 +ML {*
   2.870 +val of_nat_0 = @{thm of_nat_0};
   2.871 +val of_nat_1 = @{thm of_nat_1};
   2.872 +val of_nat_Suc = @{thm of_nat_Suc};
   2.873 +val of_nat_add = @{thm of_nat_add};
   2.874 +val of_nat_mult = @{thm of_nat_mult};
   2.875 +val of_int_0 = @{thm of_int_0};
   2.876 +val of_int_1 = @{thm of_int_1};
   2.877 +val of_int_add = @{thm of_int_add};
   2.878 +val of_int_mult = @{thm of_int_mult};
   2.879 +val int_eq_of_nat = @{thm int_eq_of_nat};
   2.880 +val zle_int = @{thm zle_int};
   2.881 +val int_int_eq = @{thm int_int_eq};
   2.882 +val diff_int_def = @{thm diff_int_def};
   2.883 +val zadd_ac = @{thms zadd_ac};
   2.884 +val zless_int = @{thm zless_int};
   2.885 +val zadd_int = @{thm zadd_int};
   2.886 +val zmult_int = @{thm zmult_int};
   2.887 +val nat_0_le = @{thm nat_0_le};
   2.888 +val int_0 = @{thm int_0};
   2.889 +val int_1 = @{thm int_1};
   2.890 +val abs_split = @{thm abs_split};
   2.891 +*}
   2.892 +
   2.893 +end
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/HOL/IntDiv.thy	Thu May 31 18:16:52 2007 +0200
     3.3 @@ -0,0 +1,1406 @@
     3.4 +(*  Title:      HOL/IntDiv.thy
     3.5 +    ID:         $Id$
     3.6 +    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     3.7 +    Copyright   1999  University of Cambridge
     3.8 +
     3.9 +*)
    3.10 +
    3.11 +header{*The Division Operators div and mod; the Divides Relation dvd*}
    3.12 +
    3.13 +theory IntDiv
    3.14 +imports IntArith Divides FunDef
    3.15 +begin
    3.16 +
    3.17 +declare zless_nat_conj [simp]
    3.18 +
    3.19 +constdefs
    3.20 +  quorem :: "(int*int) * (int*int) => bool"
    3.21 +    --{*definition of quotient and remainder*}
    3.22 +    [code func]: "quorem == %((a,b), (q,r)).
    3.23 +                      a = b*q + r &
    3.24 +                      (if 0 < b then 0\<le>r & r<b else b<r & r \<le> 0)"
    3.25 +
    3.26 +  adjust :: "[int, int*int] => int*int"
    3.27 +    --{*for the division algorithm*}
    3.28 +    [code func]: "adjust b == %(q,r). if 0 \<le> r-b then (2*q + 1, r-b)
    3.29 +                         else (2*q, r)"
    3.30 +
    3.31 +text{*algorithm for the case @{text "a\<ge>0, b>0"}*}
    3.32 +function
    3.33 +  posDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    3.34 +where
    3.35 +  "posDivAlg a b =
    3.36 +     (if (a<b | b\<le>0) then (0,a)
    3.37 +        else adjust b (posDivAlg a (2*b)))"
    3.38 +by auto
    3.39 +termination by (relation "measure (%(a,b). nat(a - b + 1))") auto
    3.40 +
    3.41 +text{*algorithm for the case @{text "a<0, b>0"}*}
    3.42 +function
    3.43 +  negDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    3.44 +where
    3.45 +  "negDivAlg a b  =
    3.46 +     (if (0\<le>a+b | b\<le>0) then (-1,a+b)
    3.47 +      else adjust b (negDivAlg a (2*b)))"
    3.48 +by auto
    3.49 +termination by (relation "measure (%(a,b). nat(- a - b))") auto
    3.50 +
    3.51 +text{*algorithm for the general case @{term "b\<noteq>0"}*}
    3.52 +constdefs
    3.53 +  negateSnd :: "int*int => int*int"
    3.54 +    [code func]: "negateSnd == %(q,r). (q,-r)"
    3.55 +
    3.56 +definition
    3.57 +  divAlg :: "int \<times> int \<Rightarrow> int \<times> int"
    3.58 +    --{*The full division algorithm considers all possible signs for a, b
    3.59 +       including the special case @{text "a=0, b<0"} because 
    3.60 +       @{term negDivAlg} requires @{term "a<0"}.*}
    3.61 +where
    3.62 +  "divAlg = (\<lambda>(a, b). (if 0\<le>a then
    3.63 +                  if 0\<le>b then posDivAlg a b
    3.64 +                  else if a=0 then (0, 0)
    3.65 +                       else negateSnd (negDivAlg (-a) (-b))
    3.66 +               else 
    3.67 +                  if 0<b then negDivAlg a b
    3.68 +                  else negateSnd (posDivAlg (-a) (-b))))"
    3.69 +
    3.70 +instance int :: Divides.div
    3.71 +  div_def: "a div b == fst (divAlg (a, b))"
    3.72 +  mod_def: "a mod b == snd (divAlg (a, b))" ..
    3.73 +
    3.74 +lemma divAlg_mod_div:
    3.75 +  "divAlg (p, q) = (p div q, p mod q)"
    3.76 +  by (auto simp add: div_def mod_def)
    3.77 +
    3.78 +text{*
    3.79 +Here is the division algorithm in ML:
    3.80 +
    3.81 +\begin{verbatim}
    3.82 +    fun posDivAlg (a,b) =
    3.83 +      if a<b then (0,a)
    3.84 +      else let val (q,r) = posDivAlg(a, 2*b)
    3.85 +	       in  if 0\<le>r-b then (2*q+1, r-b) else (2*q, r)
    3.86 +	   end
    3.87 +
    3.88 +    fun negDivAlg (a,b) =
    3.89 +      if 0\<le>a+b then (~1,a+b)
    3.90 +      else let val (q,r) = negDivAlg(a, 2*b)
    3.91 +	       in  if 0\<le>r-b then (2*q+1, r-b) else (2*q, r)
    3.92 +	   end;
    3.93 +
    3.94 +    fun negateSnd (q,r:int) = (q,~r);
    3.95 +
    3.96 +    fun divAlg (a,b) = if 0\<le>a then 
    3.97 +			  if b>0 then posDivAlg (a,b) 
    3.98 +			   else if a=0 then (0,0)
    3.99 +				else negateSnd (negDivAlg (~a,~b))
   3.100 +		       else 
   3.101 +			  if 0<b then negDivAlg (a,b)
   3.102 +			  else        negateSnd (posDivAlg (~a,~b));
   3.103 +\end{verbatim}
   3.104 +*}
   3.105 +
   3.106 +
   3.107 +
   3.108 +subsection{*Uniqueness and Monotonicity of Quotients and Remainders*}
   3.109 +
   3.110 +lemma unique_quotient_lemma:
   3.111 +     "[| b*q' + r'  \<le> b*q + r;  0 \<le> r';  r' < b;  r < b |]  
   3.112 +      ==> q' \<le> (q::int)"
   3.113 +apply (subgoal_tac "r' + b * (q'-q) \<le> r")
   3.114 + prefer 2 apply (simp add: right_diff_distrib)
   3.115 +apply (subgoal_tac "0 < b * (1 + q - q') ")
   3.116 +apply (erule_tac [2] order_le_less_trans)
   3.117 + prefer 2 apply (simp add: right_diff_distrib right_distrib)
   3.118 +apply (subgoal_tac "b * q' < b * (1 + q) ")
   3.119 + prefer 2 apply (simp add: right_diff_distrib right_distrib)
   3.120 +apply (simp add: mult_less_cancel_left)
   3.121 +done
   3.122 +
   3.123 +lemma unique_quotient_lemma_neg:
   3.124 +     "[| b*q' + r' \<le> b*q + r;  r \<le> 0;  b < r;  b < r' |]  
   3.125 +      ==> q \<le> (q'::int)"
   3.126 +by (rule_tac b = "-b" and r = "-r'" and r' = "-r" in unique_quotient_lemma, 
   3.127 +    auto)
   3.128 +
   3.129 +lemma unique_quotient:
   3.130 +     "[| quorem ((a,b), (q,r));  quorem ((a,b), (q',r'));  b \<noteq> 0 |]  
   3.131 +      ==> q = q'"
   3.132 +apply (simp add: quorem_def linorder_neq_iff split: split_if_asm)
   3.133 +apply (blast intro: order_antisym
   3.134 +             dest: order_eq_refl [THEN unique_quotient_lemma] 
   3.135 +             order_eq_refl [THEN unique_quotient_lemma_neg] sym)+
   3.136 +done
   3.137 +
   3.138 +
   3.139 +lemma unique_remainder:
   3.140 +     "[| quorem ((a,b), (q,r));  quorem ((a,b), (q',r'));  b \<noteq> 0 |]  
   3.141 +      ==> r = r'"
   3.142 +apply (subgoal_tac "q = q'")
   3.143 + apply (simp add: quorem_def)
   3.144 +apply (blast intro: unique_quotient)
   3.145 +done
   3.146 +
   3.147 +
   3.148 +subsection{*Correctness of @{term posDivAlg}, the Algorithm for Non-Negative Dividends*}
   3.149 +
   3.150 +text{*And positive divisors*}
   3.151 +
   3.152 +lemma adjust_eq [simp]:
   3.153 +     "adjust b (q,r) = 
   3.154 +      (let diff = r-b in  
   3.155 +	if 0 \<le> diff then (2*q + 1, diff)   
   3.156 +                     else (2*q, r))"
   3.157 +by (simp add: Let_def adjust_def)
   3.158 +
   3.159 +declare posDivAlg.simps [simp del]
   3.160 +
   3.161 +text{*use with a simproc to avoid repeatedly proving the premise*}
   3.162 +lemma posDivAlg_eqn:
   3.163 +     "0 < b ==>  
   3.164 +      posDivAlg a b = (if a<b then (0,a) else adjust b (posDivAlg a (2*b)))"
   3.165 +by (rule posDivAlg.simps [THEN trans], simp)
   3.166 +
   3.167 +text{*Correctness of @{term posDivAlg}: it computes quotients correctly*}
   3.168 +theorem posDivAlg_correct:
   3.169 +  assumes "0 \<le> a" and "0 < b"
   3.170 +  shows "quorem ((a, b), posDivAlg a b)"
   3.171 +using prems apply (induct a b rule: posDivAlg.induct)
   3.172 +apply auto
   3.173 +apply (simp add: quorem_def)
   3.174 +apply (subst posDivAlg_eqn, simp add: right_distrib)
   3.175 +apply (case_tac "a < b")
   3.176 +apply simp_all
   3.177 +apply (erule splitE)
   3.178 +apply (auto simp add: right_distrib Let_def)
   3.179 +done
   3.180 +
   3.181 +
   3.182 +subsection{*Correctness of @{term negDivAlg}, the Algorithm for Negative Dividends*}
   3.183 +
   3.184 +text{*And positive divisors*}
   3.185 +
   3.186 +declare negDivAlg.simps [simp del]
   3.187 +
   3.188 +text{*use with a simproc to avoid repeatedly proving the premise*}
   3.189 +lemma negDivAlg_eqn:
   3.190 +     "0 < b ==>  
   3.191 +      negDivAlg a b =       
   3.192 +       (if 0\<le>a+b then (-1,a+b) else adjust b (negDivAlg a (2*b)))"
   3.193 +by (rule negDivAlg.simps [THEN trans], simp)
   3.194 +
   3.195 +(*Correctness of negDivAlg: it computes quotients correctly
   3.196 +  It doesn't work if a=0 because the 0/b equals 0, not -1*)
   3.197 +lemma negDivAlg_correct:
   3.198 +  assumes "a < 0" and "b > 0"
   3.199 +  shows "quorem ((a, b), negDivAlg a b)"
   3.200 +using prems apply (induct a b rule: negDivAlg.induct)
   3.201 +apply (auto simp add: linorder_not_le)
   3.202 +apply (simp add: quorem_def)
   3.203 +apply (subst negDivAlg_eqn, assumption)
   3.204 +apply (case_tac "a + b < (0\<Colon>int)")
   3.205 +apply simp_all
   3.206 +apply (erule splitE)
   3.207 +apply (auto simp add: right_distrib Let_def)
   3.208 +done
   3.209 +
   3.210 +
   3.211 +subsection{*Existence Shown by Proving the Division Algorithm to be Correct*}
   3.212 +
   3.213 +(*the case a=0*)
   3.214 +lemma quorem_0: "b \<noteq> 0 ==> quorem ((0,b), (0,0))"
   3.215 +by (auto simp add: quorem_def linorder_neq_iff)
   3.216 +
   3.217 +lemma posDivAlg_0 [simp]: "posDivAlg 0 b = (0, 0)"
   3.218 +by (subst posDivAlg.simps, auto)
   3.219 +
   3.220 +lemma negDivAlg_minus1 [simp]: "negDivAlg -1 b = (-1, b - 1)"
   3.221 +by (subst negDivAlg.simps, auto)
   3.222 +
   3.223 +lemma negateSnd_eq [simp]: "negateSnd(q,r) = (q,-r)"
   3.224 +by (simp add: negateSnd_def)
   3.225 +
   3.226 +lemma quorem_neg: "quorem ((-a,-b), qr) ==> quorem ((a,b), negateSnd qr)"
   3.227 +by (auto simp add: split_ifs quorem_def)
   3.228 +
   3.229 +lemma divAlg_correct: "b \<noteq> 0 ==> quorem ((a,b), divAlg (a, b))"
   3.230 +by (force simp add: linorder_neq_iff quorem_0 divAlg_def quorem_neg
   3.231 +                    posDivAlg_correct negDivAlg_correct)
   3.232 +
   3.233 +text{*Arbitrary definitions for division by zero.  Useful to simplify 
   3.234 +    certain equations.*}
   3.235 +
   3.236 +lemma DIVISION_BY_ZERO [simp]: "a div (0::int) = 0 & a mod (0::int) = a"
   3.237 +by (simp add: div_def mod_def divAlg_def posDivAlg.simps)  
   3.238 +
   3.239 +
   3.240 +text{*Basic laws about division and remainder*}
   3.241 +
   3.242 +lemma zmod_zdiv_equality: "(a::int) = b * (a div b) + (a mod b)"
   3.243 +apply (case_tac "b = 0", simp)
   3.244 +apply (cut_tac a = a and b = b in divAlg_correct)
   3.245 +apply (auto simp add: quorem_def div_def mod_def)
   3.246 +done
   3.247 +
   3.248 +lemma zdiv_zmod_equality: "(b * (a div b) + (a mod b)) + k = (a::int)+k"
   3.249 +by(simp add: zmod_zdiv_equality[symmetric])
   3.250 +
   3.251 +lemma zdiv_zmod_equality2: "((a div b) * b + (a mod b)) + k = (a::int)+k"
   3.252 +by(simp add: mult_commute zmod_zdiv_equality[symmetric])
   3.253 +
   3.254 +text {* Tool setup *}
   3.255 +
   3.256 +ML_setup {*
   3.257 +local 
   3.258 +
   3.259 +structure CancelDivMod = CancelDivModFun(
   3.260 +struct
   3.261 +  val div_name = @{const_name Divides.div};
   3.262 +  val mod_name = @{const_name Divides.mod};
   3.263 +  val mk_binop = HOLogic.mk_binop;
   3.264 +  val mk_sum = Int_Numeral_Simprocs.mk_sum HOLogic.intT;
   3.265 +  val dest_sum = Int_Numeral_Simprocs.dest_sum;
   3.266 +  val div_mod_eqs =
   3.267 +    map mk_meta_eq [@{thm zdiv_zmod_equality},
   3.268 +      @{thm zdiv_zmod_equality2}];
   3.269 +  val trans = trans;
   3.270 +  val prove_eq_sums =
   3.271 +    let
   3.272 +      val simps = diff_int_def :: Int_Numeral_Simprocs.add_0s @ zadd_ac
   3.273 +    in NatArithUtils.prove_conv all_tac (NatArithUtils.simp_all_tac simps) end;
   3.274 +end)
   3.275 +
   3.276 +in
   3.277 +
   3.278 +val cancel_zdiv_zmod_proc = NatArithUtils.prep_simproc
   3.279 +  ("cancel_zdiv_zmod", ["(m::int) + n"], K CancelDivMod.proc)
   3.280 +
   3.281 +end;
   3.282 +
   3.283 +Addsimprocs [cancel_zdiv_zmod_proc]
   3.284 +*}
   3.285 +
   3.286 +lemma pos_mod_conj : "(0::int) < b ==> 0 \<le> a mod b & a mod b < b"
   3.287 +apply (cut_tac a = a and b = b in divAlg_correct)
   3.288 +apply (auto simp add: quorem_def mod_def)
   3.289 +done
   3.290 +
   3.291 +lemmas pos_mod_sign  [simp] = pos_mod_conj [THEN conjunct1, standard]
   3.292 +   and pos_mod_bound [simp] = pos_mod_conj [THEN conjunct2, standard]
   3.293 +
   3.294 +lemma neg_mod_conj : "b < (0::int) ==> a mod b \<le> 0 & b < a mod b"
   3.295 +apply (cut_tac a = a and b = b in divAlg_correct)
   3.296 +apply (auto simp add: quorem_def div_def mod_def)
   3.297 +done
   3.298 +
   3.299 +lemmas neg_mod_sign  [simp] = neg_mod_conj [THEN conjunct1, standard]
   3.300 +   and neg_mod_bound [simp] = neg_mod_conj [THEN conjunct2, standard]
   3.301 +
   3.302 +
   3.303 +
   3.304 +subsection{*General Properties of div and mod*}
   3.305 +
   3.306 +lemma quorem_div_mod: "b \<noteq> 0 ==> quorem ((a, b), (a div b, a mod b))"
   3.307 +apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   3.308 +apply (force simp add: quorem_def linorder_neq_iff)
   3.309 +done
   3.310 +
   3.311 +lemma quorem_div: "[| quorem((a,b),(q,r));  b \<noteq> 0 |] ==> a div b = q"
   3.312 +by (simp add: quorem_div_mod [THEN unique_quotient])
   3.313 +
   3.314 +lemma quorem_mod: "[| quorem((a,b),(q,r));  b \<noteq> 0 |] ==> a mod b = r"
   3.315 +by (simp add: quorem_div_mod [THEN unique_remainder])
   3.316 +
   3.317 +lemma div_pos_pos_trivial: "[| (0::int) \<le> a;  a < b |] ==> a div b = 0"
   3.318 +apply (rule quorem_div)
   3.319 +apply (auto simp add: quorem_def)
   3.320 +done
   3.321 +
   3.322 +lemma div_neg_neg_trivial: "[| a \<le> (0::int);  b < a |] ==> a div b = 0"
   3.323 +apply (rule quorem_div)
   3.324 +apply (auto simp add: quorem_def)
   3.325 +done
   3.326 +
   3.327 +lemma div_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a div b = -1"
   3.328 +apply (rule quorem_div)
   3.329 +apply (auto simp add: quorem_def)
   3.330 +done
   3.331 +
   3.332 +(*There is no div_neg_pos_trivial because  0 div b = 0 would supersede it*)
   3.333 +
   3.334 +lemma mod_pos_pos_trivial: "[| (0::int) \<le> a;  a < b |] ==> a mod b = a"
   3.335 +apply (rule_tac q = 0 in quorem_mod)
   3.336 +apply (auto simp add: quorem_def)
   3.337 +done
   3.338 +
   3.339 +lemma mod_neg_neg_trivial: "[| a \<le> (0::int);  b < a |] ==> a mod b = a"
   3.340 +apply (rule_tac q = 0 in quorem_mod)
   3.341 +apply (auto simp add: quorem_def)
   3.342 +done
   3.343 +
   3.344 +lemma mod_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a mod b = a+b"
   3.345 +apply (rule_tac q = "-1" in quorem_mod)
   3.346 +apply (auto simp add: quorem_def)
   3.347 +done
   3.348 +
   3.349 +text{*There is no @{text mod_neg_pos_trivial}.*}
   3.350 +
   3.351 +
   3.352 +(*Simpler laws such as -a div b = -(a div b) FAIL, but see just below*)
   3.353 +lemma zdiv_zminus_zminus [simp]: "(-a) div (-b) = a div (b::int)"
   3.354 +apply (case_tac "b = 0", simp)
   3.355 +apply (simp add: quorem_div_mod [THEN quorem_neg, simplified, 
   3.356 +                                 THEN quorem_div, THEN sym])
   3.357 +
   3.358 +done
   3.359 +
   3.360 +(*Simpler laws such as -a mod b = -(a mod b) FAIL, but see just below*)
   3.361 +lemma zmod_zminus_zminus [simp]: "(-a) mod (-b) = - (a mod (b::int))"
   3.362 +apply (case_tac "b = 0", simp)
   3.363 +apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_mod],
   3.364 +       auto)
   3.365 +done
   3.366 +
   3.367 +
   3.368 +subsection{*Laws for div and mod with Unary Minus*}
   3.369 +
   3.370 +lemma zminus1_lemma:
   3.371 +     "quorem((a,b),(q,r))  
   3.372 +      ==> quorem ((-a,b), (if r=0 then -q else -q - 1),  
   3.373 +                          (if r=0 then 0 else b-r))"
   3.374 +by (force simp add: split_ifs quorem_def linorder_neq_iff right_diff_distrib)
   3.375 +
   3.376 +
   3.377 +lemma zdiv_zminus1_eq_if:
   3.378 +     "b \<noteq> (0::int)  
   3.379 +      ==> (-a) div b =  
   3.380 +          (if a mod b = 0 then - (a div b) else  - (a div b) - 1)"
   3.381 +by (blast intro: quorem_div_mod [THEN zminus1_lemma, THEN quorem_div])
   3.382 +
   3.383 +lemma zmod_zminus1_eq_if:
   3.384 +     "(-a::int) mod b = (if a mod b = 0 then 0 else  b - (a mod b))"
   3.385 +apply (case_tac "b = 0", simp)
   3.386 +apply (blast intro: quorem_div_mod [THEN zminus1_lemma, THEN quorem_mod])
   3.387 +done
   3.388 +
   3.389 +lemma zdiv_zminus2: "a div (-b) = (-a::int) div b"
   3.390 +by (cut_tac a = "-a" in zdiv_zminus_zminus, auto)
   3.391 +
   3.392 +lemma zmod_zminus2: "a mod (-b) = - ((-a::int) mod b)"
   3.393 +by (cut_tac a = "-a" and b = b in zmod_zminus_zminus, auto)
   3.394 +
   3.395 +lemma zdiv_zminus2_eq_if:
   3.396 +     "b \<noteq> (0::int)  
   3.397 +      ==> a div (-b) =  
   3.398 +          (if a mod b = 0 then - (a div b) else  - (a div b) - 1)"
   3.399 +by (simp add: zdiv_zminus1_eq_if zdiv_zminus2)
   3.400 +
   3.401 +lemma zmod_zminus2_eq_if:
   3.402 +     "a mod (-b::int) = (if a mod b = 0 then 0 else  (a mod b) - b)"
   3.403 +by (simp add: zmod_zminus1_eq_if zmod_zminus2)
   3.404 +
   3.405 +
   3.406 +subsection{*Division of a Number by Itself*}
   3.407 +
   3.408 +lemma self_quotient_aux1: "[| (0::int) < a; a = r + a*q; r < a |] ==> 1 \<le> q"
   3.409 +apply (subgoal_tac "0 < a*q")
   3.410 + apply (simp add: zero_less_mult_iff, arith)
   3.411 +done
   3.412 +
   3.413 +lemma self_quotient_aux2: "[| (0::int) < a; a = r + a*q; 0 \<le> r |] ==> q \<le> 1"
   3.414 +apply (subgoal_tac "0 \<le> a* (1-q) ")
   3.415 + apply (simp add: zero_le_mult_iff)
   3.416 +apply (simp add: right_diff_distrib)
   3.417 +done
   3.418 +
   3.419 +lemma self_quotient: "[| quorem((a,a),(q,r));  a \<noteq> (0::int) |] ==> q = 1"
   3.420 +apply (simp add: split_ifs quorem_def linorder_neq_iff)
   3.421 +apply (rule order_antisym, safe, simp_all)
   3.422 +apply (rule_tac [3] a = "-a" and r = "-r" in self_quotient_aux1)
   3.423 +apply (rule_tac a = "-a" and r = "-r" in self_quotient_aux2)
   3.424 +apply (force intro: self_quotient_aux1 self_quotient_aux2 simp add: add_commute)+
   3.425 +done
   3.426 +
   3.427 +lemma self_remainder: "[| quorem((a,a),(q,r));  a \<noteq> (0::int) |] ==> r = 0"
   3.428 +apply (frule self_quotient, assumption)
   3.429 +apply (simp add: quorem_def)
   3.430 +done
   3.431 +
   3.432 +lemma zdiv_self [simp]: "a \<noteq> 0 ==> a div a = (1::int)"
   3.433 +by (simp add: quorem_div_mod [THEN self_quotient])
   3.434 +
   3.435 +(*Here we have 0 mod 0 = 0, also assumed by Knuth (who puts m mod 0 = 0) *)
   3.436 +lemma zmod_self [simp]: "a mod a = (0::int)"
   3.437 +apply (case_tac "a = 0", simp)
   3.438 +apply (simp add: quorem_div_mod [THEN self_remainder])
   3.439 +done
   3.440 +
   3.441 +
   3.442 +subsection{*Computation of Division and Remainder*}
   3.443 +
   3.444 +lemma zdiv_zero [simp]: "(0::int) div b = 0"
   3.445 +by (simp add: div_def divAlg_def)
   3.446 +
   3.447 +lemma div_eq_minus1: "(0::int) < b ==> -1 div b = -1"
   3.448 +by (simp add: div_def divAlg_def)
   3.449 +
   3.450 +lemma zmod_zero [simp]: "(0::int) mod b = 0"
   3.451 +by (simp add: mod_def divAlg_def)
   3.452 +
   3.453 +lemma zdiv_minus1: "(0::int) < b ==> -1 div b = -1"
   3.454 +by (simp add: div_def divAlg_def)
   3.455 +
   3.456 +lemma zmod_minus1: "(0::int) < b ==> -1 mod b = b - 1"
   3.457 +by (simp add: mod_def divAlg_def)
   3.458 +
   3.459 +text{*a positive, b positive *}
   3.460 +
   3.461 +lemma div_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a div b = fst (posDivAlg a b)"
   3.462 +by (simp add: div_def divAlg_def)
   3.463 +
   3.464 +lemma mod_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a mod b = snd (posDivAlg a b)"
   3.465 +by (simp add: mod_def divAlg_def)
   3.466 +
   3.467 +text{*a negative, b positive *}
   3.468 +
   3.469 +lemma div_neg_pos: "[| a < 0;  0 < b |] ==> a div b = fst (negDivAlg a b)"
   3.470 +by (simp add: div_def divAlg_def)
   3.471 +
   3.472 +lemma mod_neg_pos: "[| a < 0;  0 < b |] ==> a mod b = snd (negDivAlg a b)"
   3.473 +by (simp add: mod_def divAlg_def)
   3.474 +
   3.475 +text{*a positive, b negative *}
   3.476 +
   3.477 +lemma div_pos_neg:
   3.478 +     "[| 0 < a;  b < 0 |] ==> a div b = fst (negateSnd (negDivAlg (-a) (-b)))"
   3.479 +by (simp add: div_def divAlg_def)
   3.480 +
   3.481 +lemma mod_pos_neg:
   3.482 +     "[| 0 < a;  b < 0 |] ==> a mod b = snd (negateSnd (negDivAlg (-a) (-b)))"
   3.483 +by (simp add: mod_def divAlg_def)
   3.484 +
   3.485 +text{*a negative, b negative *}
   3.486 +
   3.487 +lemma div_neg_neg:
   3.488 +     "[| a < 0;  b \<le> 0 |] ==> a div b = fst (negateSnd (posDivAlg (-a) (-b)))"
   3.489 +by (simp add: div_def divAlg_def)
   3.490 +
   3.491 +lemma mod_neg_neg:
   3.492 +     "[| a < 0;  b \<le> 0 |] ==> a mod b = snd (negateSnd (posDivAlg (-a) (-b)))"
   3.493 +by (simp add: mod_def divAlg_def)
   3.494 +
   3.495 +text {*Simplify expresions in which div and mod combine numerical constants*}
   3.496 +
   3.497 +lemmas div_pos_pos_number_of [simp] =
   3.498 +    div_pos_pos [of "number_of v" "number_of w", standard]
   3.499 +
   3.500 +lemmas div_neg_pos_number_of [simp] =
   3.501 +    div_neg_pos [of "number_of v" "number_of w", standard]
   3.502 +
   3.503 +lemmas div_pos_neg_number_of [simp] =
   3.504 +    div_pos_neg [of "number_of v" "number_of w", standard]
   3.505 +
   3.506 +lemmas div_neg_neg_number_of [simp] =
   3.507 +    div_neg_neg [of "number_of v" "number_of w", standard]
   3.508 +
   3.509 +
   3.510 +lemmas mod_pos_pos_number_of [simp] =
   3.511 +    mod_pos_pos [of "number_of v" "number_of w", standard]
   3.512 +
   3.513 +lemmas mod_neg_pos_number_of [simp] =
   3.514 +    mod_neg_pos [of "number_of v" "number_of w", standard]
   3.515 +
   3.516 +lemmas mod_pos_neg_number_of [simp] =
   3.517 +    mod_pos_neg [of "number_of v" "number_of w", standard]
   3.518 +
   3.519 +lemmas mod_neg_neg_number_of [simp] =
   3.520 +    mod_neg_neg [of "number_of v" "number_of w", standard]
   3.521 +
   3.522 +
   3.523 +lemmas posDivAlg_eqn_number_of [simp] =
   3.524 +    posDivAlg_eqn [of "number_of v" "number_of w", standard]
   3.525 +
   3.526 +lemmas negDivAlg_eqn_number_of [simp] =
   3.527 +    negDivAlg_eqn [of "number_of v" "number_of w", standard]
   3.528 +
   3.529 +
   3.530 +text{*Special-case simplification *}
   3.531 +
   3.532 +lemma zmod_1 [simp]: "a mod (1::int) = 0"
   3.533 +apply (cut_tac a = a and b = 1 in pos_mod_sign)
   3.534 +apply (cut_tac [2] a = a and b = 1 in pos_mod_bound)
   3.535 +apply (auto simp del:pos_mod_bound pos_mod_sign)
   3.536 +done
   3.537 +
   3.538 +lemma zdiv_1 [simp]: "a div (1::int) = a"
   3.539 +by (cut_tac a = a and b = 1 in zmod_zdiv_equality, auto)
   3.540 +
   3.541 +lemma zmod_minus1_right [simp]: "a mod (-1::int) = 0"
   3.542 +apply (cut_tac a = a and b = "-1" in neg_mod_sign)
   3.543 +apply (cut_tac [2] a = a and b = "-1" in neg_mod_bound)
   3.544 +apply (auto simp del: neg_mod_sign neg_mod_bound)
   3.545 +done
   3.546 +
   3.547 +lemma zdiv_minus1_right [simp]: "a div (-1::int) = -a"
   3.548 +by (cut_tac a = a and b = "-1" in zmod_zdiv_equality, auto)
   3.549 +
   3.550 +(** The last remaining special cases for constant arithmetic:
   3.551 +    1 div z and 1 mod z **)
   3.552 +
   3.553 +lemmas div_pos_pos_1_number_of [simp] =
   3.554 +    div_pos_pos [OF int_0_less_1, of "number_of w", standard]
   3.555 +
   3.556 +lemmas div_pos_neg_1_number_of [simp] =
   3.557 +    div_pos_neg [OF int_0_less_1, of "number_of w", standard]
   3.558 +
   3.559 +lemmas mod_pos_pos_1_number_of [simp] =
   3.560 +    mod_pos_pos [OF int_0_less_1, of "number_of w", standard]
   3.561 +
   3.562 +lemmas mod_pos_neg_1_number_of [simp] =
   3.563 +    mod_pos_neg [OF int_0_less_1, of "number_of w", standard]
   3.564 +
   3.565 +
   3.566 +lemmas posDivAlg_eqn_1_number_of [simp] =
   3.567 +    posDivAlg_eqn [of concl: 1 "number_of w", standard]
   3.568 +
   3.569 +lemmas negDivAlg_eqn_1_number_of [simp] =
   3.570 +    negDivAlg_eqn [of concl: 1 "number_of w", standard]
   3.571 +
   3.572 +
   3.573 +
   3.574 +subsection{*Monotonicity in the First Argument (Dividend)*}
   3.575 +
   3.576 +lemma zdiv_mono1: "[| a \<le> a';  0 < (b::int) |] ==> a div b \<le> a' div b"
   3.577 +apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   3.578 +apply (cut_tac a = a' and b = b in zmod_zdiv_equality)
   3.579 +apply (rule unique_quotient_lemma)
   3.580 +apply (erule subst)
   3.581 +apply (erule subst, simp_all)
   3.582 +done
   3.583 +
   3.584 +lemma zdiv_mono1_neg: "[| a \<le> a';  (b::int) < 0 |] ==> a' div b \<le> a div b"
   3.585 +apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   3.586 +apply (cut_tac a = a' and b = b in zmod_zdiv_equality)
   3.587 +apply (rule unique_quotient_lemma_neg)
   3.588 +apply (erule subst)
   3.589 +apply (erule subst, simp_all)
   3.590 +done
   3.591 +
   3.592 +
   3.593 +subsection{*Monotonicity in the Second Argument (Divisor)*}
   3.594 +
   3.595 +lemma q_pos_lemma:
   3.596 +     "[| 0 \<le> b'*q' + r'; r' < b';  0 < b' |] ==> 0 \<le> (q'::int)"
   3.597 +apply (subgoal_tac "0 < b'* (q' + 1) ")
   3.598 + apply (simp add: zero_less_mult_iff)
   3.599 +apply (simp add: right_distrib)
   3.600 +done
   3.601 +
   3.602 +lemma zdiv_mono2_lemma:
   3.603 +     "[| b*q + r = b'*q' + r';  0 \<le> b'*q' + r';   
   3.604 +         r' < b';  0 \<le> r;  0 < b';  b' \<le> b |]   
   3.605 +      ==> q \<le> (q'::int)"
   3.606 +apply (frule q_pos_lemma, assumption+) 
   3.607 +apply (subgoal_tac "b*q < b* (q' + 1) ")
   3.608 + apply (simp add: mult_less_cancel_left)
   3.609 +apply (subgoal_tac "b*q = r' - r + b'*q'")
   3.610 + prefer 2 apply simp
   3.611 +apply (simp (no_asm_simp) add: right_distrib)
   3.612 +apply (subst add_commute, rule zadd_zless_mono, arith)
   3.613 +apply (rule mult_right_mono, auto)
   3.614 +done
   3.615 +
   3.616 +lemma zdiv_mono2:
   3.617 +     "[| (0::int) \<le> a;  0 < b';  b' \<le> b |] ==> a div b \<le> a div b'"
   3.618 +apply (subgoal_tac "b \<noteq> 0")
   3.619 + prefer 2 apply arith
   3.620 +apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   3.621 +apply (cut_tac a = a and b = b' in zmod_zdiv_equality)
   3.622 +apply (rule zdiv_mono2_lemma)
   3.623 +apply (erule subst)
   3.624 +apply (erule subst, simp_all)
   3.625 +done
   3.626 +
   3.627 +lemma q_neg_lemma:
   3.628 +     "[| b'*q' + r' < 0;  0 \<le> r';  0 < b' |] ==> q' \<le> (0::int)"
   3.629 +apply (subgoal_tac "b'*q' < 0")
   3.630 + apply (simp add: mult_less_0_iff, arith)
   3.631 +done
   3.632 +
   3.633 +lemma zdiv_mono2_neg_lemma:
   3.634 +     "[| b*q + r = b'*q' + r';  b'*q' + r' < 0;   
   3.635 +         r < b;  0 \<le> r';  0 < b';  b' \<le> b |]   
   3.636 +      ==> q' \<le> (q::int)"
   3.637 +apply (frule q_neg_lemma, assumption+) 
   3.638 +apply (subgoal_tac "b*q' < b* (q + 1) ")
   3.639 + apply (simp add: mult_less_cancel_left)
   3.640 +apply (simp add: right_distrib)
   3.641 +apply (subgoal_tac "b*q' \<le> b'*q'")
   3.642 + prefer 2 apply (simp add: mult_right_mono_neg, arith)
   3.643 +done
   3.644 +
   3.645 +lemma zdiv_mono2_neg:
   3.646 +     "[| a < (0::int);  0 < b';  b' \<le> b |] ==> a div b' \<le> a div b"
   3.647 +apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   3.648 +apply (cut_tac a = a and b = b' in zmod_zdiv_equality)
   3.649 +apply (rule zdiv_mono2_neg_lemma)
   3.650 +apply (erule subst)
   3.651 +apply (erule subst, simp_all)
   3.652 +done
   3.653 +
   3.654 +subsection{*More Algebraic Laws for div and mod*}
   3.655 +
   3.656 +text{*proving (a*b) div c = a * (b div c) + a * (b mod c) *}
   3.657 +
   3.658 +lemma zmult1_lemma:
   3.659 +     "[| quorem((b,c),(q,r));  c \<noteq> 0 |]  
   3.660 +      ==> quorem ((a*b, c), (a*q + a*r div c, a*r mod c))"
   3.661 +by (force simp add: split_ifs quorem_def linorder_neq_iff right_distrib)
   3.662 +
   3.663 +lemma zdiv_zmult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::int)"
   3.664 +apply (case_tac "c = 0", simp)
   3.665 +apply (blast intro: quorem_div_mod [THEN zmult1_lemma, THEN quorem_div])
   3.666 +done
   3.667 +
   3.668 +lemma zmod_zmult1_eq: "(a*b) mod c = a*(b mod c) mod (c::int)"
   3.669 +apply (case_tac "c = 0", simp)
   3.670 +apply (blast intro: quorem_div_mod [THEN zmult1_lemma, THEN quorem_mod])
   3.671 +done
   3.672 +
   3.673 +lemma zmod_zmult1_eq': "(a*b) mod (c::int) = ((a mod c) * b) mod c"
   3.674 +apply (rule trans)
   3.675 +apply (rule_tac s = "b*a mod c" in trans)
   3.676 +apply (rule_tac [2] zmod_zmult1_eq)
   3.677 +apply (simp_all add: mult_commute)
   3.678 +done
   3.679 +
   3.680 +lemma zmod_zmult_distrib: "(a*b) mod (c::int) = ((a mod c) * (b mod c)) mod c"
   3.681 +apply (rule zmod_zmult1_eq' [THEN trans])
   3.682 +apply (rule zmod_zmult1_eq)
   3.683 +done
   3.684 +
   3.685 +lemma zdiv_zmult_self1 [simp]: "b \<noteq> (0::int) ==> (a*b) div b = a"
   3.686 +by (simp add: zdiv_zmult1_eq)
   3.687 +
   3.688 +lemma zdiv_zmult_self2 [simp]: "b \<noteq> (0::int) ==> (b*a) div b = a"
   3.689 +by (subst mult_commute, erule zdiv_zmult_self1)
   3.690 +
   3.691 +lemma zmod_zmult_self1 [simp]: "(a*b) mod b = (0::int)"
   3.692 +by (simp add: zmod_zmult1_eq)
   3.693 +
   3.694 +lemma zmod_zmult_self2 [simp]: "(b*a) mod b = (0::int)"
   3.695 +by (simp add: mult_commute zmod_zmult1_eq)
   3.696 +
   3.697 +lemma zmod_eq_0_iff: "(m mod d = 0) = (EX q::int. m = d*q)"
   3.698 +proof
   3.699 +  assume "m mod d = 0"
   3.700 +  with zmod_zdiv_equality[of m d] show "EX q::int. m = d*q" by auto
   3.701 +next
   3.702 +  assume "EX q::int. m = d*q"
   3.703 +  thus "m mod d = 0" by auto
   3.704 +qed
   3.705 +
   3.706 +lemmas zmod_eq_0D [dest!] = zmod_eq_0_iff [THEN iffD1]
   3.707 +
   3.708 +text{*proving (a+b) div c = a div c + b div c + ((a mod c + b mod c) div c) *}
   3.709 +
   3.710 +lemma zadd1_lemma:
   3.711 +     "[| quorem((a,c),(aq,ar));  quorem((b,c),(bq,br));  c \<noteq> 0 |]  
   3.712 +      ==> quorem ((a+b, c), (aq + bq + (ar+br) div c, (ar+br) mod c))"
   3.713 +by (force simp add: split_ifs quorem_def linorder_neq_iff right_distrib)
   3.714 +
   3.715 +(*NOT suitable for rewriting: the RHS has an instance of the LHS*)
   3.716 +lemma zdiv_zadd1_eq:
   3.717 +     "(a+b) div (c::int) = a div c + b div c + ((a mod c + b mod c) div c)"
   3.718 +apply (case_tac "c = 0", simp)
   3.719 +apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod] quorem_div)
   3.720 +done
   3.721 +
   3.722 +lemma zmod_zadd1_eq: "(a+b) mod (c::int) = (a mod c + b mod c) mod c"
   3.723 +apply (case_tac "c = 0", simp)
   3.724 +apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod] quorem_mod)
   3.725 +done
   3.726 +
   3.727 +lemma mod_div_trivial [simp]: "(a mod b) div b = (0::int)"
   3.728 +apply (case_tac "b = 0", simp)
   3.729 +apply (auto simp add: linorder_neq_iff div_pos_pos_trivial div_neg_neg_trivial)
   3.730 +done
   3.731 +
   3.732 +lemma mod_mod_trivial [simp]: "(a mod b) mod b = a mod (b::int)"
   3.733 +apply (case_tac "b = 0", simp)
   3.734 +apply (force simp add: linorder_neq_iff mod_pos_pos_trivial mod_neg_neg_trivial)
   3.735 +done
   3.736 +
   3.737 +lemma zmod_zadd_left_eq: "(a+b) mod (c::int) = ((a mod c) + b) mod c"
   3.738 +apply (rule trans [symmetric])
   3.739 +apply (rule zmod_zadd1_eq, simp)
   3.740 +apply (rule zmod_zadd1_eq [symmetric])
   3.741 +done
   3.742 +
   3.743 +lemma zmod_zadd_right_eq: "(a+b) mod (c::int) = (a + (b mod c)) mod c"
   3.744 +apply (rule trans [symmetric])
   3.745 +apply (rule zmod_zadd1_eq, simp)
   3.746 +apply (rule zmod_zadd1_eq [symmetric])
   3.747 +done
   3.748 +
   3.749 +lemma zdiv_zadd_self1[simp]: "a \<noteq> (0::int) ==> (a+b) div a = b div a + 1"
   3.750 +by (simp add: zdiv_zadd1_eq)
   3.751 +
   3.752 +lemma zdiv_zadd_self2[simp]: "a \<noteq> (0::int) ==> (b+a) div a = b div a + 1"
   3.753 +by (simp add: zdiv_zadd1_eq)
   3.754 +
   3.755 +lemma zmod_zadd_self1[simp]: "(a+b) mod a = b mod (a::int)"
   3.756 +apply (case_tac "a = 0", simp)
   3.757 +apply (simp add: zmod_zadd1_eq)
   3.758 +done
   3.759 +
   3.760 +lemma zmod_zadd_self2[simp]: "(b+a) mod a = b mod (a::int)"
   3.761 +apply (case_tac "a = 0", simp)
   3.762 +apply (simp add: zmod_zadd1_eq)
   3.763 +done
   3.764 +
   3.765 +
   3.766 +subsection{*Proving  @{term "a div (b*c) = (a div b) div c"} *}
   3.767 +
   3.768 +(*The condition c>0 seems necessary.  Consider that 7 div ~6 = ~2 but
   3.769 +  7 div 2 div ~3 = 3 div ~3 = ~1.  The subcase (a div b) mod c = 0 seems
   3.770 +  to cause particular problems.*)
   3.771 +
   3.772 +text{*first, four lemmas to bound the remainder for the cases b<0 and b>0 *}
   3.773 +
   3.774 +lemma zmult2_lemma_aux1: "[| (0::int) < c;  b < r;  r \<le> 0 |] ==> b*c < b*(q mod c) + r"
   3.775 +apply (subgoal_tac "b * (c - q mod c) < r * 1")
   3.776 +apply (simp add: right_diff_distrib)
   3.777 +apply (rule order_le_less_trans)
   3.778 +apply (erule_tac [2] mult_strict_right_mono)
   3.779 +apply (rule mult_left_mono_neg)
   3.780 +apply (auto simp add: compare_rls add_commute [of 1]
   3.781 +                      add1_zle_eq pos_mod_bound)
   3.782 +done
   3.783 +
   3.784 +lemma zmult2_lemma_aux2:
   3.785 +     "[| (0::int) < c;   b < r;  r \<le> 0 |] ==> b * (q mod c) + r \<le> 0"
   3.786 +apply (subgoal_tac "b * (q mod c) \<le> 0")
   3.787 + apply arith
   3.788 +apply (simp add: mult_le_0_iff)
   3.789 +done
   3.790 +
   3.791 +lemma zmult2_lemma_aux3: "[| (0::int) < c;  0 \<le> r;  r < b |] ==> 0 \<le> b * (q mod c) + r"
   3.792 +apply (subgoal_tac "0 \<le> b * (q mod c) ")
   3.793 +apply arith
   3.794 +apply (simp add: zero_le_mult_iff)
   3.795 +done
   3.796 +
   3.797 +lemma zmult2_lemma_aux4: "[| (0::int) < c; 0 \<le> r; r < b |] ==> b * (q mod c) + r < b * c"
   3.798 +apply (subgoal_tac "r * 1 < b * (c - q mod c) ")
   3.799 +apply (simp add: right_diff_distrib)
   3.800 +apply (rule order_less_le_trans)
   3.801 +apply (erule mult_strict_right_mono)
   3.802 +apply (rule_tac [2] mult_left_mono)
   3.803 +apply (auto simp add: compare_rls add_commute [of 1]
   3.804 +                      add1_zle_eq pos_mod_bound)
   3.805 +done
   3.806 +
   3.807 +lemma zmult2_lemma: "[| quorem ((a,b), (q,r));  b \<noteq> 0;  0 < c |]  
   3.808 +      ==> quorem ((a, b*c), (q div c, b*(q mod c) + r))"
   3.809 +by (auto simp add: mult_ac quorem_def linorder_neq_iff
   3.810 +                   zero_less_mult_iff right_distrib [symmetric] 
   3.811 +                   zmult2_lemma_aux1 zmult2_lemma_aux2 zmult2_lemma_aux3 zmult2_lemma_aux4)
   3.812 +
   3.813 +lemma zdiv_zmult2_eq: "(0::int) < c ==> a div (b*c) = (a div b) div c"
   3.814 +apply (case_tac "b = 0", simp)
   3.815 +apply (force simp add: quorem_div_mod [THEN zmult2_lemma, THEN quorem_div])
   3.816 +done
   3.817 +
   3.818 +lemma zmod_zmult2_eq:
   3.819 +     "(0::int) < c ==> a mod (b*c) = b*(a div b mod c) + a mod b"
   3.820 +apply (case_tac "b = 0", simp)
   3.821 +apply (force simp add: quorem_div_mod [THEN zmult2_lemma, THEN quorem_mod])
   3.822 +done
   3.823 +
   3.824 +
   3.825 +subsection{*Cancellation of Common Factors in div*}
   3.826 +
   3.827 +lemma zdiv_zmult_zmult1_aux1:
   3.828 +     "[| (0::int) < b;  c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
   3.829 +by (subst zdiv_zmult2_eq, auto)
   3.830 +
   3.831 +lemma zdiv_zmult_zmult1_aux2:
   3.832 +     "[| b < (0::int);  c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
   3.833 +apply (subgoal_tac " (c * (-a)) div (c * (-b)) = (-a) div (-b) ")
   3.834 +apply (rule_tac [2] zdiv_zmult_zmult1_aux1, auto)
   3.835 +done
   3.836 +
   3.837 +lemma zdiv_zmult_zmult1: "c \<noteq> (0::int) ==> (c*a) div (c*b) = a div b"
   3.838 +apply (case_tac "b = 0", simp)
   3.839 +apply (auto simp add: linorder_neq_iff zdiv_zmult_zmult1_aux1 zdiv_zmult_zmult1_aux2)
   3.840 +done
   3.841 +
   3.842 +lemma zdiv_zmult_zmult2: "c \<noteq> (0::int) ==> (a*c) div (b*c) = a div b"
   3.843 +apply (drule zdiv_zmult_zmult1)
   3.844 +apply (auto simp add: mult_commute)
   3.845 +done
   3.846 +
   3.847 +
   3.848 +
   3.849 +subsection{*Distribution of Factors over mod*}
   3.850 +
   3.851 +lemma zmod_zmult_zmult1_aux1:
   3.852 +     "[| (0::int) < b;  c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
   3.853 +by (subst zmod_zmult2_eq, auto)
   3.854 +
   3.855 +lemma zmod_zmult_zmult1_aux2:
   3.856 +     "[| b < (0::int);  c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
   3.857 +apply (subgoal_tac " (c * (-a)) mod (c * (-b)) = c * ((-a) mod (-b))")
   3.858 +apply (rule_tac [2] zmod_zmult_zmult1_aux1, auto)
   3.859 +done
   3.860 +
   3.861 +lemma zmod_zmult_zmult1: "(c*a) mod (c*b) = (c::int) * (a mod b)"
   3.862 +apply (case_tac "b = 0", simp)
   3.863 +apply (case_tac "c = 0", simp)
   3.864 +apply (auto simp add: linorder_neq_iff zmod_zmult_zmult1_aux1 zmod_zmult_zmult1_aux2)
   3.865 +done
   3.866 +
   3.867 +lemma zmod_zmult_zmult2: "(a*c) mod (b*c) = (a mod b) * (c::int)"
   3.868 +apply (cut_tac c = c in zmod_zmult_zmult1)
   3.869 +apply (auto simp add: mult_commute)
   3.870 +done
   3.871 +
   3.872 +
   3.873 +subsection {*Splitting Rules for div and mod*}
   3.874 +
   3.875 +text{*The proofs of the two lemmas below are essentially identical*}
   3.876 +
   3.877 +lemma split_pos_lemma:
   3.878 + "0<k ==> 
   3.879 +    P(n div k :: int)(n mod k) = (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P i j)"
   3.880 +apply (rule iffI, clarify)
   3.881 + apply (erule_tac P="P ?x ?y" in rev_mp)  
   3.882 + apply (subst zmod_zadd1_eq) 
   3.883 + apply (subst zdiv_zadd1_eq) 
   3.884 + apply (simp add: div_pos_pos_trivial mod_pos_pos_trivial)  
   3.885 +txt{*converse direction*}
   3.886 +apply (drule_tac x = "n div k" in spec) 
   3.887 +apply (drule_tac x = "n mod k" in spec, simp)
   3.888 +done
   3.889 +
   3.890 +lemma split_neg_lemma:
   3.891 + "k<0 ==>
   3.892 +    P(n div k :: int)(n mod k) = (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P i j)"
   3.893 +apply (rule iffI, clarify)
   3.894 + apply (erule_tac P="P ?x ?y" in rev_mp)  
   3.895 + apply (subst zmod_zadd1_eq) 
   3.896 + apply (subst zdiv_zadd1_eq) 
   3.897 + apply (simp add: div_neg_neg_trivial mod_neg_neg_trivial)  
   3.898 +txt{*converse direction*}
   3.899 +apply (drule_tac x = "n div k" in spec) 
   3.900 +apply (drule_tac x = "n mod k" in spec, simp)
   3.901 +done
   3.902 +
   3.903 +lemma split_zdiv:
   3.904 + "P(n div k :: int) =
   3.905 +  ((k = 0 --> P 0) & 
   3.906 +   (0<k --> (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P i)) & 
   3.907 +   (k<0 --> (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P i)))"
   3.908 +apply (case_tac "k=0", simp)
   3.909 +apply (simp only: linorder_neq_iff)
   3.910 +apply (erule disjE) 
   3.911 + apply (simp_all add: split_pos_lemma [of concl: "%x y. P x"] 
   3.912 +                      split_neg_lemma [of concl: "%x y. P x"])
   3.913 +done
   3.914 +
   3.915 +lemma split_zmod:
   3.916 + "P(n mod k :: int) =
   3.917 +  ((k = 0 --> P n) & 
   3.918 +   (0<k --> (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P j)) & 
   3.919 +   (k<0 --> (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P j)))"
   3.920 +apply (case_tac "k=0", simp)
   3.921 +apply (simp only: linorder_neq_iff)
   3.922 +apply (erule disjE) 
   3.923 + apply (simp_all add: split_pos_lemma [of concl: "%x y. P y"] 
   3.924 +                      split_neg_lemma [of concl: "%x y. P y"])
   3.925 +done
   3.926 +
   3.927 +(* Enable arith to deal with div 2 and mod 2: *)
   3.928 +declare split_zdiv [of _ _ "number_of k", simplified, standard, arith_split]
   3.929 +declare split_zmod [of _ _ "number_of k", simplified, standard, arith_split]
   3.930 +
   3.931 +
   3.932 +subsection{*Speeding up the Division Algorithm with Shifting*}
   3.933 +
   3.934 +text{*computing div by shifting *}
   3.935 +
   3.936 +lemma pos_zdiv_mult_2: "(0::int) \<le> a ==> (1 + 2*b) div (2*a) = b div a"
   3.937 +proof cases
   3.938 +  assume "a=0"
   3.939 +    thus ?thesis by simp
   3.940 +next
   3.941 +  assume "a\<noteq>0" and le_a: "0\<le>a"   
   3.942 +  hence a_pos: "1 \<le> a" by arith
   3.943 +  hence one_less_a2: "1 < 2*a" by arith
   3.944 +  hence le_2a: "2 * (1 + b mod a) \<le> 2 * a"
   3.945 +    by (simp add: mult_le_cancel_left add_commute [of 1] add1_zle_eq)
   3.946 +  with a_pos have "0 \<le> b mod a" by simp
   3.947 +  hence le_addm: "0 \<le> 1 mod (2*a) + 2*(b mod a)"
   3.948 +    by (simp add: mod_pos_pos_trivial one_less_a2)
   3.949 +  with  le_2a
   3.950 +  have "(1 mod (2*a) + 2*(b mod a)) div (2*a) = 0"
   3.951 +    by (simp add: div_pos_pos_trivial le_addm mod_pos_pos_trivial one_less_a2
   3.952 +                  right_distrib) 
   3.953 +  thus ?thesis
   3.954 +    by (subst zdiv_zadd1_eq,
   3.955 +        simp add: zdiv_zmult_zmult1 zmod_zmult_zmult1 one_less_a2
   3.956 +                  div_pos_pos_trivial)
   3.957 +qed
   3.958 +
   3.959 +lemma neg_zdiv_mult_2: "a \<le> (0::int) ==> (1 + 2*b) div (2*a) = (b+1) div a"
   3.960 +apply (subgoal_tac " (1 + 2* (-b - 1)) div (2 * (-a)) = (-b - 1) div (-a) ")
   3.961 +apply (rule_tac [2] pos_zdiv_mult_2)
   3.962 +apply (auto simp add: minus_mult_right [symmetric] right_diff_distrib)
   3.963 +apply (subgoal_tac " (-1 - (2 * b)) = - (1 + (2 * b))")
   3.964 +apply (simp only: zdiv_zminus_zminus diff_minus minus_add_distrib [symmetric],
   3.965 +       simp) 
   3.966 +done
   3.967 +
   3.968 +
   3.969 +(*Not clear why this must be proved separately; probably number_of causes
   3.970 +  simplification problems*)
   3.971 +lemma not_0_le_lemma: "~ 0 \<le> x ==> x \<le> (0::int)"
   3.972 +by auto
   3.973 +
   3.974 +lemma zdiv_number_of_BIT[simp]:
   3.975 +     "number_of (v BIT b) div number_of (w BIT bit.B0) =  
   3.976 +          (if b=bit.B0 | (0::int) \<le> number_of w                    
   3.977 +           then number_of v div (number_of w)     
   3.978 +           else (number_of v + (1::int)) div (number_of w))"
   3.979 +apply (simp only: number_of_eq numeral_simps UNIV_I split: split_if) 
   3.980 +apply (simp add: zdiv_zmult_zmult1 pos_zdiv_mult_2 neg_zdiv_mult_2 add_ac 
   3.981 +            split: bit.split)
   3.982 +done
   3.983 +
   3.984 +
   3.985 +subsection{*Computing mod by Shifting (proofs resemble those for div)*}
   3.986 +
   3.987 +lemma pos_zmod_mult_2:
   3.988 +     "(0::int) \<le> a ==> (1 + 2*b) mod (2*a) = 1 + 2 * (b mod a)"
   3.989 +apply (case_tac "a = 0", simp)
   3.990 +apply (subgoal_tac "1 < a * 2")
   3.991 + prefer 2 apply arith
   3.992 +apply (subgoal_tac "2* (1 + b mod a) \<le> 2*a")
   3.993 + apply (rule_tac [2] mult_left_mono)
   3.994 +apply (auto simp add: add_commute [of 1] mult_commute add1_zle_eq 
   3.995 +                      pos_mod_bound)
   3.996 +apply (subst zmod_zadd1_eq)
   3.997 +apply (simp add: zmod_zmult_zmult2 mod_pos_pos_trivial)
   3.998 +apply (rule mod_pos_pos_trivial)
   3.999 +apply (auto simp add: mod_pos_pos_trivial left_distrib)
  3.1000 +apply (subgoal_tac "0 \<le> b mod a", arith, simp)
  3.1001 +done
  3.1002 +
  3.1003 +lemma neg_zmod_mult_2:
  3.1004 +     "a \<le> (0::int) ==> (1 + 2*b) mod (2*a) = 2 * ((b+1) mod a) - 1"
  3.1005 +apply (subgoal_tac "(1 + 2* (-b - 1)) mod (2* (-a)) = 
  3.1006 +                    1 + 2* ((-b - 1) mod (-a))")
  3.1007 +apply (rule_tac [2] pos_zmod_mult_2)
  3.1008 +apply (auto simp add: minus_mult_right [symmetric] right_diff_distrib)
  3.1009 +apply (subgoal_tac " (-1 - (2 * b)) = - (1 + (2 * b))")
  3.1010 + prefer 2 apply simp 
  3.1011 +apply (simp only: zmod_zminus_zminus diff_minus minus_add_distrib [symmetric])
  3.1012 +done
  3.1013 +
  3.1014 +lemma zmod_number_of_BIT [simp]:
  3.1015 +     "number_of (v BIT b) mod number_of (w BIT bit.B0) =  
  3.1016 +      (case b of
  3.1017 +          bit.B0 => 2 * (number_of v mod number_of w)
  3.1018 +        | bit.B1 => if (0::int) \<le> number_of w  
  3.1019 +                then 2 * (number_of v mod number_of w) + 1     
  3.1020 +                else 2 * ((number_of v + (1::int)) mod number_of w) - 1)"
  3.1021 +apply (simp only: number_of_eq numeral_simps UNIV_I split: bit.split) 
  3.1022 +apply (simp add: zmod_zmult_zmult1 pos_zmod_mult_2 
  3.1023 +                 not_0_le_lemma neg_zmod_mult_2 add_ac)
  3.1024 +done
  3.1025 +
  3.1026 +
  3.1027 +subsection{*Quotients of Signs*}
  3.1028 +
  3.1029 +lemma div_neg_pos_less0: "[| a < (0::int);  0 < b |] ==> a div b < 0"
  3.1030 +apply (subgoal_tac "a div b \<le> -1", force)
  3.1031 +apply (rule order_trans)
  3.1032 +apply (rule_tac a' = "-1" in zdiv_mono1)
  3.1033 +apply (auto simp add: zdiv_minus1)
  3.1034 +done
  3.1035 +
  3.1036 +lemma div_nonneg_neg_le0: "[| (0::int) \<le> a;  b < 0 |] ==> a div b \<le> 0"
  3.1037 +by (drule zdiv_mono1_neg, auto)
  3.1038 +
  3.1039 +lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)"
  3.1040 +apply auto
  3.1041 +apply (drule_tac [2] zdiv_mono1)
  3.1042 +apply (auto simp add: linorder_neq_iff)
  3.1043 +apply (simp (no_asm_use) add: linorder_not_less [symmetric])
  3.1044 +apply (blast intro: div_neg_pos_less0)
  3.1045 +done
  3.1046 +
  3.1047 +lemma neg_imp_zdiv_nonneg_iff:
  3.1048 +     "b < (0::int) ==> (0 \<le> a div b) = (a \<le> (0::int))"
  3.1049 +apply (subst zdiv_zminus_zminus [symmetric])
  3.1050 +apply (subst pos_imp_zdiv_nonneg_iff, auto)
  3.1051 +done
  3.1052 +
  3.1053 +(*But not (a div b \<le> 0 iff a\<le>0); consider a=1, b=2 when a div b = 0.*)
  3.1054 +lemma pos_imp_zdiv_neg_iff: "(0::int) < b ==> (a div b < 0) = (a < 0)"
  3.1055 +by (simp add: linorder_not_le [symmetric] pos_imp_zdiv_nonneg_iff)
  3.1056 +
  3.1057 +(*Again the law fails for \<le>: consider a = -1, b = -2 when a div b = 0*)
  3.1058 +lemma neg_imp_zdiv_neg_iff: "b < (0::int) ==> (a div b < 0) = (0 < a)"
  3.1059 +by (simp add: linorder_not_le [symmetric] neg_imp_zdiv_nonneg_iff)
  3.1060 +
  3.1061 +
  3.1062 +subsection {* The Divides Relation *}
  3.1063 +
  3.1064 +lemma zdvd_iff_zmod_eq_0: "(m dvd n) = (n mod m = (0::int))"
  3.1065 +by(simp add:dvd_def zmod_eq_0_iff)
  3.1066 +
  3.1067 +lemmas zdvd_iff_zmod_eq_0_number_of [simp] =
  3.1068 +  zdvd_iff_zmod_eq_0 [of "number_of x" "number_of y", standard]
  3.1069 +
  3.1070 +lemma zdvd_0_right [iff]: "(m::int) dvd 0"
  3.1071 +by (simp add: dvd_def)
  3.1072 +
  3.1073 +lemma zdvd_0_left [iff]: "(0 dvd (m::int)) = (m = 0)"
  3.1074 +  by (simp add: dvd_def)
  3.1075 +
  3.1076 +lemma zdvd_1_left [iff]: "1 dvd (m::int)"
  3.1077 +  by (simp add: dvd_def)
  3.1078 +
  3.1079 +lemma zdvd_refl [simp]: "m dvd (m::int)"
  3.1080 +by (auto simp add: dvd_def intro: zmult_1_right [symmetric])
  3.1081 +
  3.1082 +lemma zdvd_trans: "m dvd n ==> n dvd k ==> m dvd (k::int)"
  3.1083 +by (auto simp add: dvd_def intro: mult_assoc)
  3.1084 +
  3.1085 +lemma zdvd_zminus_iff: "(m dvd -n) = (m dvd (n::int))"
  3.1086 +  apply (simp add: dvd_def, auto)
  3.1087 +   apply (rule_tac [!] x = "-k" in exI, auto)
  3.1088 +  done
  3.1089 +
  3.1090 +lemma zdvd_zminus2_iff: "(-m dvd n) = (m dvd (n::int))"
  3.1091 +  apply (simp add: dvd_def, auto)
  3.1092 +   apply (rule_tac [!] x = "-k" in exI, auto)
  3.1093 +  done
  3.1094 +lemma zdvd_abs1: "( \<bar>i::int\<bar> dvd j) = (i dvd j)" 
  3.1095 +  apply (cases "i > 0", simp)
  3.1096 +  apply (simp add: dvd_def)
  3.1097 +  apply (rule iffI)
  3.1098 +  apply (erule exE)
  3.1099 +  apply (rule_tac x="- k" in exI, simp)
  3.1100 +  apply (erule exE)
  3.1101 +  apply (rule_tac x="- k" in exI, simp)
  3.1102 +  done
  3.1103 +lemma zdvd_abs2: "( (i::int) dvd \<bar>j\<bar>) = (i dvd j)" 
  3.1104 +  apply (cases "j > 0", simp)
  3.1105 +  apply (simp add: dvd_def)
  3.1106 +  apply (rule iffI)
  3.1107 +  apply (erule exE)
  3.1108 +  apply (rule_tac x="- k" in exI, simp)
  3.1109 +  apply (erule exE)
  3.1110 +  apply (rule_tac x="- k" in exI, simp)
  3.1111 +  done
  3.1112 +
  3.1113 +lemma zdvd_anti_sym:
  3.1114 +    "0 < m ==> 0 < n ==> m dvd n ==> n dvd m ==> m = (n::int)"
  3.1115 +  apply (simp add: dvd_def, auto)
  3.1116 +  apply (simp add: mult_assoc zero_less_mult_iff zmult_eq_1_iff)
  3.1117 +  done
  3.1118 +
  3.1119 +lemma zdvd_zadd: "k dvd m ==> k dvd n ==> k dvd (m + n :: int)"
  3.1120 +  apply (simp add: dvd_def)
  3.1121 +  apply (blast intro: right_distrib [symmetric])
  3.1122 +  done
  3.1123 +
  3.1124 +lemma zdvd_dvd_eq: assumes anz:"a \<noteq> 0" and ab: "(a::int) dvd b" and ba:"b dvd a" 
  3.1125 +  shows "\<bar>a\<bar> = \<bar>b\<bar>"
  3.1126 +proof-
  3.1127 +  from ab obtain k where k:"b = a*k" unfolding dvd_def by blast 
  3.1128 +  from ba obtain k' where k':"a = b*k'" unfolding dvd_def by blast 
  3.1129 +  from k k' have "a = a*k*k'" by simp
  3.1130 +  with mult_cancel_left1[where c="a" and b="k*k'"]
  3.1131 +  have kk':"k*k' = 1" using anz by (simp add: mult_assoc)
  3.1132 +  hence "k = 1 \<and> k' = 1 \<or> k = -1 \<and> k' = -1" by (simp add: zmult_eq_1_iff)
  3.1133 +  thus ?thesis using k k' by auto
  3.1134 +qed
  3.1135 +
  3.1136 +lemma zdvd_zdiff: "k dvd m ==> k dvd n ==> k dvd (m - n :: int)"
  3.1137 +  apply (simp add: dvd_def)
  3.1138 +  apply (blast intro: right_diff_distrib [symmetric])
  3.1139 +  done
  3.1140 +
  3.1141 +lemma zdvd_zdiffD: "k dvd m - n ==> k dvd n ==> k dvd (m::int)"
  3.1142 +  apply (subgoal_tac "m = n + (m - n)")
  3.1143 +   apply (erule ssubst)
  3.1144 +   apply (blast intro: zdvd_zadd, simp)
  3.1145 +  done
  3.1146 +
  3.1147 +lemma zdvd_zmult: "k dvd (n::int) ==> k dvd m * n"
  3.1148 +  apply (simp add: dvd_def)
  3.1149 +  apply (blast intro: mult_left_commute)
  3.1150 +  done
  3.1151 +
  3.1152 +lemma zdvd_zmult2: "k dvd (m::int) ==> k dvd m * n"
  3.1153 +  apply (subst mult_commute)
  3.1154 +  apply (erule zdvd_zmult)
  3.1155 +  done
  3.1156 +
  3.1157 +lemma zdvd_triv_right [iff]: "(k::int) dvd m * k"
  3.1158 +  apply (rule zdvd_zmult)
  3.1159 +  apply (rule zdvd_refl)
  3.1160 +  done
  3.1161 +
  3.1162 +lemma zdvd_triv_left [iff]: "(k::int) dvd k * m"
  3.1163 +  apply (rule zdvd_zmult2)
  3.1164 +  apply (rule zdvd_refl)
  3.1165 +  done
  3.1166 +
  3.1167 +lemma zdvd_zmultD2: "j * k dvd n ==> j dvd (n::int)"
  3.1168 +  apply (simp add: dvd_def)
  3.1169 +  apply (simp add: mult_assoc, blast)
  3.1170 +  done
  3.1171 +
  3.1172 +lemma zdvd_zmultD: "j * k dvd n ==> k dvd (n::int)"
  3.1173 +  apply (rule zdvd_zmultD2)
  3.1174 +  apply (subst mult_commute, assumption)
  3.1175 +  done
  3.1176 +
  3.1177 +lemma zdvd_zmult_mono: "i dvd m ==> j dvd (n::int) ==> i * j dvd m * n"
  3.1178 +  apply (simp add: dvd_def, clarify)
  3.1179 +  apply (rule_tac x = "k * ka" in exI)
  3.1180 +  apply (simp add: mult_ac)
  3.1181 +  done
  3.1182 +
  3.1183 +lemma zdvd_reduce: "(k dvd n + k * m) = (k dvd (n::int))"
  3.1184 +  apply (rule iffI)
  3.1185 +   apply (erule_tac [2] zdvd_zadd)
  3.1186 +   apply (subgoal_tac "n = (n + k * m) - k * m")
  3.1187 +    apply (erule ssubst)
  3.1188 +    apply (erule zdvd_zdiff, simp_all)
  3.1189 +  done
  3.1190 +
  3.1191 +lemma zdvd_zmod: "f dvd m ==> f dvd (n::int) ==> f dvd m mod n"
  3.1192 +  apply (simp add: dvd_def)
  3.1193 +  apply (auto simp add: zmod_zmult_zmult1)
  3.1194 +  done
  3.1195 +
  3.1196 +lemma zdvd_zmod_imp_zdvd: "k dvd m mod n ==> k dvd n ==> k dvd (m::int)"
  3.1197 +  apply (subgoal_tac "k dvd n * (m div n) + m mod n")
  3.1198 +   apply (simp add: zmod_zdiv_equality [symmetric])
  3.1199 +  apply (simp only: zdvd_zadd zdvd_zmult2)
  3.1200 +  done
  3.1201 +
  3.1202 +lemma zdvd_not_zless: "0 < m ==> m < n ==> \<not> n dvd (m::int)"
  3.1203 +  apply (simp add: dvd_def, auto)
  3.1204 +  apply (subgoal_tac "0 < n")
  3.1205 +   prefer 2
  3.1206 +   apply (blast intro: order_less_trans)
  3.1207 +  apply (simp add: zero_less_mult_iff)
  3.1208 +  apply (subgoal_tac "n * k < n * 1")
  3.1209 +   apply (drule mult_less_cancel_left [THEN iffD1], auto)
  3.1210 +  done
  3.1211 +lemma zmult_div_cancel: "(n::int) * (m div n) = m - (m mod n)"
  3.1212 +  using zmod_zdiv_equality[where a="m" and b="n"]
  3.1213 +  by (simp add: ring_eq_simps)
  3.1214 +
  3.1215 +lemma zdvd_mult_div_cancel:"(n::int) dvd m \<Longrightarrow> n * (m div n) = m"
  3.1216 +apply (subgoal_tac "m mod n = 0")
  3.1217 + apply (simp add: zmult_div_cancel)
  3.1218 +apply (simp only: zdvd_iff_zmod_eq_0)
  3.1219 +done
  3.1220 +
  3.1221 +lemma zdvd_mult_cancel: assumes d:"k * m dvd k * n" and kz:"k \<noteq> (0::int)"
  3.1222 +  shows "m dvd n"
  3.1223 +proof-
  3.1224 +  from d obtain h where h: "k*n = k*m * h" unfolding dvd_def by blast
  3.1225 +  {assume "n \<noteq> m*h" hence "k* n \<noteq> k* (m*h)" using kz by simp
  3.1226 +    with h have False by (simp add: mult_assoc)}
  3.1227 +  hence "n = m * h" by blast
  3.1228 +  thus ?thesis by blast
  3.1229 +qed
  3.1230 +
  3.1231 +theorem ex_nat: "(\<exists>x::nat. P x) = (\<exists>x::int. 0 <= x \<and> P (nat x))"
  3.1232 +  apply (simp split add: split_nat)
  3.1233 +  apply (rule iffI)
  3.1234 +  apply (erule exE)
  3.1235 +  apply (rule_tac x = "int x" in exI)
  3.1236 +  apply simp
  3.1237 +  apply (erule exE)
  3.1238 +  apply (rule_tac x = "nat x" in exI)
  3.1239 +  apply (erule conjE)
  3.1240 +  apply (erule_tac x = "nat x" in allE)
  3.1241 +  apply simp
  3.1242 +  done
  3.1243 +
  3.1244 +theorem zdvd_int: "(x dvd y) = (int x dvd int y)"
  3.1245 +  apply (simp only: dvd_def ex_nat int_int_eq [symmetric] zmult_int [symmetric]
  3.1246 +    nat_0_le cong add: conj_cong)
  3.1247 +  apply (rule iffI)
  3.1248 +  apply iprover
  3.1249 +  apply (erule exE)
  3.1250 +  apply (case_tac "x=0")
  3.1251 +  apply (rule_tac x=0 in exI)
  3.1252 +  apply simp
  3.1253 +  apply (case_tac "0 \<le> k")
  3.1254 +  apply iprover
  3.1255 +  apply (simp add: linorder_not_le)
  3.1256 +  apply (drule mult_strict_left_mono_neg [OF iffD2 [OF zero_less_int_conv]])
  3.1257 +  apply assumption
  3.1258 +  apply (simp add: mult_ac)
  3.1259 +  done
  3.1260 +
  3.1261 +lemma zdvd1_eq[simp]: "(x::int) dvd 1 = ( \<bar>x\<bar> = 1)"
  3.1262 +proof
  3.1263 +  assume d: "x dvd 1" hence "int (nat \<bar>x\<bar>) dvd int (nat 1)" by (simp add: zdvd_abs1)
  3.1264 +  hence "nat \<bar>x\<bar> dvd 1" by (simp add: zdvd_int)
  3.1265 +  hence "nat \<bar>x\<bar> = 1"  by simp
  3.1266 +  thus "\<bar>x\<bar> = 1" by (cases "x < 0", auto)
  3.1267 +next
  3.1268 +  assume "\<bar>x\<bar>=1" thus "x dvd 1" 
  3.1269 +    by(cases "x < 0",simp_all add: minus_equation_iff zdvd_iff_zmod_eq_0)
  3.1270 +qed
  3.1271 +lemma zdvd_mult_cancel1: 
  3.1272 +  assumes mp:"m \<noteq>(0::int)" shows "(m * n dvd m) = (\<bar>n\<bar> = 1)"
  3.1273 +proof
  3.1274 +  assume n1: "\<bar>n\<bar> = 1" thus "m * n dvd m" 
  3.1275 +    by (cases "n >0", auto simp add: zdvd_zminus2_iff minus_equation_iff)
  3.1276 +next
  3.1277 +  assume H: "m * n dvd m" hence H2: "m * n dvd m * 1" by simp
  3.1278 +  from zdvd_mult_cancel[OF H2 mp] show "\<bar>n\<bar> = 1" by (simp only: zdvd1_eq)
  3.1279 +qed
  3.1280 +
  3.1281 +lemma int_dvd_iff: "(int m dvd z) = (m dvd nat (abs z))"
  3.1282 +  apply (auto simp add: dvd_def nat_abs_mult_distrib)
  3.1283 +  apply (auto simp add: nat_eq_iff abs_if split add: split_if_asm)
  3.1284 +   apply (rule_tac x = "-(int k)" in exI)
  3.1285 +  apply (auto simp add: int_mult)
  3.1286 +  done
  3.1287 +
  3.1288 +lemma dvd_int_iff: "(z dvd int m) = (nat (abs z) dvd m)"
  3.1289 +  apply (auto simp add: dvd_def abs_if int_mult)
  3.1290 +    apply (rule_tac [3] x = "nat k" in exI)
  3.1291 +    apply (rule_tac [2] x = "-(int k)" in exI)
  3.1292 +    apply (rule_tac x = "nat (-k)" in exI)
  3.1293 +    apply (cut_tac [3] k = m in int_less_0_conv)
  3.1294 +    apply (cut_tac k = m in int_less_0_conv)
  3.1295 +    apply (auto simp add: zero_le_mult_iff mult_less_0_iff
  3.1296 +      nat_mult_distrib [symmetric] nat_eq_iff2)
  3.1297 +  done
  3.1298 +
  3.1299 +lemma nat_dvd_iff: "(nat z dvd m) = (if 0 \<le> z then (z dvd int m) else m = 0)"
  3.1300 +  apply (auto simp add: dvd_def int_mult)
  3.1301 +  apply (rule_tac x = "nat k" in exI)
  3.1302 +  apply (cut_tac k = m in int_less_0_conv)
  3.1303 +  apply (auto simp add: zero_le_mult_iff mult_less_0_iff
  3.1304 +    nat_mult_distrib [symmetric] nat_eq_iff2)
  3.1305 +  done
  3.1306 +
  3.1307 +lemma zminus_dvd_iff [iff]: "(-z dvd w) = (z dvd (w::int))"
  3.1308 +  apply (auto simp add: dvd_def)
  3.1309 +   apply (rule_tac [!] x = "-k" in exI, auto)
  3.1310 +  done
  3.1311 +
  3.1312 +lemma dvd_zminus_iff [iff]: "(z dvd -w) = (z dvd (w::int))"
  3.1313 +  apply (auto simp add: dvd_def)
  3.1314 +   apply (drule minus_equation_iff [THEN iffD1])
  3.1315 +   apply (rule_tac [!] x = "-k" in exI, auto)
  3.1316 +  done
  3.1317 +
  3.1318 +lemma zdvd_imp_le: "[| z dvd n; 0 < n |] ==> z \<le> (n::int)"
  3.1319 +  apply (rule_tac z=n in int_cases)
  3.1320 +  apply (auto simp add: dvd_int_iff) 
  3.1321 +  apply (rule_tac z=z in int_cases) 
  3.1322 +  apply (auto simp add: dvd_imp_le) 
  3.1323 +  done
  3.1324 +
  3.1325 +
  3.1326 +subsection{*Integer Powers*} 
  3.1327 +
  3.1328 +instance int :: power ..
  3.1329 +
  3.1330 +primrec
  3.1331 +  "p ^ 0 = 1"
  3.1332 +  "p ^ (Suc n) = (p::int) * (p ^ n)"
  3.1333 +
  3.1334 +
  3.1335 +instance int :: recpower
  3.1336 +proof
  3.1337 +  fix z :: int
  3.1338 +  fix n :: nat
  3.1339 +  show "z^0 = 1" by simp
  3.1340 +  show "z^(Suc n) = z * (z^n)" by simp
  3.1341 +qed
  3.1342 +
  3.1343 +
  3.1344 +lemma zpower_zmod: "((x::int) mod m)^y mod m = x^y mod m"
  3.1345 +apply (induct "y", auto)
  3.1346 +apply (rule zmod_zmult1_eq [THEN trans])
  3.1347 +apply (simp (no_asm_simp))
  3.1348 +apply (rule zmod_zmult_distrib [symmetric])
  3.1349 +done
  3.1350 +
  3.1351 +lemma zpower_zadd_distrib: "x^(y+z) = ((x^y)*(x^z)::int)"
  3.1352 +  by (rule Power.power_add)
  3.1353 +
  3.1354 +lemma zpower_zpower: "(x^y)^z = (x^(y*z)::int)"
  3.1355 +  by (rule Power.power_mult [symmetric])
  3.1356 +
  3.1357 +lemma zero_less_zpower_abs_iff [simp]:
  3.1358 +     "(0 < (abs x)^n) = (x \<noteq> (0::int) | n=0)"
  3.1359 +apply (induct "n")
  3.1360 +apply (auto simp add: zero_less_mult_iff)
  3.1361 +done
  3.1362 +
  3.1363 +lemma zero_le_zpower_abs [simp]: "(0::int) <= (abs x)^n"
  3.1364 +apply (induct "n")
  3.1365 +apply (auto simp add: zero_le_mult_iff)
  3.1366 +done
  3.1367 +
  3.1368 +lemma int_power: "int (m^n) = (int m) ^ n"
  3.1369 +  by (induct n, simp_all add: int_mult)
  3.1370 +
  3.1371 +text{*Compatibility binding*}
  3.1372 +lemmas zpower_int = int_power [symmetric]
  3.1373 +
  3.1374 +lemma zdiv_int: "int (a div b) = (int a) div (int b)"
  3.1375 +apply (subst split_div, auto)
  3.1376 +apply (subst split_zdiv, auto)
  3.1377 +apply (rule_tac a="int (b * i) + int j" and b="int b" and r="int j" and r'=ja in IntDiv.unique_quotient)
  3.1378 +apply (auto simp add: IntDiv.quorem_def int_eq_of_nat)
  3.1379 +done
  3.1380 +
  3.1381 +lemma zmod_int: "int (a mod b) = (int a) mod (int b)"
  3.1382 +apply (subst split_mod, auto)
  3.1383 +apply (subst split_zmod, auto)
  3.1384 +apply (rule_tac a="int (b * i) + int j" and b="int b" and q="int i" and q'=ia 
  3.1385 +       in unique_remainder)
  3.1386 +apply (auto simp add: IntDiv.quorem_def int_eq_of_nat)
  3.1387 +done
  3.1388 +
  3.1389 +text{*Suggested by Matthias Daum*}
  3.1390 +lemma int_power_div_base:
  3.1391 +     "\<lbrakk>0 < m; 0 < k\<rbrakk> \<Longrightarrow> k ^ m div k = (k::int) ^ (m - Suc 0)"
  3.1392 +apply (subgoal_tac "k ^ m = k ^ ((m - 1) + 1)")
  3.1393 + apply (erule ssubst)
  3.1394 + apply (simp only: power_add)
  3.1395 + apply simp_all
  3.1396 +done
  3.1397 +
  3.1398 +text {* code serializer setup *}
  3.1399 +
  3.1400 +code_modulename SML
  3.1401 +  IntDiv Integer
  3.1402 +
  3.1403 +code_modulename OCaml
  3.1404 +  IntDiv Integer
  3.1405 +
  3.1406 +code_modulename Haskell
  3.1407 +  IntDiv Divides
  3.1408 +
  3.1409 +end
     4.1 --- a/src/HOL/Integ/IntArith.thy	Thu May 31 18:16:51 2007 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,411 +0,0 @@
     4.4 -(*  Title:      HOL/Integ/IntArith.thy
     4.5 -    ID:         $Id$
     4.6 -    Authors:    Larry Paulson and Tobias Nipkow
     4.7 -*)
     4.8 -
     4.9 -header {* Integer arithmetic *}
    4.10 -
    4.11 -theory IntArith
    4.12 -imports Numeral "../Wellfounded_Relations"
    4.13 -uses "~~/src/Provers/Arith/assoc_fold.ML" ("int_arith1.ML")
    4.14 -begin
    4.15 -
    4.16 -text{*Duplicate: can't understand why it's necessary*}
    4.17 -declare numeral_0_eq_0 [simp]
    4.18 -
    4.19 -
    4.20 -subsection{*Inequality Reasoning for the Arithmetic Simproc*}
    4.21 -
    4.22 -lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)"
    4.23 -by simp 
    4.24 -
    4.25 -lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)"
    4.26 -by simp
    4.27 -
    4.28 -lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)"
    4.29 -by simp 
    4.30 -
    4.31 -lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)"
    4.32 -by simp
    4.33 -
    4.34 -lemma divide_numeral_1: "a / Numeral1 = (a::'a::{number_ring,field})"
    4.35 -by simp
    4.36 -
    4.37 -lemma inverse_numeral_1:
    4.38 -  "inverse Numeral1 = (Numeral1::'a::{number_ring,field})"
    4.39 -by simp
    4.40 -
    4.41 -text{*Theorem lists for the cancellation simprocs. The use of binary numerals
    4.42 -for 0 and 1 reduces the number of special cases.*}
    4.43 -
    4.44 -lemmas add_0s = add_numeral_0 add_numeral_0_right
    4.45 -lemmas mult_1s = mult_numeral_1 mult_numeral_1_right 
    4.46 -                 mult_minus1 mult_minus1_right
    4.47 -
    4.48 -
    4.49 -subsection{*Special Arithmetic Rules for Abstract 0 and 1*}
    4.50 -
    4.51 -text{*Arithmetic computations are defined for binary literals, which leaves 0
    4.52 -and 1 as special cases. Addition already has rules for 0, but not 1.
    4.53 -Multiplication and unary minus already have rules for both 0 and 1.*}
    4.54 -
    4.55 -
    4.56 -lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'"
    4.57 -by simp
    4.58 -
    4.59 -
    4.60 -lemmas add_number_of_eq = number_of_add [symmetric]
    4.61 -
    4.62 -text{*Allow 1 on either or both sides*}
    4.63 -lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)"
    4.64 -by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq)
    4.65 -
    4.66 -lemmas add_special =
    4.67 -    one_add_one_is_two
    4.68 -    binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard]
    4.69 -    binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard]
    4.70 -
    4.71 -text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*}
    4.72 -lemmas diff_special =
    4.73 -    binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard]
    4.74 -    binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard]
    4.75 -
    4.76 -text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    4.77 -lemmas eq_special =
    4.78 -    binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard]
    4.79 -    binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard]
    4.80 -    binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard]
    4.81 -    binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard]
    4.82 -
    4.83 -text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    4.84 -lemmas less_special =
    4.85 -  binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard]
    4.86 -  binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard]
    4.87 -  binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard]
    4.88 -  binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard]
    4.89 -
    4.90 -text{*Allow 0 or 1 on either side with a binary numeral on the other*}
    4.91 -lemmas le_special =
    4.92 -    binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard]
    4.93 -    binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard]
    4.94 -    binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard]
    4.95 -    binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard]
    4.96 -
    4.97 -lemmas arith_special[simp] = 
    4.98 -       add_special diff_special eq_special less_special le_special
    4.99 -
   4.100 -
   4.101 -lemma min_max_01: "min (0::int) 1 = 0 & min (1::int) 0 = 0 &
   4.102 -                   max (0::int) 1 = 1 & max (1::int) 0 = 1"
   4.103 -by(simp add:min_def max_def)
   4.104 -
   4.105 -lemmas min_max_special[simp] =
   4.106 - min_max_01
   4.107 - max_def[of "0::int" "number_of v", standard, simp]
   4.108 - min_def[of "0::int" "number_of v", standard, simp]
   4.109 - max_def[of "number_of u" "0::int", standard, simp]
   4.110 - min_def[of "number_of u" "0::int", standard, simp]
   4.111 - max_def[of "1::int" "number_of v", standard, simp]
   4.112 - min_def[of "1::int" "number_of v", standard, simp]
   4.113 - max_def[of "number_of u" "1::int", standard, simp]
   4.114 - min_def[of "number_of u" "1::int", standard, simp]
   4.115 -
   4.116 -use "int_arith1.ML"
   4.117 -setup int_arith_setup
   4.118 -
   4.119 -
   4.120 -subsection{*Lemmas About Small Numerals*}
   4.121 -
   4.122 -lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)"
   4.123 -proof -
   4.124 -  have "(of_int -1 :: 'a) = of_int (- 1)" by simp
   4.125 -  also have "... = - of_int 1" by (simp only: of_int_minus)
   4.126 -  also have "... = -1" by simp
   4.127 -  finally show ?thesis .
   4.128 -qed
   4.129 -
   4.130 -lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_idom,number_ring})"
   4.131 -by (simp add: abs_if)
   4.132 -
   4.133 -lemma abs_power_minus_one [simp]:
   4.134 -     "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring,recpower})"
   4.135 -by (simp add: power_abs)
   4.136 -
   4.137 -lemma of_int_number_of_eq:
   4.138 -     "of_int (number_of v) = (number_of v :: 'a :: number_ring)"
   4.139 -by (simp add: number_of_eq) 
   4.140 -
   4.141 -text{*Lemmas for specialist use, NOT as default simprules*}
   4.142 -lemma mult_2: "2 * z = (z+z::'a::number_ring)"
   4.143 -proof -
   4.144 -  have "2*z = (1 + 1)*z" by simp
   4.145 -  also have "... = z+z" by (simp add: left_distrib)
   4.146 -  finally show ?thesis .
   4.147 -qed
   4.148 -
   4.149 -lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)"
   4.150 -by (subst mult_commute, rule mult_2)
   4.151 -
   4.152 -
   4.153 -subsection{*More Inequality Reasoning*}
   4.154 -
   4.155 -lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
   4.156 -by arith
   4.157 -
   4.158 -lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
   4.159 -by arith
   4.160 -
   4.161 -lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<z)"
   4.162 -by arith
   4.163 -
   4.164 -lemma zle_add1_eq_le [simp]: "(w < z + (1::int)) = (w\<le>z)"
   4.165 -by arith
   4.166 -
   4.167 -lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
   4.168 -by arith
   4.169 -
   4.170 -
   4.171 -subsection{*The Functions @{term nat} and @{term int}*}
   4.172 -
   4.173 -text{*Simplify the terms @{term "int 0"}, @{term "int(Suc 0)"} and
   4.174 -  @{term "w + - z"}*}
   4.175 -declare Zero_int_def [symmetric, simp]
   4.176 -declare One_int_def [symmetric, simp]
   4.177 -
   4.178 -lemmas diff_int_def_symmetric = diff_int_def [symmetric, simp]
   4.179 -
   4.180 -lemma nat_0: "nat 0 = 0"
   4.181 -by (simp add: nat_eq_iff)
   4.182 -
   4.183 -lemma nat_1: "nat 1 = Suc 0"
   4.184 -by (subst nat_eq_iff, simp)
   4.185 -
   4.186 -lemma nat_2: "nat 2 = Suc (Suc 0)"
   4.187 -by (subst nat_eq_iff, simp)
   4.188 -
   4.189 -lemma one_less_nat_eq [simp]: "(Suc 0 < nat z) = (1 < z)"
   4.190 -apply (insert zless_nat_conj [of 1 z])
   4.191 -apply (auto simp add: nat_1)
   4.192 -done
   4.193 -
   4.194 -text{*This simplifies expressions of the form @{term "int n = z"} where
   4.195 -      z is an integer literal.*}
   4.196 -lemmas int_eq_iff_number_of [simp] = int_eq_iff [of _ "number_of v", standard]
   4.197 -
   4.198 -
   4.199 -lemma split_nat [arith_split]:
   4.200 -  "P(nat(i::int)) = ((\<forall>n. i = int n \<longrightarrow> P n) & (i < 0 \<longrightarrow> P 0))"
   4.201 -  (is "?P = (?L & ?R)")
   4.202 -proof (cases "i < 0")
   4.203 -  case True thus ?thesis by simp
   4.204 -next
   4.205 -  case False
   4.206 -  have "?P = ?L"
   4.207 -  proof
   4.208 -    assume ?P thus ?L using False by clarsimp
   4.209 -  next
   4.210 -    assume ?L thus ?P using False by simp
   4.211 -  qed
   4.212 -  with False show ?thesis by simp
   4.213 -qed
   4.214 -
   4.215 -
   4.216 -(*Analogous to zadd_int*)
   4.217 -lemma zdiff_int: "n \<le> m ==> int m - int n = int (m-n)" 
   4.218 -by (induct m n rule: diff_induct, simp_all)
   4.219 -
   4.220 -lemma nat_mult_distrib: "(0::int) \<le> z ==> nat (z*z') = nat z * nat z'"
   4.221 -apply (cases "0 \<le> z'")
   4.222 -apply (rule inj_int [THEN injD])
   4.223 -apply (simp add: int_mult zero_le_mult_iff)
   4.224 -apply (simp add: mult_le_0_iff)
   4.225 -done
   4.226 -
   4.227 -lemma nat_mult_distrib_neg: "z \<le> (0::int) ==> nat(z*z') = nat(-z) * nat(-z')"
   4.228 -apply (rule trans)
   4.229 -apply (rule_tac [2] nat_mult_distrib, auto)
   4.230 -done
   4.231 -
   4.232 -lemma nat_abs_mult_distrib: "nat (abs (w * z)) = nat (abs w) * nat (abs z)"
   4.233 -apply (cases "z=0 | w=0")
   4.234 -apply (auto simp add: abs_if nat_mult_distrib [symmetric] 
   4.235 -                      nat_mult_distrib_neg [symmetric] mult_less_0_iff)
   4.236 -done
   4.237 -
   4.238 -
   4.239 -subsection "Induction principles for int"
   4.240 -
   4.241 -text{*Well-founded segments of the integers*}
   4.242 -
   4.243 -definition
   4.244 -  int_ge_less_than  ::  "int => (int * int) set"
   4.245 -where
   4.246 -  "int_ge_less_than d = {(z',z). d \<le> z' & z' < z}"
   4.247 -
   4.248 -theorem wf_int_ge_less_than: "wf (int_ge_less_than d)"
   4.249 -proof -
   4.250 -  have "int_ge_less_than d \<subseteq> measure (%z. nat (z-d))"
   4.251 -    by (auto simp add: int_ge_less_than_def)
   4.252 -  thus ?thesis 
   4.253 -    by (rule wf_subset [OF wf_measure]) 
   4.254 -qed
   4.255 -
   4.256 -text{*This variant looks odd, but is typical of the relations suggested
   4.257 -by RankFinder.*}
   4.258 -
   4.259 -definition
   4.260 -  int_ge_less_than2 ::  "int => (int * int) set"
   4.261 -where
   4.262 -  "int_ge_less_than2 d = {(z',z). d \<le> z & z' < z}"
   4.263 -
   4.264 -theorem wf_int_ge_less_than2: "wf (int_ge_less_than2 d)"
   4.265 -proof -
   4.266 -  have "int_ge_less_than2 d \<subseteq> measure (%z. nat (1+z-d))" 
   4.267 -    by (auto simp add: int_ge_less_than2_def)
   4.268 -  thus ?thesis 
   4.269 -    by (rule wf_subset [OF wf_measure]) 
   4.270 -qed
   4.271 -
   4.272 -                     (* `set:int': dummy construction *)
   4.273 -theorem int_ge_induct[case_names base step,induct set:int]:
   4.274 -  assumes ge: "k \<le> (i::int)" and
   4.275 -        base: "P(k)" and
   4.276 -        step: "\<And>i. \<lbrakk>k \<le> i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   4.277 -  shows "P i"
   4.278 -proof -
   4.279 -  { fix n have "\<And>i::int. n = nat(i-k) \<Longrightarrow> k \<le> i \<Longrightarrow> P i"
   4.280 -    proof (induct n)
   4.281 -      case 0
   4.282 -      hence "i = k" by arith
   4.283 -      thus "P i" using base by simp
   4.284 -    next
   4.285 -      case (Suc n)
   4.286 -      hence "n = nat((i - 1) - k)" by arith
   4.287 -      moreover
   4.288 -      have ki1: "k \<le> i - 1" using Suc.prems by arith
   4.289 -      ultimately
   4.290 -      have "P(i - 1)" by(rule Suc.hyps)
   4.291 -      from step[OF ki1 this] show ?case by simp
   4.292 -    qed
   4.293 -  }
   4.294 -  with ge show ?thesis by fast
   4.295 -qed
   4.296 -
   4.297 -                     (* `set:int': dummy construction *)
   4.298 -theorem int_gr_induct[case_names base step,induct set:int]:
   4.299 -  assumes gr: "k < (i::int)" and
   4.300 -        base: "P(k+1)" and
   4.301 -        step: "\<And>i. \<lbrakk>k < i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
   4.302 -  shows "P i"
   4.303 -apply(rule int_ge_induct[of "k + 1"])
   4.304 -  using gr apply arith
   4.305 - apply(rule base)
   4.306 -apply (rule step, simp+)
   4.307 -done
   4.308 -
   4.309 -theorem int_le_induct[consumes 1,case_names base step]:
   4.310 -  assumes le: "i \<le> (k::int)" and
   4.311 -        base: "P(k)" and
   4.312 -        step: "\<And>i. \<lbrakk>i \<le> k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   4.313 -  shows "P i"
   4.314 -proof -
   4.315 -  { fix n have "\<And>i::int. n = nat(k-i) \<Longrightarrow> i \<le> k \<Longrightarrow> P i"
   4.316 -    proof (induct n)
   4.317 -      case 0
   4.318 -      hence "i = k" by arith
   4.319 -      thus "P i" using base by simp
   4.320 -    next
   4.321 -      case (Suc n)
   4.322 -      hence "n = nat(k - (i+1))" by arith
   4.323 -      moreover
   4.324 -      have ki1: "i + 1 \<le> k" using Suc.prems by arith
   4.325 -      ultimately
   4.326 -      have "P(i+1)" by(rule Suc.hyps)
   4.327 -      from step[OF ki1 this] show ?case by simp
   4.328 -    qed
   4.329 -  }
   4.330 -  with le show ?thesis by fast
   4.331 -qed
   4.332 -
   4.333 -theorem int_less_induct [consumes 1,case_names base step]:
   4.334 -  assumes less: "(i::int) < k" and
   4.335 -        base: "P(k - 1)" and
   4.336 -        step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
   4.337 -  shows "P i"
   4.338 -apply(rule int_le_induct[of _ "k - 1"])
   4.339 -  using less apply arith
   4.340 - apply(rule base)
   4.341 -apply (rule step, simp+)
   4.342 -done
   4.343 -
   4.344 -subsection{*Intermediate value theorems*}
   4.345 -
   4.346 -lemma int_val_lemma:
   4.347 -     "(\<forall>i<n::nat. abs(f(i+1) - f i) \<le> 1) -->  
   4.348 -      f 0 \<le> k --> k \<le> f n --> (\<exists>i \<le> n. f i = (k::int))"
   4.349 -apply (induct_tac "n", simp)
   4.350 -apply (intro strip)
   4.351 -apply (erule impE, simp)
   4.352 -apply (erule_tac x = n in allE, simp)
   4.353 -apply (case_tac "k = f (n+1) ")
   4.354 - apply force
   4.355 -apply (erule impE)
   4.356 - apply (simp add: abs_if split add: split_if_asm)
   4.357 -apply (blast intro: le_SucI)
   4.358 -done
   4.359 -
   4.360 -lemmas nat0_intermed_int_val = int_val_lemma [rule_format (no_asm)]
   4.361 -
   4.362 -lemma nat_intermed_int_val:
   4.363 -     "[| \<forall>i. m \<le> i & i < n --> abs(f(i + 1::nat) - f i) \<le> 1; m < n;  
   4.364 -         f m \<le> k; k \<le> f n |] ==> ? i. m \<le> i & i \<le> n & f i = (k::int)"
   4.365 -apply (cut_tac n = "n-m" and f = "%i. f (i+m) " and k = k 
   4.366 -       in int_val_lemma)
   4.367 -apply simp
   4.368 -apply (erule exE)
   4.369 -apply (rule_tac x = "i+m" in exI, arith)
   4.370 -done
   4.371 -
   4.372 -
   4.373 -subsection{*Products and 1, by T. M. Rasmussen*}
   4.374 -
   4.375 -lemma zabs_less_one_iff [simp]: "(\<bar>z\<bar> < 1) = (z = (0::int))"
   4.376 -by arith
   4.377 -
   4.378 -lemma abs_zmult_eq_1: "(\<bar>m * n\<bar> = 1) ==> \<bar>m\<bar> = (1::int)"
   4.379 -apply (cases "\<bar>n\<bar>=1") 
   4.380 -apply (simp add: abs_mult) 
   4.381 -apply (rule ccontr) 
   4.382 -apply (auto simp add: linorder_neq_iff abs_mult) 
   4.383 -apply (subgoal_tac "2 \<le> \<bar>m\<bar> & 2 \<le> \<bar>n\<bar>")
   4.384 - prefer 2 apply arith 
   4.385 -apply (subgoal_tac "2*2 \<le> \<bar>m\<bar> * \<bar>n\<bar>", simp) 
   4.386 -apply (rule mult_mono, auto) 
   4.387 -done
   4.388 -
   4.389 -lemma pos_zmult_eq_1_iff_lemma: "(m * n = 1) ==> m = (1::int) | m = -1"
   4.390 -by (insert abs_zmult_eq_1 [of m n], arith)
   4.391 -
   4.392 -lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
   4.393 -apply (auto dest: pos_zmult_eq_1_iff_lemma) 
   4.394 -apply (simp add: mult_commute [of m]) 
   4.395 -apply (frule pos_zmult_eq_1_iff_lemma, auto) 
   4.396 -done
   4.397 -
   4.398 -lemma zmult_eq_1_iff: "(m*n = (1::int)) = ((m = 1 & n = 1) | (m = -1 & n = -1))"
   4.399 -apply (rule iffI) 
   4.400 - apply (frule pos_zmult_eq_1_iff_lemma)
   4.401 - apply (simp add: mult_commute [of m]) 
   4.402 - apply (frule pos_zmult_eq_1_iff_lemma, auto) 
   4.403 -done
   4.404 -
   4.405 -
   4.406 -subsection {* Legacy ML bindings *}
   4.407 -
   4.408 -ML {*
   4.409 -val of_int_number_of_eq = @{thm of_int_number_of_eq};
   4.410 -val nat_0 = @{thm nat_0};
   4.411 -val nat_1 = @{thm nat_1};
   4.412 -*}
   4.413 -
   4.414 -end
     5.1 --- a/src/HOL/Integ/IntDef.thy	Thu May 31 18:16:51 2007 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,890 +0,0 @@
     5.4 -(*  Title:      IntDef.thy
     5.5 -    ID:         $Id$
     5.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     5.7 -    Copyright   1996  University of Cambridge
     5.8 -
     5.9 -*)
    5.10 -
    5.11 -header{*The Integers as Equivalence Classes over Pairs of Natural Numbers*} 
    5.12 -
    5.13 -theory IntDef
    5.14 -imports Equiv_Relations Nat
    5.15 -begin
    5.16 -
    5.17 -text {* the equivalence relation underlying the integers *}
    5.18 -
    5.19 -definition
    5.20 -  intrel :: "((nat \<times> nat) \<times> (nat \<times> nat)) set"
    5.21 -where
    5.22 -  "intrel = {((x, y), (u, v)) | x y u v. x + v = u +y }"
    5.23 -
    5.24 -typedef (Integ)
    5.25 -  int = "UNIV//intrel"
    5.26 -  by (auto simp add: quotient_def)
    5.27 -
    5.28 -definition
    5.29 -  int :: "nat \<Rightarrow> int"
    5.30 -where
    5.31 -  [code func del]: "int m = Abs_Integ (intrel `` {(m, 0)})"
    5.32 -
    5.33 -instance int :: zero
    5.34 -  Zero_int_def: "0 \<equiv> int 0" ..
    5.35 -
    5.36 -instance int :: one
    5.37 -  One_int_def: "1 \<equiv> int 1" ..
    5.38 -
    5.39 -instance int :: plus
    5.40 -  add_int_def: "z + w \<equiv> Abs_Integ
    5.41 -    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u, v) \<in> Rep_Integ w.
    5.42 -      intrel `` {(x + u, y + v)})" ..
    5.43 -
    5.44 -instance int :: minus
    5.45 -  minus_int_def:
    5.46 -    "- z \<equiv> Abs_Integ (\<Union>(x, y) \<in> Rep_Integ z. intrel `` {(y, x)})"
    5.47 -  diff_int_def:  "z - w \<equiv> z + (-w)" ..
    5.48 -
    5.49 -instance int :: times
    5.50 -  mult_int_def: "z * w \<equiv>  Abs_Integ
    5.51 -    (\<Union>(x, y) \<in> Rep_Integ z. \<Union>(u,v ) \<in> Rep_Integ w.
    5.52 -      intrel `` {(x*u + y*v, x*v + y*u)})" ..
    5.53 -
    5.54 -instance int :: ord
    5.55 -  le_int_def:
    5.56 -   "z \<le> w \<equiv> \<exists>x y u v. x+v \<le> u+y \<and> (x, y) \<in> Rep_Integ z \<and> (u, v) \<in> Rep_Integ w"
    5.57 -  less_int_def: "z < w \<equiv> z \<le> w \<and> z \<noteq> w" ..
    5.58 -
    5.59 -lemmas [code func del] = Zero_int_def One_int_def add_int_def
    5.60 -  minus_int_def mult_int_def le_int_def less_int_def
    5.61 -
    5.62 -
    5.63 -subsection{*Construction of the Integers*}
    5.64 -
    5.65 -subsubsection{*Preliminary Lemmas about the Equivalence Relation*}
    5.66 -
    5.67 -lemma intrel_iff [simp]: "(((x,y),(u,v)) \<in> intrel) = (x+v = u+y)"
    5.68 -by (simp add: intrel_def)
    5.69 -
    5.70 -lemma equiv_intrel: "equiv UNIV intrel"
    5.71 -by (simp add: intrel_def equiv_def refl_def sym_def trans_def)
    5.72 -
    5.73 -text{*Reduces equality of equivalence classes to the @{term intrel} relation:
    5.74 -  @{term "(intrel `` {x} = intrel `` {y}) = ((x,y) \<in> intrel)"} *}
    5.75 -lemmas equiv_intrel_iff [simp] = eq_equiv_class_iff [OF equiv_intrel UNIV_I UNIV_I]
    5.76 -
    5.77 -text{*All equivalence classes belong to set of representatives*}
    5.78 -lemma [simp]: "intrel``{(x,y)} \<in> Integ"
    5.79 -by (auto simp add: Integ_def intrel_def quotient_def)
    5.80 -
    5.81 -text{*Reduces equality on abstractions to equality on representatives:
    5.82 -  @{prop "\<lbrakk>x \<in> Integ; y \<in> Integ\<rbrakk> \<Longrightarrow> (Abs_Integ x = Abs_Integ y) = (x=y)"} *}
    5.83 -declare Abs_Integ_inject [simp]  Abs_Integ_inverse [simp]
    5.84 -
    5.85 -text{*Case analysis on the representation of an integer as an equivalence
    5.86 -      class of pairs of naturals.*}
    5.87 -lemma eq_Abs_Integ [case_names Abs_Integ, cases type: int]:
    5.88 -     "(!!x y. z = Abs_Integ(intrel``{(x,y)}) ==> P) ==> P"
    5.89 -apply (rule Abs_Integ_cases [of z]) 
    5.90 -apply (auto simp add: Integ_def quotient_def) 
    5.91 -done
    5.92 -
    5.93 -
    5.94 -subsubsection{*@{term int}: Embedding the Naturals into the Integers*}
    5.95 -
    5.96 -lemma inj_int: "inj int"
    5.97 -by (simp add: inj_on_def int_def)
    5.98 -
    5.99 -lemma int_int_eq [iff]: "(int m = int n) = (m = n)"
   5.100 -by (fast elim!: inj_int [THEN injD])
   5.101 -
   5.102 -
   5.103 -subsubsection{*Integer Unary Negation*}
   5.104 -
   5.105 -lemma minus: "- Abs_Integ(intrel``{(x,y)}) = Abs_Integ(intrel `` {(y,x)})"
   5.106 -proof -
   5.107 -  have "(\<lambda>(x,y). intrel``{(y,x)}) respects intrel"
   5.108 -    by (simp add: congruent_def) 
   5.109 -  thus ?thesis
   5.110 -    by (simp add: minus_int_def UN_equiv_class [OF equiv_intrel])
   5.111 -qed
   5.112 -
   5.113 -lemma zminus_zminus: "- (- z) = (z::int)"
   5.114 -  by (cases z) (simp add: minus)
   5.115 -
   5.116 -lemma zminus_0: "- 0 = (0::int)"
   5.117 -  by (simp add: int_def Zero_int_def minus)
   5.118 -
   5.119 -
   5.120 -subsection{*Integer Addition*}
   5.121 -
   5.122 -lemma add:
   5.123 -     "Abs_Integ (intrel``{(x,y)}) + Abs_Integ (intrel``{(u,v)}) =
   5.124 -      Abs_Integ (intrel``{(x+u, y+v)})"
   5.125 -proof -
   5.126 -  have "(\<lambda>z w. (\<lambda>(x,y). (\<lambda>(u,v). intrel `` {(x+u, y+v)}) w) z) 
   5.127 -        respects2 intrel"
   5.128 -    by (simp add: congruent2_def)
   5.129 -  thus ?thesis
   5.130 -    by (simp add: add_int_def UN_UN_split_split_eq
   5.131 -                  UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   5.132 -qed
   5.133 -
   5.134 -lemma zminus_zadd_distrib: "- (z + w) = (- z) + (- w::int)"
   5.135 -  by (cases z, cases w) (simp add: minus add)
   5.136 -
   5.137 -lemma zadd_commute: "(z::int) + w = w + z"
   5.138 -  by (cases z, cases w) (simp add: add_ac add)
   5.139 -
   5.140 -lemma zadd_assoc: "((z1::int) + z2) + z3 = z1 + (z2 + z3)"
   5.141 -  by (cases z1, cases z2, cases z3) (simp add: add add_assoc)
   5.142 -
   5.143 -(*For AC rewriting*)
   5.144 -lemma zadd_left_commute: "x + (y + z) = y + ((x + z)  ::int)"
   5.145 -  apply (rule mk_left_commute [of "op +"])
   5.146 -  apply (rule zadd_assoc)
   5.147 -  apply (rule zadd_commute)
   5.148 -  done
   5.149 -
   5.150 -lemmas zadd_ac = zadd_assoc zadd_commute zadd_left_commute
   5.151 -
   5.152 -lemmas zmult_ac = OrderedGroup.mult_ac
   5.153 -
   5.154 -lemma zadd_int: "(int m) + (int n) = int (m + n)"
   5.155 -  by (simp add: int_def add)
   5.156 -
   5.157 -lemma zadd_int_left: "(int m) + (int n + z) = int (m + n) + z"
   5.158 -  by (simp add: zadd_int zadd_assoc [symmetric])
   5.159 -
   5.160 -(*also for the instance declaration int :: comm_monoid_add*)
   5.161 -lemma zadd_0: "(0::int) + z = z"
   5.162 -apply (simp add: Zero_int_def int_def)
   5.163 -apply (cases z, simp add: add)
   5.164 -done
   5.165 -
   5.166 -lemma zadd_0_right: "z + (0::int) = z"
   5.167 -by (rule trans [OF zadd_commute zadd_0])
   5.168 -
   5.169 -lemma zadd_zminus_inverse2: "(- z) + z = (0::int)"
   5.170 -by (cases z, simp add: int_def Zero_int_def minus add)
   5.171 -
   5.172 -
   5.173 -subsection{*Integer Multiplication*}
   5.174 -
   5.175 -text{*Congruence property for multiplication*}
   5.176 -lemma mult_congruent2:
   5.177 -     "(%p1 p2. (%(x,y). (%(u,v). intrel``{(x*u + y*v, x*v + y*u)}) p2) p1)
   5.178 -      respects2 intrel"
   5.179 -apply (rule equiv_intrel [THEN congruent2_commuteI])
   5.180 - apply (force simp add: mult_ac, clarify) 
   5.181 -apply (simp add: congruent_def mult_ac)  
   5.182 -apply (rename_tac u v w x y z)
   5.183 -apply (subgoal_tac "u*y + x*y = w*y + v*y  &  u*z + x*z = w*z + v*z")
   5.184 -apply (simp add: mult_ac)
   5.185 -apply (simp add: add_mult_distrib [symmetric])
   5.186 -done
   5.187 -
   5.188 -
   5.189 -lemma mult:
   5.190 -     "Abs_Integ((intrel``{(x,y)})) * Abs_Integ((intrel``{(u,v)})) =
   5.191 -      Abs_Integ(intrel `` {(x*u + y*v, x*v + y*u)})"
   5.192 -by (simp add: mult_int_def UN_UN_split_split_eq mult_congruent2
   5.193 -              UN_equiv_class2 [OF equiv_intrel equiv_intrel])
   5.194 -
   5.195 -lemma zmult_zminus: "(- z) * w = - (z * (w::int))"
   5.196 -by (cases z, cases w, simp add: minus mult add_ac)
   5.197 -
   5.198 -lemma zmult_commute: "(z::int) * w = w * z"
   5.199 -by (cases z, cases w, simp add: mult add_ac mult_ac)
   5.200 -
   5.201 -lemma zmult_assoc: "((z1::int) * z2) * z3 = z1 * (z2 * z3)"
   5.202 -by (cases z1, cases z2, cases z3, simp add: mult add_mult_distrib2 mult_ac)
   5.203 -
   5.204 -lemma zadd_zmult_distrib: "((z1::int) + z2) * w = (z1 * w) + (z2 * w)"
   5.205 -by (cases z1, cases z2, cases w, simp add: add mult add_mult_distrib2 mult_ac)
   5.206 -
   5.207 -lemma zadd_zmult_distrib2: "(w::int) * (z1 + z2) = (w * z1) + (w * z2)"
   5.208 -by (simp add: zmult_commute [of w] zadd_zmult_distrib)
   5.209 -
   5.210 -lemma zdiff_zmult_distrib: "((z1::int) - z2) * w = (z1 * w) - (z2 * w)"
   5.211 -by (simp add: diff_int_def zadd_zmult_distrib zmult_zminus)
   5.212 -
   5.213 -lemma zdiff_zmult_distrib2: "(w::int) * (z1 - z2) = (w * z1) - (w * z2)"
   5.214 -by (simp add: zmult_commute [of w] zdiff_zmult_distrib)
   5.215 -
   5.216 -lemmas int_distrib =
   5.217 -  zadd_zmult_distrib zadd_zmult_distrib2
   5.218 -  zdiff_zmult_distrib zdiff_zmult_distrib2
   5.219 -
   5.220 -lemma int_mult: "int (m * n) = (int m) * (int n)"
   5.221 -by (simp add: int_def mult)
   5.222 -
   5.223 -text{*Compatibility binding*}
   5.224 -lemmas zmult_int = int_mult [symmetric]
   5.225 -
   5.226 -lemma zmult_1: "(1::int) * z = z"
   5.227 -by (cases z, simp add: One_int_def int_def mult)
   5.228 -
   5.229 -lemma zmult_1_right: "z * (1::int) = z"
   5.230 -by (rule trans [OF zmult_commute zmult_1])
   5.231 -
   5.232 -
   5.233 -text{*The integers form a @{text comm_ring_1}*}
   5.234 -instance int :: comm_ring_1
   5.235 -proof
   5.236 -  fix i j k :: int
   5.237 -  show "(i + j) + k = i + (j + k)" by (simp add: zadd_assoc)
   5.238 -  show "i + j = j + i" by (simp add: zadd_commute)
   5.239 -  show "0 + i = i" by (rule zadd_0)
   5.240 -  show "- i + i = 0" by (rule zadd_zminus_inverse2)
   5.241 -  show "i - j = i + (-j)" by (simp add: diff_int_def)
   5.242 -  show "(i * j) * k = i * (j * k)" by (rule zmult_assoc)
   5.243 -  show "i * j = j * i" by (rule zmult_commute)
   5.244 -  show "1 * i = i" by (rule zmult_1) 
   5.245 -  show "(i + j) * k = i * k + j * k" by (simp add: int_distrib)
   5.246 -  show "0 \<noteq> (1::int)"
   5.247 -    by (simp only: Zero_int_def One_int_def One_nat_def int_int_eq)
   5.248 -qed
   5.249 -
   5.250 -
   5.251 -subsection{*The @{text "\<le>"} Ordering*}
   5.252 -
   5.253 -lemma le:
   5.254 -  "(Abs_Integ(intrel``{(x,y)}) \<le> Abs_Integ(intrel``{(u,v)})) = (x+v \<le> u+y)"
   5.255 -by (force simp add: le_int_def)
   5.256 -
   5.257 -lemma zle_refl: "w \<le> (w::int)"
   5.258 -by (cases w, simp add: le)
   5.259 -
   5.260 -lemma zle_trans: "[| i \<le> j; j \<le> k |] ==> i \<le> (k::int)"
   5.261 -by (cases i, cases j, cases k, simp add: le)
   5.262 -
   5.263 -lemma zle_anti_sym: "[| z \<le> w; w \<le> z |] ==> z = (w::int)"
   5.264 -by (cases w, cases z, simp add: le)
   5.265 -
   5.266 -instance int :: order
   5.267 -  by intro_classes
   5.268 -    (assumption |
   5.269 -      rule zle_refl zle_trans zle_anti_sym less_int_def [THEN meta_eq_to_obj_eq])+
   5.270 -
   5.271 -lemma zle_linear: "(z::int) \<le> w \<or> w \<le> z"
   5.272 -by (cases z, cases w) (simp add: le linorder_linear)
   5.273 -
   5.274 -instance int :: linorder
   5.275 -  by intro_classes (rule zle_linear)
   5.276 -
   5.277 -lemmas zless_linear = linorder_less_linear [where 'a = int]
   5.278 -
   5.279 -
   5.280 -lemma int_eq_0_conv [simp]: "(int n = 0) = (n = 0)"
   5.281 -by (simp add: Zero_int_def)
   5.282 -
   5.283 -lemma zless_int [simp]: "(int m < int n) = (m<n)"
   5.284 -by (simp add: le add int_def linorder_not_le [symmetric]) 
   5.285 -
   5.286 -lemma int_less_0_conv [simp]: "~ (int k < 0)"
   5.287 -by (simp add: Zero_int_def)
   5.288 -
   5.289 -lemma zero_less_int_conv [simp]: "(0 < int n) = (0 < n)"
   5.290 -by (simp add: Zero_int_def)
   5.291 -
   5.292 -lemma int_0_less_1: "0 < (1::int)"
   5.293 -by (simp only: Zero_int_def One_int_def One_nat_def zless_int)
   5.294 -
   5.295 -lemma int_0_neq_1 [simp]: "0 \<noteq> (1::int)"
   5.296 -by (simp only: Zero_int_def One_int_def One_nat_def int_int_eq)
   5.297 -
   5.298 -lemma zle_int [simp]: "(int m \<le> int n) = (m\<le>n)"
   5.299 -by (simp add: linorder_not_less [symmetric])
   5.300 -
   5.301 -lemma zero_zle_int [simp]: "(0 \<le> int n)"
   5.302 -by (simp add: Zero_int_def)
   5.303 -
   5.304 -lemma int_le_0_conv [simp]: "(int n \<le> 0) = (n = 0)"
   5.305 -by (simp add: Zero_int_def)
   5.306 -
   5.307 -lemma int_0 [simp]: "int 0 = (0::int)"
   5.308 -by (simp add: Zero_int_def)
   5.309 -
   5.310 -lemma int_1 [simp]: "int 1 = 1"
   5.311 -by (simp add: One_int_def)
   5.312 -
   5.313 -lemma int_Suc0_eq_1: "int (Suc 0) = 1"
   5.314 -by (simp add: One_int_def One_nat_def)
   5.315 -
   5.316 -lemma int_Suc: "int (Suc m) = 1 + (int m)"
   5.317 -by (simp add: One_int_def zadd_int)
   5.318 -
   5.319 -
   5.320 -subsection{*Monotonicity results*}
   5.321 -
   5.322 -lemma zadd_left_mono: "i \<le> j ==> k + i \<le> k + (j::int)"
   5.323 -by (cases i, cases j, cases k, simp add: le add)
   5.324 -
   5.325 -lemma zadd_strict_right_mono: "i < j ==> i + k < j + (k::int)"
   5.326 -apply (cases i, cases j, cases k)
   5.327 -apply (simp add: linorder_not_le [where 'a = int, symmetric]
   5.328 -                 linorder_not_le [where 'a = nat]  le add)
   5.329 -done
   5.330 -
   5.331 -lemma zadd_zless_mono: "[| w'<w; z'\<le>z |] ==> w' + z' < w + (z::int)"
   5.332 -by (rule order_less_le_trans [OF zadd_strict_right_mono zadd_left_mono])
   5.333 -
   5.334 -
   5.335 -subsection{*Strict Monotonicity of Multiplication*}
   5.336 -
   5.337 -text{*strict, in 1st argument; proof is by induction on k>0*}
   5.338 -lemma zmult_zless_mono2_lemma:
   5.339 -     "i<j ==> 0<k ==> int k * i < int k * j"
   5.340 -apply (induct "k", simp)
   5.341 -apply (simp add: int_Suc)
   5.342 -apply (case_tac "k=0")
   5.343 -apply (simp_all add: zadd_zmult_distrib int_Suc0_eq_1 order_le_less)
   5.344 -apply (simp add: zadd_zless_mono int_Suc0_eq_1 order_le_less)
   5.345 -done
   5.346 -
   5.347 -lemma zero_le_imp_eq_int: "0 \<le> k ==> \<exists>n. k = int n"
   5.348 -apply (cases k)
   5.349 -apply (auto simp add: le add int_def Zero_int_def)
   5.350 -apply (rule_tac x="x-y" in exI, simp)
   5.351 -done
   5.352 -
   5.353 -lemma zmult_zless_mono2: "[| i<j;  (0::int) < k |] ==> k*i < k*j"
   5.354 -apply (frule order_less_imp_le [THEN zero_le_imp_eq_int])
   5.355 -apply (auto simp add: zmult_zless_mono2_lemma)
   5.356 -done
   5.357 -
   5.358 -instance int :: minus
   5.359 -  zabs_def: "\<bar>i\<Colon>int\<bar> \<equiv> if i < 0 then - i else i" ..
   5.360 -
   5.361 -instance int :: distrib_lattice
   5.362 -  "inf \<equiv> min"
   5.363 -  "sup \<equiv> max"
   5.364 -  by intro_classes
   5.365 -    (auto simp add: inf_int_def sup_int_def min_max.sup_inf_distrib1)
   5.366 -
   5.367 -text{*The integers form an ordered @{text comm_ring_1}*}
   5.368 -instance int :: ordered_idom
   5.369 -proof
   5.370 -  fix i j k :: int
   5.371 -  show "i \<le> j ==> k + i \<le> k + j" by (rule zadd_left_mono)
   5.372 -  show "i < j ==> 0 < k ==> k * i < k * j" by (rule zmult_zless_mono2)
   5.373 -  show "\<bar>i\<bar> = (if i < 0 then -i else i)" by (simp only: zabs_def)
   5.374 -qed
   5.375 -
   5.376 -lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z"
   5.377 -apply (cases w, cases z) 
   5.378 -apply (simp add: linorder_not_le [symmetric] le int_def add One_int_def)
   5.379 -done
   5.380 -
   5.381 -subsection{*Magnitide of an Integer, as a Natural Number: @{term nat}*}
   5.382 -
   5.383 -definition
   5.384 -  nat :: "int \<Rightarrow> nat"
   5.385 -where
   5.386 -  [code func del]: "nat z = contents (\<Union>(x, y) \<in> Rep_Integ z. {x-y})"
   5.387 -
   5.388 -lemma nat: "nat (Abs_Integ (intrel``{(x,y)})) = x-y"
   5.389 -proof -
   5.390 -  have "(\<lambda>(x,y). {x-y}) respects intrel"
   5.391 -    by (simp add: congruent_def) arith
   5.392 -  thus ?thesis
   5.393 -    by (simp add: nat_def UN_equiv_class [OF equiv_intrel])
   5.394 -qed
   5.395 -
   5.396 -lemma nat_int [simp]: "nat(int n) = n"
   5.397 -by (simp add: nat int_def) 
   5.398 -
   5.399 -lemma nat_zero [simp]: "nat 0 = 0"
   5.400 -by (simp only: Zero_int_def nat_int)
   5.401 -
   5.402 -lemma int_nat_eq [simp]: "int (nat z) = (if 0 \<le> z then z else 0)"
   5.403 -by (cases z, simp add: nat le int_def Zero_int_def)
   5.404 -
   5.405 -corollary nat_0_le: "0 \<le> z ==> int (nat z) = z"
   5.406 -by simp
   5.407 -
   5.408 -lemma nat_le_0 [simp]: "z \<le> 0 ==> nat z = 0"
   5.409 -by (cases z, simp add: nat le int_def Zero_int_def)
   5.410 -
   5.411 -lemma nat_le_eq_zle: "0 < w | 0 \<le> z ==> (nat w \<le> nat z) = (w\<le>z)"
   5.412 -apply (cases w, cases z) 
   5.413 -apply (simp add: nat le linorder_not_le [symmetric] int_def Zero_int_def, arith)
   5.414 -done
   5.415 -
   5.416 -text{*An alternative condition is @{term "0 \<le> w"} *}
   5.417 -corollary nat_mono_iff: "0 < z ==> (nat w < nat z) = (w < z)"
   5.418 -by (simp add: nat_le_eq_zle linorder_not_le [symmetric]) 
   5.419 -
   5.420 -corollary nat_less_eq_zless: "0 \<le> w ==> (nat w < nat z) = (w<z)"
   5.421 -by (simp add: nat_le_eq_zle linorder_not_le [symmetric]) 
   5.422 -
   5.423 -lemma zless_nat_conj: "(nat w < nat z) = (0 < z & w < z)"
   5.424 -apply (cases w, cases z) 
   5.425 -apply (simp add: nat le int_def Zero_int_def linorder_not_le [symmetric], arith)
   5.426 -done
   5.427 -
   5.428 -lemma nonneg_eq_int: "[| 0 \<le> z;  !!m. z = int m ==> P |] ==> P"
   5.429 -by (blast dest: nat_0_le sym)
   5.430 -
   5.431 -lemma nat_eq_iff: "(nat w = m) = (if 0 \<le> w then w = int m else m=0)"
   5.432 -by (cases w, simp add: nat le int_def Zero_int_def, arith)
   5.433 -
   5.434 -corollary nat_eq_iff2: "(m = nat w) = (if 0 \<le> w then w = int m else m=0)"
   5.435 -by (simp only: eq_commute [of m] nat_eq_iff) 
   5.436 -
   5.437 -lemma nat_less_iff: "0 \<le> w ==> (nat w < m) = (w < int m)"
   5.438 -apply (cases w)
   5.439 -apply (simp add: nat le int_def Zero_int_def linorder_not_le [symmetric], arith)
   5.440 -done
   5.441 -
   5.442 -lemma int_eq_iff: "(int m = z) = (m = nat z & 0 \<le> z)"
   5.443 -by (auto simp add: nat_eq_iff2)
   5.444 -
   5.445 -lemma zero_less_nat_eq [simp]: "(0 < nat z) = (0 < z)"
   5.446 -by (insert zless_nat_conj [of 0], auto)
   5.447 -
   5.448 -lemma nat_add_distrib:
   5.449 -     "[| (0::int) \<le> z;  0 \<le> z' |] ==> nat (z+z') = nat z + nat z'"
   5.450 -by (cases z, cases z', simp add: nat add le int_def Zero_int_def)
   5.451 -
   5.452 -lemma nat_diff_distrib:
   5.453 -     "[| (0::int) \<le> z';  z' \<le> z |] ==> nat (z-z') = nat z - nat z'"
   5.454 -by (cases z, cases z', 
   5.455 -    simp add: nat add minus diff_minus le int_def Zero_int_def)
   5.456 -
   5.457 -
   5.458 -lemma nat_zminus_int [simp]: "nat (- (int n)) = 0"
   5.459 -by (simp add: int_def minus nat Zero_int_def) 
   5.460 -
   5.461 -lemma zless_nat_eq_int_zless: "(m < nat z) = (int m < z)"
   5.462 -by (cases z, simp add: nat le int_def  linorder_not_le [symmetric], arith)
   5.463 -
   5.464 -
   5.465 -subsection{*Lemmas about the Function @{term int} and Orderings*}
   5.466 -
   5.467 -lemma negative_zless_0: "- (int (Suc n)) < 0"
   5.468 -by (simp add: order_less_le)
   5.469 -
   5.470 -lemma negative_zless [iff]: "- (int (Suc n)) < int m"
   5.471 -by (rule negative_zless_0 [THEN order_less_le_trans], simp)
   5.472 -
   5.473 -lemma negative_zle_0: "- int n \<le> 0"
   5.474 -by (simp add: minus_le_iff)
   5.475 -
   5.476 -lemma negative_zle [iff]: "- int n \<le> int m"
   5.477 -by (rule order_trans [OF negative_zle_0 zero_zle_int])
   5.478 -
   5.479 -lemma not_zle_0_negative [simp]: "~ (0 \<le> - (int (Suc n)))"
   5.480 -by (subst le_minus_iff, simp)
   5.481 -
   5.482 -lemma int_zle_neg: "(int n \<le> - int m) = (n = 0 & m = 0)"
   5.483 -by (simp add: int_def le minus Zero_int_def) 
   5.484 -
   5.485 -lemma not_int_zless_negative [simp]: "~ (int n < - int m)"
   5.486 -by (simp add: linorder_not_less)
   5.487 -
   5.488 -lemma negative_eq_positive [simp]: "(- int n = int m) = (n = 0 & m = 0)"
   5.489 -by (force simp add: order_eq_iff [of "- int n"] int_zle_neg)
   5.490 -
   5.491 -lemma zle_iff_zadd: "(w \<le> z) = (\<exists>n. z = w + int n)"
   5.492 -proof (cases w, cases z, simp add: le add int_def)
   5.493 -  fix a b c d
   5.494 -  assume "w = Abs_Integ (intrel `` {(a,b)})" "z = Abs_Integ (intrel `` {(c,d)})"
   5.495 -  show "(a+d \<le> c+b) = (\<exists>n. c+b = a+n+d)"
   5.496 -  proof
   5.497 -    assume "a + d \<le> c + b" 
   5.498 -    thus "\<exists>n. c + b = a + n + d" 
   5.499 -      by (auto intro!: exI [where x="c+b - (a+d)"])
   5.500 -  next    
   5.501 -    assume "\<exists>n. c + b = a + n + d" 
   5.502 -    then obtain n where "c + b = a + n + d" ..
   5.503 -    thus "a + d \<le> c + b" by arith
   5.504 -  qed
   5.505 -qed
   5.506 -
   5.507 -lemma abs_int_eq [simp]: "abs (int m) = int m"
   5.508 -by (simp add: abs_if)
   5.509 -
   5.510 -text{*This version is proved for all ordered rings, not just integers!
   5.511 -      It is proved here because attribute @{text arith_split} is not available
   5.512 -      in theory @{text Ring_and_Field}.
   5.513 -      But is it really better than just rewriting with @{text abs_if}?*}
   5.514 -lemma abs_split [arith_split]:
   5.515 -     "P(abs(a::'a::ordered_idom)) = ((0 \<le> a --> P a) & (a < 0 --> P(-a)))"
   5.516 -by (force dest: order_less_le_trans simp add: abs_if linorder_not_less)
   5.517 -
   5.518 -
   5.519 -subsection {* Constants @{term neg} and @{term iszero} *}
   5.520 -
   5.521 -definition
   5.522 -  neg  :: "'a\<Colon>ordered_idom \<Rightarrow> bool"
   5.523 -where
   5.524 -  [code inline]: "neg Z \<longleftrightarrow> Z < 0"
   5.525 -
   5.526 -definition (*for simplifying equalities*)
   5.527 -  iszero :: "'a\<Colon>comm_semiring_1_cancel \<Rightarrow> bool"
   5.528 -where
   5.529 -  "iszero z \<longleftrightarrow> z = 0"
   5.530 -
   5.531 -lemma not_neg_int [simp]: "~ neg(int n)"
   5.532 -by (simp add: neg_def)
   5.533 -
   5.534 -lemma neg_zminus_int [simp]: "neg(- (int (Suc n)))"
   5.535 -by (simp add: neg_def neg_less_0_iff_less)
   5.536 -
   5.537 -lemmas neg_eq_less_0 = neg_def
   5.538 -
   5.539 -lemma not_neg_eq_ge_0: "(~neg x) = (0 \<le> x)"
   5.540 -by (simp add: neg_def linorder_not_less)
   5.541 -
   5.542 -
   5.543 -subsection{*To simplify inequalities when Numeral1 can get simplified to 1*}
   5.544 -
   5.545 -lemma not_neg_0: "~ neg 0"
   5.546 -by (simp add: One_int_def neg_def)
   5.547 -
   5.548 -lemma not_neg_1: "~ neg 1"
   5.549 -by (simp add: neg_def linorder_not_less zero_le_one)
   5.550 -
   5.551 -lemma iszero_0: "iszero 0"
   5.552 -by (simp add: iszero_def)
   5.553 -
   5.554 -lemma not_iszero_1: "~ iszero 1"
   5.555 -by (simp add: iszero_def eq_commute)
   5.556 -
   5.557 -lemma neg_nat: "neg z ==> nat z = 0"
   5.558 -by (simp add: neg_def order_less_imp_le) 
   5.559 -
   5.560 -lemma not_neg_nat: "~ neg z ==> int (nat z) = z"
   5.561 -by (simp add: linorder_not_less neg_def)
   5.562 -
   5.563 -
   5.564 -subsection{*The Set of Natural Numbers*}
   5.565 -
   5.566 -constdefs
   5.567 -  Nats  :: "'a::semiring_1_cancel set"
   5.568 -  "Nats == range of_nat"
   5.569 -
   5.570 -notation (xsymbols)
   5.571 -  Nats  ("\<nat>")
   5.572 -
   5.573 -lemma of_nat_in_Nats [simp]: "of_nat n \<in> Nats"
   5.574 -by (simp add: Nats_def)
   5.575 -
   5.576 -lemma Nats_0 [simp]: "0 \<in> Nats"
   5.577 -apply (simp add: Nats_def)
   5.578 -apply (rule range_eqI)
   5.579 -apply (rule of_nat_0 [symmetric])
   5.580 -done
   5.581 -
   5.582 -lemma Nats_1 [simp]: "1 \<in> Nats"
   5.583 -apply (simp add: Nats_def)
   5.584 -apply (rule range_eqI)
   5.585 -apply (rule of_nat_1 [symmetric])
   5.586 -done
   5.587 -
   5.588 -lemma Nats_add [simp]: "[|a \<in> Nats; b \<in> Nats|] ==> a+b \<in> Nats"
   5.589 -apply (auto simp add: Nats_def)
   5.590 -apply (rule range_eqI)
   5.591 -apply (rule of_nat_add [symmetric])
   5.592 -done
   5.593 -
   5.594 -lemma Nats_mult [simp]: "[|a \<in> Nats; b \<in> Nats|] ==> a*b \<in> Nats"
   5.595 -apply (auto simp add: Nats_def)
   5.596 -apply (rule range_eqI)
   5.597 -apply (rule of_nat_mult [symmetric])
   5.598 -done
   5.599 -
   5.600 -text{*Agreement with the specific embedding for the integers*}
   5.601 -lemma int_eq_of_nat: "int = (of_nat :: nat => int)"
   5.602 -proof
   5.603 -  fix n
   5.604 -  show "int n = of_nat n"  by (induct n, simp_all add: int_Suc add_ac)
   5.605 -qed
   5.606 -
   5.607 -lemma of_nat_eq_id [simp]: "of_nat = (id :: nat => nat)"
   5.608 -proof
   5.609 -  fix n
   5.610 -  show "of_nat n = id n"  by (induct n, simp_all)
   5.611 -qed
   5.612 -
   5.613 -
   5.614 -subsection{*Embedding of the Integers into any @{text ring_1}:
   5.615 -@{term of_int}*}
   5.616 -
   5.617 -constdefs
   5.618 -   of_int :: "int => 'a::ring_1"
   5.619 -   "of_int z == contents (\<Union>(i,j) \<in> Rep_Integ z. { of_nat i - of_nat j })"
   5.620 -
   5.621 -
   5.622 -lemma of_int: "of_int (Abs_Integ (intrel `` {(i,j)})) = of_nat i - of_nat j"
   5.623 -proof -
   5.624 -  have "(\<lambda>(i,j). { of_nat i - (of_nat j :: 'a) }) respects intrel"
   5.625 -    by (simp add: congruent_def compare_rls of_nat_add [symmetric]
   5.626 -            del: of_nat_add) 
   5.627 -  thus ?thesis
   5.628 -    by (simp add: of_int_def UN_equiv_class [OF equiv_intrel])
   5.629 -qed
   5.630 -
   5.631 -lemma of_int_0 [simp]: "of_int 0 = 0"
   5.632 -by (simp add: of_int Zero_int_def int_def)
   5.633 -
   5.634 -lemma of_int_1 [simp]: "of_int 1 = 1"
   5.635 -by (simp add: of_int One_int_def int_def)
   5.636 -
   5.637 -lemma of_int_add [simp]: "of_int (w+z) = of_int w + of_int z"
   5.638 -by (cases w, cases z, simp add: compare_rls of_int add)
   5.639 -
   5.640 -lemma of_int_minus [simp]: "of_int (-z) = - (of_int z)"
   5.641 -by (cases z, simp add: compare_rls of_int minus)
   5.642 -
   5.643 -lemma of_int_diff [simp]: "of_int (w-z) = of_int w - of_int z"
   5.644 -by (simp add: diff_minus)
   5.645 -
   5.646 -lemma of_int_mult [simp]: "of_int (w*z) = of_int w * of_int z"
   5.647 -apply (cases w, cases z)
   5.648 -apply (simp add: compare_rls of_int left_diff_distrib right_diff_distrib
   5.649 -                 mult add_ac)
   5.650 -done
   5.651 -
   5.652 -lemma of_int_le_iff [simp]:
   5.653 -     "(of_int w \<le> (of_int z::'a::ordered_idom)) = (w \<le> z)"
   5.654 -apply (cases w)
   5.655 -apply (cases z)
   5.656 -apply (simp add: compare_rls of_int le diff_int_def add minus
   5.657 -                 of_nat_add [symmetric]   del: of_nat_add)
   5.658 -done
   5.659 -
   5.660 -text{*Special cases where either operand is zero*}
   5.661 -lemmas of_int_0_le_iff [simp] = of_int_le_iff [of 0, simplified]
   5.662 -lemmas of_int_le_0_iff [simp] = of_int_le_iff [of _ 0, simplified]
   5.663 -
   5.664 -
   5.665 -lemma of_int_less_iff [simp]:
   5.666 -     "(of_int w < (of_int z::'a::ordered_idom)) = (w < z)"
   5.667 -by (simp add: linorder_not_le [symmetric])
   5.668 -
   5.669 -text{*Special cases where either operand is zero*}
   5.670 -lemmas of_int_0_less_iff [simp] = of_int_less_iff [of 0, simplified]
   5.671 -lemmas of_int_less_0_iff [simp] = of_int_less_iff [of _ 0, simplified]
   5.672 -
   5.673 -text{*Class for unital rings with characteristic zero.
   5.674 - Includes non-ordered rings like the complex numbers.*}
   5.675 -axclass ring_char_0 < ring_1
   5.676 -  of_int_inject: "of_int w = of_int z ==> w = z"
   5.677 -
   5.678 -lemma of_int_eq_iff [simp]:
   5.679 -     "(of_int w = (of_int z::'a::ring_char_0)) = (w = z)"
   5.680 -by (safe elim!: of_int_inject)
   5.681 -
   5.682 -text{*Every @{text ordered_idom} has characteristic zero.*}
   5.683 -instance ordered_idom < ring_char_0
   5.684 -by intro_classes (simp add: order_eq_iff)
   5.685 -
   5.686 -text{*Special cases where either operand is zero*}
   5.687 -lemmas of_int_0_eq_iff [simp] = of_int_eq_iff [of 0, simplified]
   5.688 -lemmas of_int_eq_0_iff [simp] = of_int_eq_iff [of _ 0, simplified]
   5.689 -
   5.690 -lemma of_int_eq_id [simp]: "of_int = (id :: int => int)"
   5.691 -proof
   5.692 -  fix z
   5.693 -  show "of_int z = id z"  
   5.694 -    by (cases z)
   5.695 -      (simp add: of_int add minus int_eq_of_nat [symmetric] int_def diff_minus)
   5.696 -qed
   5.697 -
   5.698 -
   5.699 -subsection{*The Set of Integers*}
   5.700 -
   5.701 -constdefs
   5.702 -  Ints  :: "'a::ring_1 set"
   5.703 -  "Ints == range of_int"
   5.704 -
   5.705 -notation (xsymbols)
   5.706 -  Ints  ("\<int>")
   5.707 -
   5.708 -lemma Ints_0 [simp]: "0 \<in> Ints"
   5.709 -apply (simp add: Ints_def)
   5.710 -apply (rule range_eqI)
   5.711 -apply (rule of_int_0 [symmetric])
   5.712 -done
   5.713 -
   5.714 -lemma Ints_1 [simp]: "1 \<in> Ints"
   5.715 -apply (simp add: Ints_def)
   5.716 -apply (rule range_eqI)
   5.717 -apply (rule of_int_1 [symmetric])
   5.718 -done
   5.719 -
   5.720 -lemma Ints_add [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a+b \<in> Ints"
   5.721 -apply (auto simp add: Ints_def)
   5.722 -apply (rule range_eqI)
   5.723 -apply (rule of_int_add [symmetric])
   5.724 -done
   5.725 -
   5.726 -lemma Ints_minus [simp]: "a \<in> Ints ==> -a \<in> Ints"
   5.727 -apply (auto simp add: Ints_def)
   5.728 -apply (rule range_eqI)
   5.729 -apply (rule of_int_minus [symmetric])
   5.730 -done
   5.731 -
   5.732 -lemma Ints_diff [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a-b \<in> Ints"
   5.733 -apply (auto simp add: Ints_def)
   5.734 -apply (rule range_eqI)
   5.735 -apply (rule of_int_diff [symmetric])
   5.736 -done
   5.737 -
   5.738 -lemma Ints_mult [simp]: "[|a \<in> Ints; b \<in> Ints|] ==> a*b \<in> Ints"
   5.739 -apply (auto simp add: Ints_def)
   5.740 -apply (rule range_eqI)
   5.741 -apply (rule of_int_mult [symmetric])
   5.742 -done
   5.743 -
   5.744 -text{*Collapse nested embeddings*}
   5.745 -lemma of_int_of_nat_eq [simp]: "of_int (of_nat n) = of_nat n"
   5.746 -by (induct n, auto)
   5.747 -
   5.748 -lemma of_int_int_eq [simp]: "of_int (int n) = of_nat n"
   5.749 -by (simp add: int_eq_of_nat)
   5.750 -
   5.751 -lemma Ints_cases [cases set: Ints]:
   5.752 -  assumes "q \<in> \<int>"
   5.753 -  obtains (of_int) z where "q = of_int z"
   5.754 -  unfolding Ints_def
   5.755 -proof -
   5.756 -  from `q \<in> \<int>` have "q \<in> range of_int" unfolding Ints_def .
   5.757 -  then obtain z where "q = of_int z" ..
   5.758 -  then show thesis ..
   5.759 -qed
   5.760 -
   5.761 -lemma Ints_induct [case_names of_int, induct set: Ints]:
   5.762 -  "q \<in> \<int> ==> (!!z. P (of_int z)) ==> P q"
   5.763 -  by (rule Ints_cases) auto
   5.764 -
   5.765 -
   5.766 -(* int (Suc n) = 1 + int n *)
   5.767 -
   5.768 -
   5.769 -
   5.770 -subsection{*More Properties of @{term setsum} and  @{term setprod}*}
   5.771 -
   5.772 -text{*By Jeremy Avigad*}
   5.773 -
   5.774 -
   5.775 -lemma of_nat_setsum: "of_nat (setsum f A) = (\<Sum>x\<in>A. of_nat(f x))"
   5.776 -  apply (cases "finite A")
   5.777 -  apply (erule finite_induct, auto)
   5.778 -  done
   5.779 -
   5.780 -lemma of_int_setsum: "of_int (setsum f A) = (\<Sum>x\<in>A. of_int(f x))"
   5.781 -  apply (cases "finite A")
   5.782 -  apply (erule finite_induct, auto)
   5.783 -  done
   5.784 -
   5.785 -lemma int_setsum: "int (setsum f A) = (\<Sum>x\<in>A. int(f x))"
   5.786 -  by (simp add: int_eq_of_nat of_nat_setsum)
   5.787 -
   5.788 -lemma of_nat_setprod: "of_nat (setprod f A) = (\<Prod>x\<in>A. of_nat(f x))"
   5.789 -  apply (cases "finite A")
   5.790 -  apply (erule finite_induct, auto)
   5.791 -  done
   5.792 -
   5.793 -lemma of_int_setprod: "of_int (setprod f A) = (\<Prod>x\<in>A. of_int(f x))"
   5.794 -  apply (cases "finite A")
   5.795 -  apply (erule finite_induct, auto)
   5.796 -  done
   5.797 -
   5.798 -lemma int_setprod: "int (setprod f A) = (\<Prod>x\<in>A. int(f x))"
   5.799 -  by (simp add: int_eq_of_nat of_nat_setprod)
   5.800 -
   5.801 -lemma setprod_nonzero_nat:
   5.802 -    "finite A ==> (\<forall>x \<in> A. f x \<noteq> (0::nat)) ==> setprod f A \<noteq> 0"
   5.803 -  by (rule setprod_nonzero, auto)
   5.804 -
   5.805 -lemma setprod_zero_eq_nat:
   5.806 -    "finite A ==> (setprod f A = (0::nat)) = (\<exists>x \<in> A. f x = 0)"
   5.807 -  by (rule setprod_zero_eq, auto)
   5.808 -
   5.809 -lemma setprod_nonzero_int:
   5.810 -    "finite A ==> (\<forall>x \<in> A. f x \<noteq> (0::int)) ==> setprod f A \<noteq> 0"
   5.811 -  by (rule setprod_nonzero, auto)
   5.812 -
   5.813 -lemma setprod_zero_eq_int:
   5.814 -    "finite A ==> (setprod f A = (0::int)) = (\<exists>x \<in> A. f x = 0)"
   5.815 -  by (rule setprod_zero_eq, auto)
   5.816 -
   5.817 -
   5.818 -subsection {* Further properties *}
   5.819 -
   5.820 -text{*Now we replace the case analysis rule by a more conventional one:
   5.821 -whether an integer is negative or not.*}
   5.822 -
   5.823 -lemma zless_iff_Suc_zadd:
   5.824 -    "(w < z) = (\<exists>n. z = w + int(Suc n))"
   5.825 -apply (cases z, cases w)
   5.826 -apply (auto simp add: le add int_def linorder_not_le [symmetric]) 
   5.827 -apply (rename_tac a b c d) 
   5.828 -apply (rule_tac x="a+d - Suc(c+b)" in exI) 
   5.829 -apply arith
   5.830 -done
   5.831 -
   5.832 -lemma negD: "x<0 ==> \<exists>n. x = - (int (Suc n))"
   5.833 -apply (cases x)
   5.834 -apply (auto simp add: le minus Zero_int_def int_def order_less_le) 
   5.835 -apply (rule_tac x="y - Suc x" in exI, arith)
   5.836 -done
   5.837 -
   5.838 -theorem int_cases [cases type: int, case_names nonneg neg]:
   5.839 -     "[|!! n. z = int n ==> P;  !! n. z =  - (int (Suc n)) ==> P |] ==> P"
   5.840 -apply (cases "z < 0", blast dest!: negD)
   5.841 -apply (simp add: linorder_not_less)
   5.842 -apply (blast dest: nat_0_le [THEN sym])
   5.843 -done
   5.844 -
   5.845 -theorem int_induct [induct type: int, case_names nonneg neg]:
   5.846 -     "[|!! n. P (int n);  !!n. P (- (int (Suc n))) |] ==> P z"
   5.847 -  by (cases z) auto
   5.848 -
   5.849 -text{*Contributed by Brian Huffman*}
   5.850 -theorem int_diff_cases [case_names diff]:
   5.851 -assumes prem: "!!m n. z = int m - int n ==> P" shows "P"
   5.852 - apply (rule_tac z=z in int_cases)
   5.853 -  apply (rule_tac m=n and n=0 in prem, simp)
   5.854 - apply (rule_tac m=0 and n="Suc n" in prem, simp)
   5.855 -done
   5.856 -
   5.857 -lemma of_nat_nat: "0 \<le> z ==> of_nat (nat z) = of_int z"
   5.858 -apply (cases z)
   5.859 -apply (simp_all add: not_zle_0_negative del: int_Suc)
   5.860 -done
   5.861 -
   5.862 -lemmas zless_le = less_int_def [THEN meta_eq_to_obj_eq]
   5.863 -
   5.864 -lemmas [simp] = int_Suc
   5.865 -
   5.866 -
   5.867 -subsection {* Legacy ML bindings *}
   5.868 -
   5.869 -ML {*
   5.870 -val of_nat_0 = @{thm of_nat_0};
   5.871 -val of_nat_1 = @{thm of_nat_1};
   5.872 -val of_nat_Suc = @{thm of_nat_Suc};
   5.873 -val of_nat_add = @{thm of_nat_add};
   5.874 -val of_nat_mult = @{thm of_nat_mult};
   5.875 -val of_int_0 = @{thm of_int_0};
   5.876 -val of_int_1 = @{thm of_int_1};
   5.877 -val of_int_add = @{thm of_int_add};
   5.878 -val of_int_mult = @{thm of_int_mult};
   5.879 -val int_eq_of_nat = @{thm int_eq_of_nat};
   5.880 -val zle_int = @{thm zle_int};
   5.881 -val int_int_eq = @{thm int_int_eq};
   5.882 -val diff_int_def = @{thm diff_int_def};
   5.883 -val zadd_ac = @{thms zadd_ac};
   5.884 -val zless_int = @{thm zless_int};
   5.885 -val zadd_int = @{thm zadd_int};
   5.886 -val zmult_int = @{thm zmult_int};
   5.887 -val nat_0_le = @{thm nat_0_le};
   5.888 -val int_0 = @{thm int_0};
   5.889 -val int_1 = @{thm int_1};
   5.890 -val abs_split = @{thm abs_split};
   5.891 -*}
   5.892 -
   5.893 -end
     6.1 --- a/src/HOL/Integ/IntDiv.thy	Thu May 31 18:16:51 2007 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,1406 +0,0 @@
     6.4 -(*  Title:      HOL/IntDiv.thy
     6.5 -    ID:         $Id$
     6.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     6.7 -    Copyright   1999  University of Cambridge
     6.8 -
     6.9 -*)
    6.10 -
    6.11 -header{*The Division Operators div and mod; the Divides Relation dvd*}
    6.12 -
    6.13 -theory IntDiv
    6.14 -imports IntArith "../Divides" "../FunDef"
    6.15 -begin
    6.16 -
    6.17 -declare zless_nat_conj [simp]
    6.18 -
    6.19 -constdefs
    6.20 -  quorem :: "(int*int) * (int*int) => bool"
    6.21 -    --{*definition of quotient and remainder*}
    6.22 -    [code func]: "quorem == %((a,b), (q,r)).
    6.23 -                      a = b*q + r &
    6.24 -                      (if 0 < b then 0\<le>r & r<b else b<r & r \<le> 0)"
    6.25 -
    6.26 -  adjust :: "[int, int*int] => int*int"
    6.27 -    --{*for the division algorithm*}
    6.28 -    [code func]: "adjust b == %(q,r). if 0 \<le> r-b then (2*q + 1, r-b)
    6.29 -                         else (2*q, r)"
    6.30 -
    6.31 -text{*algorithm for the case @{text "a\<ge>0, b>0"}*}
    6.32 -function
    6.33 -  posDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    6.34 -where
    6.35 -  "posDivAlg a b =
    6.36 -     (if (a<b | b\<le>0) then (0,a)
    6.37 -        else adjust b (posDivAlg a (2*b)))"
    6.38 -by auto
    6.39 -termination by (relation "measure (%(a,b). nat(a - b + 1))") auto
    6.40 -
    6.41 -text{*algorithm for the case @{text "a<0, b>0"}*}
    6.42 -function
    6.43 -  negDivAlg :: "int \<Rightarrow> int \<Rightarrow> int \<times> int"
    6.44 -where
    6.45 -  "negDivAlg a b  =
    6.46 -     (if (0\<le>a+b | b\<le>0) then (-1,a+b)
    6.47 -      else adjust b (negDivAlg a (2*b)))"
    6.48 -by auto
    6.49 -termination by (relation "measure (%(a,b). nat(- a - b))") auto
    6.50 -
    6.51 -text{*algorithm for the general case @{term "b\<noteq>0"}*}
    6.52 -constdefs
    6.53 -  negateSnd :: "int*int => int*int"
    6.54 -    [code func]: "negateSnd == %(q,r). (q,-r)"
    6.55 -
    6.56 -definition
    6.57 -  divAlg :: "int \<times> int \<Rightarrow> int \<times> int"
    6.58 -    --{*The full division algorithm considers all possible signs for a, b
    6.59 -       including the special case @{text "a=0, b<0"} because 
    6.60 -       @{term negDivAlg} requires @{term "a<0"}.*}
    6.61 -where
    6.62 -  "divAlg = (\<lambda>(a, b). (if 0\<le>a then
    6.63 -                  if 0\<le>b then posDivAlg a b
    6.64 -                  else if a=0 then (0, 0)
    6.65 -                       else negateSnd (negDivAlg (-a) (-b))
    6.66 -               else 
    6.67 -                  if 0<b then negDivAlg a b
    6.68 -                  else negateSnd (posDivAlg (-a) (-b))))"
    6.69 -
    6.70 -instance int :: Divides.div
    6.71 -  div_def: "a div b == fst (divAlg (a, b))"
    6.72 -  mod_def: "a mod b == snd (divAlg (a, b))" ..
    6.73 -
    6.74 -lemma divAlg_mod_div:
    6.75 -  "divAlg (p, q) = (p div q, p mod q)"
    6.76 -  by (auto simp add: div_def mod_def)
    6.77 -
    6.78 -text{*
    6.79 -Here is the division algorithm in ML:
    6.80 -
    6.81 -\begin{verbatim}
    6.82 -    fun posDivAlg (a,b) =
    6.83 -      if a<b then (0,a)
    6.84 -      else let val (q,r) = posDivAlg(a, 2*b)
    6.85 -	       in  if 0\<le>r-b then (2*q+1, r-b) else (2*q, r)
    6.86 -	   end
    6.87 -
    6.88 -    fun negDivAlg (a,b) =
    6.89 -      if 0\<le>a+b then (~1,a+b)
    6.90 -      else let val (q,r) = negDivAlg(a, 2*b)
    6.91 -	       in  if 0\<le>r-b then (2*q+1, r-b) else (2*q, r)
    6.92 -	   end;
    6.93 -
    6.94 -    fun negateSnd (q,r:int) = (q,~r);
    6.95 -
    6.96 -    fun divAlg (a,b) = if 0\<le>a then 
    6.97 -			  if b>0 then posDivAlg (a,b) 
    6.98 -			   else if a=0 then (0,0)
    6.99 -				else negateSnd (negDivAlg (~a,~b))
   6.100 -		       else 
   6.101 -			  if 0<b then negDivAlg (a,b)
   6.102 -			  else        negateSnd (posDivAlg (~a,~b));
   6.103 -\end{verbatim}
   6.104 -*}
   6.105 -
   6.106 -
   6.107 -
   6.108 -subsection{*Uniqueness and Monotonicity of Quotients and Remainders*}
   6.109 -
   6.110 -lemma unique_quotient_lemma:
   6.111 -     "[| b*q' + r'  \<le> b*q + r;  0 \<le> r';  r' < b;  r < b |]  
   6.112 -      ==> q' \<le> (q::int)"
   6.113 -apply (subgoal_tac "r' + b * (q'-q) \<le> r")
   6.114 - prefer 2 apply (simp add: right_diff_distrib)
   6.115 -apply (subgoal_tac "0 < b * (1 + q - q') ")
   6.116 -apply (erule_tac [2] order_le_less_trans)
   6.117 - prefer 2 apply (simp add: right_diff_distrib right_distrib)
   6.118 -apply (subgoal_tac "b * q' < b * (1 + q) ")
   6.119 - prefer 2 apply (simp add: right_diff_distrib right_distrib)
   6.120 -apply (simp add: mult_less_cancel_left)
   6.121 -done
   6.122 -
   6.123 -lemma unique_quotient_lemma_neg:
   6.124 -     "[| b*q' + r' \<le> b*q + r;  r \<le> 0;  b < r;  b < r' |]  
   6.125 -      ==> q \<le> (q'::int)"
   6.126 -by (rule_tac b = "-b" and r = "-r'" and r' = "-r" in unique_quotient_lemma, 
   6.127 -    auto)
   6.128 -
   6.129 -lemma unique_quotient:
   6.130 -     "[| quorem ((a,b), (q,r));  quorem ((a,b), (q',r'));  b \<noteq> 0 |]  
   6.131 -      ==> q = q'"
   6.132 -apply (simp add: quorem_def linorder_neq_iff split: split_if_asm)
   6.133 -apply (blast intro: order_antisym
   6.134 -             dest: order_eq_refl [THEN unique_quotient_lemma] 
   6.135 -             order_eq_refl [THEN unique_quotient_lemma_neg] sym)+
   6.136 -done
   6.137 -
   6.138 -
   6.139 -lemma unique_remainder:
   6.140 -     "[| quorem ((a,b), (q,r));  quorem ((a,b), (q',r'));  b \<noteq> 0 |]  
   6.141 -      ==> r = r'"
   6.142 -apply (subgoal_tac "q = q'")
   6.143 - apply (simp add: quorem_def)
   6.144 -apply (blast intro: unique_quotient)
   6.145 -done
   6.146 -
   6.147 -
   6.148 -subsection{*Correctness of @{term posDivAlg}, the Algorithm for Non-Negative Dividends*}
   6.149 -
   6.150 -text{*And positive divisors*}
   6.151 -
   6.152 -lemma adjust_eq [simp]:
   6.153 -     "adjust b (q,r) = 
   6.154 -      (let diff = r-b in  
   6.155 -	if 0 \<le> diff then (2*q + 1, diff)   
   6.156 -                     else (2*q, r))"
   6.157 -by (simp add: Let_def adjust_def)
   6.158 -
   6.159 -declare posDivAlg.simps [simp del]
   6.160 -
   6.161 -text{*use with a simproc to avoid repeatedly proving the premise*}
   6.162 -lemma posDivAlg_eqn:
   6.163 -     "0 < b ==>  
   6.164 -      posDivAlg a b = (if a<b then (0,a) else adjust b (posDivAlg a (2*b)))"
   6.165 -by (rule posDivAlg.simps [THEN trans], simp)
   6.166 -
   6.167 -text{*Correctness of @{term posDivAlg}: it computes quotients correctly*}
   6.168 -theorem posDivAlg_correct:
   6.169 -  assumes "0 \<le> a" and "0 < b"
   6.170 -  shows "quorem ((a, b), posDivAlg a b)"
   6.171 -using prems apply (induct a b rule: posDivAlg.induct)
   6.172 -apply auto
   6.173 -apply (simp add: quorem_def)
   6.174 -apply (subst posDivAlg_eqn, simp add: right_distrib)
   6.175 -apply (case_tac "a < b")
   6.176 -apply simp_all
   6.177 -apply (erule splitE)
   6.178 -apply (auto simp add: right_distrib Let_def)
   6.179 -done
   6.180 -
   6.181 -
   6.182 -subsection{*Correctness of @{term negDivAlg}, the Algorithm for Negative Dividends*}
   6.183 -
   6.184 -text{*And positive divisors*}
   6.185 -
   6.186 -declare negDivAlg.simps [simp del]
   6.187 -
   6.188 -text{*use with a simproc to avoid repeatedly proving the premise*}
   6.189 -lemma negDivAlg_eqn:
   6.190 -     "0 < b ==>  
   6.191 -      negDivAlg a b =       
   6.192 -       (if 0\<le>a+b then (-1,a+b) else adjust b (negDivAlg a (2*b)))"
   6.193 -by (rule negDivAlg.simps [THEN trans], simp)
   6.194 -
   6.195 -(*Correctness of negDivAlg: it computes quotients correctly
   6.196 -  It doesn't work if a=0 because the 0/b equals 0, not -1*)
   6.197 -lemma negDivAlg_correct:
   6.198 -  assumes "a < 0" and "b > 0"
   6.199 -  shows "quorem ((a, b), negDivAlg a b)"
   6.200 -using prems apply (induct a b rule: negDivAlg.induct)
   6.201 -apply (auto simp add: linorder_not_le)
   6.202 -apply (simp add: quorem_def)
   6.203 -apply (subst negDivAlg_eqn, assumption)
   6.204 -apply (case_tac "a + b < (0\<Colon>int)")
   6.205 -apply simp_all
   6.206 -apply (erule splitE)
   6.207 -apply (auto simp add: right_distrib Let_def)
   6.208 -done
   6.209 -
   6.210 -
   6.211 -subsection{*Existence Shown by Proving the Division Algorithm to be Correct*}
   6.212 -
   6.213 -(*the case a=0*)
   6.214 -lemma quorem_0: "b \<noteq> 0 ==> quorem ((0,b), (0,0))"
   6.215 -by (auto simp add: quorem_def linorder_neq_iff)
   6.216 -
   6.217 -lemma posDivAlg_0 [simp]: "posDivAlg 0 b = (0, 0)"
   6.218 -by (subst posDivAlg.simps, auto)
   6.219 -
   6.220 -lemma negDivAlg_minus1 [simp]: "negDivAlg -1 b = (-1, b - 1)"
   6.221 -by (subst negDivAlg.simps, auto)
   6.222 -
   6.223 -lemma negateSnd_eq [simp]: "negateSnd(q,r) = (q,-r)"
   6.224 -by (simp add: negateSnd_def)
   6.225 -
   6.226 -lemma quorem_neg: "quorem ((-a,-b), qr) ==> quorem ((a,b), negateSnd qr)"
   6.227 -by (auto simp add: split_ifs quorem_def)
   6.228 -
   6.229 -lemma divAlg_correct: "b \<noteq> 0 ==> quorem ((a,b), divAlg (a, b))"
   6.230 -by (force simp add: linorder_neq_iff quorem_0 divAlg_def quorem_neg
   6.231 -                    posDivAlg_correct negDivAlg_correct)
   6.232 -
   6.233 -text{*Arbitrary definitions for division by zero.  Useful to simplify 
   6.234 -    certain equations.*}
   6.235 -
   6.236 -lemma DIVISION_BY_ZERO [simp]: "a div (0::int) = 0 & a mod (0::int) = a"
   6.237 -by (simp add: div_def mod_def divAlg_def posDivAlg.simps)  
   6.238 -
   6.239 -
   6.240 -text{*Basic laws about division and remainder*}
   6.241 -
   6.242 -lemma zmod_zdiv_equality: "(a::int) = b * (a div b) + (a mod b)"
   6.243 -apply (case_tac "b = 0", simp)
   6.244 -apply (cut_tac a = a and b = b in divAlg_correct)
   6.245 -apply (auto simp add: quorem_def div_def mod_def)
   6.246 -done
   6.247 -
   6.248 -lemma zdiv_zmod_equality: "(b * (a div b) + (a mod b)) + k = (a::int)+k"
   6.249 -by(simp add: zmod_zdiv_equality[symmetric])
   6.250 -
   6.251 -lemma zdiv_zmod_equality2: "((a div b) * b + (a mod b)) + k = (a::int)+k"
   6.252 -by(simp add: mult_commute zmod_zdiv_equality[symmetric])
   6.253 -
   6.254 -text {* Tool setup *}
   6.255 -
   6.256 -ML_setup {*
   6.257 -local 
   6.258 -
   6.259 -structure CancelDivMod = CancelDivModFun(
   6.260 -struct
   6.261 -  val div_name = @{const_name Divides.div};
   6.262 -  val mod_name = @{const_name Divides.mod};
   6.263 -  val mk_binop = HOLogic.mk_binop;
   6.264 -  val mk_sum = Int_Numeral_Simprocs.mk_sum HOLogic.intT;
   6.265 -  val dest_sum = Int_Numeral_Simprocs.dest_sum;
   6.266 -  val div_mod_eqs =
   6.267 -    map mk_meta_eq [@{thm zdiv_zmod_equality},
   6.268 -      @{thm zdiv_zmod_equality2}];
   6.269 -  val trans = trans;
   6.270 -  val prove_eq_sums =
   6.271 -    let
   6.272 -      val simps = diff_int_def :: Int_Numeral_Simprocs.add_0s @ zadd_ac
   6.273 -    in NatArithUtils.prove_conv all_tac (NatArithUtils.simp_all_tac simps) end;
   6.274 -end)
   6.275 -
   6.276 -in
   6.277 -
   6.278 -val cancel_zdiv_zmod_proc = NatArithUtils.prep_simproc
   6.279 -  ("cancel_zdiv_zmod", ["(m::int) + n"], K CancelDivMod.proc)
   6.280 -
   6.281 -end;
   6.282 -
   6.283 -Addsimprocs [cancel_zdiv_zmod_proc]
   6.284 -*}
   6.285 -
   6.286 -lemma pos_mod_conj : "(0::int) < b ==> 0 \<le> a mod b & a mod b < b"
   6.287 -apply (cut_tac a = a and b = b in divAlg_correct)
   6.288 -apply (auto simp add: quorem_def mod_def)
   6.289 -done
   6.290 -
   6.291 -lemmas pos_mod_sign  [simp] = pos_mod_conj [THEN conjunct1, standard]
   6.292 -   and pos_mod_bound [simp] = pos_mod_conj [THEN conjunct2, standard]
   6.293 -
   6.294 -lemma neg_mod_conj : "b < (0::int) ==> a mod b \<le> 0 & b < a mod b"
   6.295 -apply (cut_tac a = a and b = b in divAlg_correct)
   6.296 -apply (auto simp add: quorem_def div_def mod_def)
   6.297 -done
   6.298 -
   6.299 -lemmas neg_mod_sign  [simp] = neg_mod_conj [THEN conjunct1, standard]
   6.300 -   and neg_mod_bound [simp] = neg_mod_conj [THEN conjunct2, standard]
   6.301 -
   6.302 -
   6.303 -
   6.304 -subsection{*General Properties of div and mod*}
   6.305 -
   6.306 -lemma quorem_div_mod: "b \<noteq> 0 ==> quorem ((a, b), (a div b, a mod b))"
   6.307 -apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   6.308 -apply (force simp add: quorem_def linorder_neq_iff)
   6.309 -done
   6.310 -
   6.311 -lemma quorem_div: "[| quorem((a,b),(q,r));  b \<noteq> 0 |] ==> a div b = q"
   6.312 -by (simp add: quorem_div_mod [THEN unique_quotient])
   6.313 -
   6.314 -lemma quorem_mod: "[| quorem((a,b),(q,r));  b \<noteq> 0 |] ==> a mod b = r"
   6.315 -by (simp add: quorem_div_mod [THEN unique_remainder])
   6.316 -
   6.317 -lemma div_pos_pos_trivial: "[| (0::int) \<le> a;  a < b |] ==> a div b = 0"
   6.318 -apply (rule quorem_div)
   6.319 -apply (auto simp add: quorem_def)
   6.320 -done
   6.321 -
   6.322 -lemma div_neg_neg_trivial: "[| a \<le> (0::int);  b < a |] ==> a div b = 0"
   6.323 -apply (rule quorem_div)
   6.324 -apply (auto simp add: quorem_def)
   6.325 -done
   6.326 -
   6.327 -lemma div_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a div b = -1"
   6.328 -apply (rule quorem_div)
   6.329 -apply (auto simp add: quorem_def)
   6.330 -done
   6.331 -
   6.332 -(*There is no div_neg_pos_trivial because  0 div b = 0 would supersede it*)
   6.333 -
   6.334 -lemma mod_pos_pos_trivial: "[| (0::int) \<le> a;  a < b |] ==> a mod b = a"
   6.335 -apply (rule_tac q = 0 in quorem_mod)
   6.336 -apply (auto simp add: quorem_def)
   6.337 -done
   6.338 -
   6.339 -lemma mod_neg_neg_trivial: "[| a \<le> (0::int);  b < a |] ==> a mod b = a"
   6.340 -apply (rule_tac q = 0 in quorem_mod)
   6.341 -apply (auto simp add: quorem_def)
   6.342 -done
   6.343 -
   6.344 -lemma mod_pos_neg_trivial: "[| (0::int) < a;  a+b \<le> 0 |] ==> a mod b = a+b"
   6.345 -apply (rule_tac q = "-1" in quorem_mod)
   6.346 -apply (auto simp add: quorem_def)
   6.347 -done
   6.348 -
   6.349 -text{*There is no @{text mod_neg_pos_trivial}.*}
   6.350 -
   6.351 -
   6.352 -(*Simpler laws such as -a div b = -(a div b) FAIL, but see just below*)
   6.353 -lemma zdiv_zminus_zminus [simp]: "(-a) div (-b) = a div (b::int)"
   6.354 -apply (case_tac "b = 0", simp)
   6.355 -apply (simp add: quorem_div_mod [THEN quorem_neg, simplified, 
   6.356 -                                 THEN quorem_div, THEN sym])
   6.357 -
   6.358 -done
   6.359 -
   6.360 -(*Simpler laws such as -a mod b = -(a mod b) FAIL, but see just below*)
   6.361 -lemma zmod_zminus_zminus [simp]: "(-a) mod (-b) = - (a mod (b::int))"
   6.362 -apply (case_tac "b = 0", simp)
   6.363 -apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_mod],
   6.364 -       auto)
   6.365 -done
   6.366 -
   6.367 -
   6.368 -subsection{*Laws for div and mod with Unary Minus*}
   6.369 -
   6.370 -lemma zminus1_lemma:
   6.371 -     "quorem((a,b),(q,r))  
   6.372 -      ==> quorem ((-a,b), (if r=0 then -q else -q - 1),  
   6.373 -                          (if r=0 then 0 else b-r))"
   6.374 -by (force simp add: split_ifs quorem_def linorder_neq_iff right_diff_distrib)
   6.375 -
   6.376 -
   6.377 -lemma zdiv_zminus1_eq_if:
   6.378 -     "b \<noteq> (0::int)  
   6.379 -      ==> (-a) div b =  
   6.380 -          (if a mod b = 0 then - (a div b) else  - (a div b) - 1)"
   6.381 -by (blast intro: quorem_div_mod [THEN zminus1_lemma, THEN quorem_div])
   6.382 -
   6.383 -lemma zmod_zminus1_eq_if:
   6.384 -     "(-a::int) mod b = (if a mod b = 0 then 0 else  b - (a mod b))"
   6.385 -apply (case_tac "b = 0", simp)
   6.386 -apply (blast intro: quorem_div_mod [THEN zminus1_lemma, THEN quorem_mod])
   6.387 -done
   6.388 -
   6.389 -lemma zdiv_zminus2: "a div (-b) = (-a::int) div b"
   6.390 -by (cut_tac a = "-a" in zdiv_zminus_zminus, auto)
   6.391 -
   6.392 -lemma zmod_zminus2: "a mod (-b) = - ((-a::int) mod b)"
   6.393 -by (cut_tac a = "-a" and b = b in zmod_zminus_zminus, auto)
   6.394 -
   6.395 -lemma zdiv_zminus2_eq_if:
   6.396 -     "b \<noteq> (0::int)  
   6.397 -      ==> a div (-b) =  
   6.398 -          (if a mod b = 0 then - (a div b) else  - (a div b) - 1)"
   6.399 -by (simp add: zdiv_zminus1_eq_if zdiv_zminus2)
   6.400 -
   6.401 -lemma zmod_zminus2_eq_if:
   6.402 -     "a mod (-b::int) = (if a mod b = 0 then 0 else  (a mod b) - b)"
   6.403 -by (simp add: zmod_zminus1_eq_if zmod_zminus2)
   6.404 -
   6.405 -
   6.406 -subsection{*Division of a Number by Itself*}
   6.407 -
   6.408 -lemma self_quotient_aux1: "[| (0::int) < a; a = r + a*q; r < a |] ==> 1 \<le> q"
   6.409 -apply (subgoal_tac "0 < a*q")
   6.410 - apply (simp add: zero_less_mult_iff, arith)
   6.411 -done
   6.412 -
   6.413 -lemma self_quotient_aux2: "[| (0::int) < a; a = r + a*q; 0 \<le> r |] ==> q \<le> 1"
   6.414 -apply (subgoal_tac "0 \<le> a* (1-q) ")
   6.415 - apply (simp add: zero_le_mult_iff)
   6.416 -apply (simp add: right_diff_distrib)
   6.417 -done
   6.418 -
   6.419 -lemma self_quotient: "[| quorem((a,a),(q,r));  a \<noteq> (0::int) |] ==> q = 1"
   6.420 -apply (simp add: split_ifs quorem_def linorder_neq_iff)
   6.421 -apply (rule order_antisym, safe, simp_all)
   6.422 -apply (rule_tac [3] a = "-a" and r = "-r" in self_quotient_aux1)
   6.423 -apply (rule_tac a = "-a" and r = "-r" in self_quotient_aux2)
   6.424 -apply (force intro: self_quotient_aux1 self_quotient_aux2 simp add: add_commute)+
   6.425 -done
   6.426 -
   6.427 -lemma self_remainder: "[| quorem((a,a),(q,r));  a \<noteq> (0::int) |] ==> r = 0"
   6.428 -apply (frule self_quotient, assumption)
   6.429 -apply (simp add: quorem_def)
   6.430 -done
   6.431 -
   6.432 -lemma zdiv_self [simp]: "a \<noteq> 0 ==> a div a = (1::int)"
   6.433 -by (simp add: quorem_div_mod [THEN self_quotient])
   6.434 -
   6.435 -(*Here we have 0 mod 0 = 0, also assumed by Knuth (who puts m mod 0 = 0) *)
   6.436 -lemma zmod_self [simp]: "a mod a = (0::int)"
   6.437 -apply (case_tac "a = 0", simp)
   6.438 -apply (simp add: quorem_div_mod [THEN self_remainder])
   6.439 -done
   6.440 -
   6.441 -
   6.442 -subsection{*Computation of Division and Remainder*}
   6.443 -
   6.444 -lemma zdiv_zero [simp]: "(0::int) div b = 0"
   6.445 -by (simp add: div_def divAlg_def)
   6.446 -
   6.447 -lemma div_eq_minus1: "(0::int) < b ==> -1 div b = -1"
   6.448 -by (simp add: div_def divAlg_def)
   6.449 -
   6.450 -lemma zmod_zero [simp]: "(0::int) mod b = 0"
   6.451 -by (simp add: mod_def divAlg_def)
   6.452 -
   6.453 -lemma zdiv_minus1: "(0::int) < b ==> -1 div b = -1"
   6.454 -by (simp add: div_def divAlg_def)
   6.455 -
   6.456 -lemma zmod_minus1: "(0::int) < b ==> -1 mod b = b - 1"
   6.457 -by (simp add: mod_def divAlg_def)
   6.458 -
   6.459 -text{*a positive, b positive *}
   6.460 -
   6.461 -lemma div_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a div b = fst (posDivAlg a b)"
   6.462 -by (simp add: div_def divAlg_def)
   6.463 -
   6.464 -lemma mod_pos_pos: "[| 0 < a;  0 \<le> b |] ==> a mod b = snd (posDivAlg a b)"
   6.465 -by (simp add: mod_def divAlg_def)
   6.466 -
   6.467 -text{*a negative, b positive *}
   6.468 -
   6.469 -lemma div_neg_pos: "[| a < 0;  0 < b |] ==> a div b = fst (negDivAlg a b)"
   6.470 -by (simp add: div_def divAlg_def)
   6.471 -
   6.472 -lemma mod_neg_pos: "[| a < 0;  0 < b |] ==> a mod b = snd (negDivAlg a b)"
   6.473 -by (simp add: mod_def divAlg_def)
   6.474 -
   6.475 -text{*a positive, b negative *}
   6.476 -
   6.477 -lemma div_pos_neg:
   6.478 -     "[| 0 < a;  b < 0 |] ==> a div b = fst (negateSnd (negDivAlg (-a) (-b)))"
   6.479 -by (simp add: div_def divAlg_def)
   6.480 -
   6.481 -lemma mod_pos_neg:
   6.482 -     "[| 0 < a;  b < 0 |] ==> a mod b = snd (negateSnd (negDivAlg (-a) (-b)))"
   6.483 -by (simp add: mod_def divAlg_def)
   6.484 -
   6.485 -text{*a negative, b negative *}
   6.486 -
   6.487 -lemma div_neg_neg:
   6.488 -     "[| a < 0;  b \<le> 0 |] ==> a div b = fst (negateSnd (posDivAlg (-a) (-b)))"
   6.489 -by (simp add: div_def divAlg_def)
   6.490 -
   6.491 -lemma mod_neg_neg:
   6.492 -     "[| a < 0;  b \<le> 0 |] ==> a mod b = snd (negateSnd (posDivAlg (-a) (-b)))"
   6.493 -by (simp add: mod_def divAlg_def)
   6.494 -
   6.495 -text {*Simplify expresions in which div and mod combine numerical constants*}
   6.496 -
   6.497 -lemmas div_pos_pos_number_of [simp] =
   6.498 -    div_pos_pos [of "number_of v" "number_of w", standard]
   6.499 -
   6.500 -lemmas div_neg_pos_number_of [simp] =
   6.501 -    div_neg_pos [of "number_of v" "number_of w", standard]
   6.502 -
   6.503 -lemmas div_pos_neg_number_of [simp] =
   6.504 -    div_pos_neg [of "number_of v" "number_of w", standard]
   6.505 -
   6.506 -lemmas div_neg_neg_number_of [simp] =
   6.507 -    div_neg_neg [of "number_of v" "number_of w", standard]
   6.508 -
   6.509 -
   6.510 -lemmas mod_pos_pos_number_of [simp] =
   6.511 -    mod_pos_pos [of "number_of v" "number_of w", standard]
   6.512 -
   6.513 -lemmas mod_neg_pos_number_of [simp] =
   6.514 -    mod_neg_pos [of "number_of v" "number_of w", standard]
   6.515 -
   6.516 -lemmas mod_pos_neg_number_of [simp] =
   6.517 -    mod_pos_neg [of "number_of v" "number_of w", standard]
   6.518 -
   6.519 -lemmas mod_neg_neg_number_of [simp] =
   6.520 -    mod_neg_neg [of "number_of v" "number_of w", standard]
   6.521 -
   6.522 -
   6.523 -lemmas posDivAlg_eqn_number_of [simp] =
   6.524 -    posDivAlg_eqn [of "number_of v" "number_of w", standard]
   6.525 -
   6.526 -lemmas negDivAlg_eqn_number_of [simp] =
   6.527 -    negDivAlg_eqn [of "number_of v" "number_of w", standard]
   6.528 -
   6.529 -
   6.530 -text{*Special-case simplification *}
   6.531 -
   6.532 -lemma zmod_1 [simp]: "a mod (1::int) = 0"
   6.533 -apply (cut_tac a = a and b = 1 in pos_mod_sign)
   6.534 -apply (cut_tac [2] a = a and b = 1 in pos_mod_bound)
   6.535 -apply (auto simp del:pos_mod_bound pos_mod_sign)
   6.536 -done
   6.537 -
   6.538 -lemma zdiv_1 [simp]: "a div (1::int) = a"
   6.539 -by (cut_tac a = a and b = 1 in zmod_zdiv_equality, auto)
   6.540 -
   6.541 -lemma zmod_minus1_right [simp]: "a mod (-1::int) = 0"
   6.542 -apply (cut_tac a = a and b = "-1" in neg_mod_sign)
   6.543 -apply (cut_tac [2] a = a and b = "-1" in neg_mod_bound)
   6.544 -apply (auto simp del: neg_mod_sign neg_mod_bound)
   6.545 -done
   6.546 -
   6.547 -lemma zdiv_minus1_right [simp]: "a div (-1::int) = -a"
   6.548 -by (cut_tac a = a and b = "-1" in zmod_zdiv_equality, auto)
   6.549 -
   6.550 -(** The last remaining special cases for constant arithmetic:
   6.551 -    1 div z and 1 mod z **)
   6.552 -
   6.553 -lemmas div_pos_pos_1_number_of [simp] =
   6.554 -    div_pos_pos [OF int_0_less_1, of "number_of w", standard]
   6.555 -
   6.556 -lemmas div_pos_neg_1_number_of [simp] =
   6.557 -    div_pos_neg [OF int_0_less_1, of "number_of w", standard]
   6.558 -
   6.559 -lemmas mod_pos_pos_1_number_of [simp] =
   6.560 -    mod_pos_pos [OF int_0_less_1, of "number_of w", standard]
   6.561 -
   6.562 -lemmas mod_pos_neg_1_number_of [simp] =
   6.563 -    mod_pos_neg [OF int_0_less_1, of "number_of w", standard]
   6.564 -
   6.565 -
   6.566 -lemmas posDivAlg_eqn_1_number_of [simp] =
   6.567 -    posDivAlg_eqn [of concl: 1 "number_of w", standard]
   6.568 -
   6.569 -lemmas negDivAlg_eqn_1_number_of [simp] =
   6.570 -    negDivAlg_eqn [of concl: 1 "number_of w", standard]
   6.571 -
   6.572 -
   6.573 -
   6.574 -subsection{*Monotonicity in the First Argument (Dividend)*}
   6.575 -
   6.576 -lemma zdiv_mono1: "[| a \<le> a';  0 < (b::int) |] ==> a div b \<le> a' div b"
   6.577 -apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   6.578 -apply (cut_tac a = a' and b = b in zmod_zdiv_equality)
   6.579 -apply (rule unique_quotient_lemma)
   6.580 -apply (erule subst)
   6.581 -apply (erule subst, simp_all)
   6.582 -done
   6.583 -
   6.584 -lemma zdiv_mono1_neg: "[| a \<le> a';  (b::int) < 0 |] ==> a' div b \<le> a div b"
   6.585 -apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   6.586 -apply (cut_tac a = a' and b = b in zmod_zdiv_equality)
   6.587 -apply (rule unique_quotient_lemma_neg)
   6.588 -apply (erule subst)
   6.589 -apply (erule subst, simp_all)
   6.590 -done
   6.591 -
   6.592 -
   6.593 -subsection{*Monotonicity in the Second Argument (Divisor)*}
   6.594 -
   6.595 -lemma q_pos_lemma:
   6.596 -     "[| 0 \<le> b'*q' + r'; r' < b';  0 < b' |] ==> 0 \<le> (q'::int)"
   6.597 -apply (subgoal_tac "0 < b'* (q' + 1) ")
   6.598 - apply (simp add: zero_less_mult_iff)
   6.599 -apply (simp add: right_distrib)
   6.600 -done
   6.601 -
   6.602 -lemma zdiv_mono2_lemma:
   6.603 -     "[| b*q + r = b'*q' + r';  0 \<le> b'*q' + r';   
   6.604 -         r' < b';  0 \<le> r;  0 < b';  b' \<le> b |]   
   6.605 -      ==> q \<le> (q'::int)"
   6.606 -apply (frule q_pos_lemma, assumption+) 
   6.607 -apply (subgoal_tac "b*q < b* (q' + 1) ")
   6.608 - apply (simp add: mult_less_cancel_left)
   6.609 -apply (subgoal_tac "b*q = r' - r + b'*q'")
   6.610 - prefer 2 apply simp
   6.611 -apply (simp (no_asm_simp) add: right_distrib)
   6.612 -apply (subst add_commute, rule zadd_zless_mono, arith)
   6.613 -apply (rule mult_right_mono, auto)
   6.614 -done
   6.615 -
   6.616 -lemma zdiv_mono2:
   6.617 -     "[| (0::int) \<le> a;  0 < b';  b' \<le> b |] ==> a div b \<le> a div b'"
   6.618 -apply (subgoal_tac "b \<noteq> 0")
   6.619 - prefer 2 apply arith
   6.620 -apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   6.621 -apply (cut_tac a = a and b = b' in zmod_zdiv_equality)
   6.622 -apply (rule zdiv_mono2_lemma)
   6.623 -apply (erule subst)
   6.624 -apply (erule subst, simp_all)
   6.625 -done
   6.626 -
   6.627 -lemma q_neg_lemma:
   6.628 -     "[| b'*q' + r' < 0;  0 \<le> r';  0 < b' |] ==> q' \<le> (0::int)"
   6.629 -apply (subgoal_tac "b'*q' < 0")
   6.630 - apply (simp add: mult_less_0_iff, arith)
   6.631 -done
   6.632 -
   6.633 -lemma zdiv_mono2_neg_lemma:
   6.634 -     "[| b*q + r = b'*q' + r';  b'*q' + r' < 0;   
   6.635 -         r < b;  0 \<le> r';  0 < b';  b' \<le> b |]   
   6.636 -      ==> q' \<le> (q::int)"
   6.637 -apply (frule q_neg_lemma, assumption+) 
   6.638 -apply (subgoal_tac "b*q' < b* (q + 1) ")
   6.639 - apply (simp add: mult_less_cancel_left)
   6.640 -apply (simp add: right_distrib)
   6.641 -apply (subgoal_tac "b*q' \<le> b'*q'")
   6.642 - prefer 2 apply (simp add: mult_right_mono_neg, arith)
   6.643 -done
   6.644 -
   6.645 -lemma zdiv_mono2_neg:
   6.646 -     "[| a < (0::int);  0 < b';  b' \<le> b |] ==> a div b' \<le> a div b"
   6.647 -apply (cut_tac a = a and b = b in zmod_zdiv_equality)
   6.648 -apply (cut_tac a = a and b = b' in zmod_zdiv_equality)
   6.649 -apply (rule zdiv_mono2_neg_lemma)
   6.650 -apply (erule subst)
   6.651 -apply (erule subst, simp_all)
   6.652 -done
   6.653 -
   6.654 -subsection{*More Algebraic Laws for div and mod*}
   6.655 -
   6.656 -text{*proving (a*b) div c = a * (b div c) + a * (b mod c) *}
   6.657 -
   6.658 -lemma zmult1_lemma:
   6.659 -     "[| quorem((b,c),(q,r));  c \<noteq> 0 |]  
   6.660 -      ==> quorem ((a*b, c), (a*q + a*r div c, a*r mod c))"
   6.661 -by (force simp add: split_ifs quorem_def linorder_neq_iff right_distrib)
   6.662 -
   6.663 -lemma zdiv_zmult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::int)"
   6.664 -apply (case_tac "c = 0", simp)
   6.665 -apply (blast intro: quorem_div_mod [THEN zmult1_lemma, THEN quorem_div])
   6.666 -done
   6.667 -
   6.668 -lemma zmod_zmult1_eq: "(a*b) mod c = a*(b mod c) mod (c::int)"
   6.669 -apply (case_tac "c = 0", simp)
   6.670 -apply (blast intro: quorem_div_mod [THEN zmult1_lemma, THEN quorem_mod])
   6.671 -done
   6.672 -
   6.673 -lemma zmod_zmult1_eq': "(a*b) mod (c::int) = ((a mod c) * b) mod c"
   6.674 -apply (rule trans)
   6.675 -apply (rule_tac s = "b*a mod c" in trans)
   6.676 -apply (rule_tac [2] zmod_zmult1_eq)
   6.677 -apply (simp_all add: mult_commute)
   6.678 -done
   6.679 -
   6.680 -lemma zmod_zmult_distrib: "(a*b) mod (c::int) = ((a mod c) * (b mod c)) mod c"
   6.681 -apply (rule zmod_zmult1_eq' [THEN trans])
   6.682 -apply (rule zmod_zmult1_eq)
   6.683 -done
   6.684 -
   6.685 -lemma zdiv_zmult_self1 [simp]: "b \<noteq> (0::int) ==> (a*b) div b = a"
   6.686 -by (simp add: zdiv_zmult1_eq)
   6.687 -
   6.688 -lemma zdiv_zmult_self2 [simp]: "b \<noteq> (0::int) ==> (b*a) div b = a"
   6.689 -by (subst mult_commute, erule zdiv_zmult_self1)
   6.690 -
   6.691 -lemma zmod_zmult_self1 [simp]: "(a*b) mod b = (0::int)"
   6.692 -by (simp add: zmod_zmult1_eq)
   6.693 -
   6.694 -lemma zmod_zmult_self2 [simp]: "(b*a) mod b = (0::int)"
   6.695 -by (simp add: mult_commute zmod_zmult1_eq)
   6.696 -
   6.697 -lemma zmod_eq_0_iff: "(m mod d = 0) = (EX q::int. m = d*q)"
   6.698 -proof
   6.699 -  assume "m mod d = 0"
   6.700 -  with zmod_zdiv_equality[of m d] show "EX q::int. m = d*q" by auto
   6.701 -next
   6.702 -  assume "EX q::int. m = d*q"
   6.703 -  thus "m mod d = 0" by auto
   6.704 -qed
   6.705 -
   6.706 -lemmas zmod_eq_0D [dest!] = zmod_eq_0_iff [THEN iffD1]
   6.707 -
   6.708 -text{*proving (a+b) div c = a div c + b div c + ((a mod c + b mod c) div c) *}
   6.709 -
   6.710 -lemma zadd1_lemma:
   6.711 -     "[| quorem((a,c),(aq,ar));  quorem((b,c),(bq,br));  c \<noteq> 0 |]  
   6.712 -      ==> quorem ((a+b, c), (aq + bq + (ar+br) div c, (ar+br) mod c))"
   6.713 -by (force simp add: split_ifs quorem_def linorder_neq_iff right_distrib)
   6.714 -
   6.715 -(*NOT suitable for rewriting: the RHS has an instance of the LHS*)
   6.716 -lemma zdiv_zadd1_eq:
   6.717 -     "(a+b) div (c::int) = a div c + b div c + ((a mod c + b mod c) div c)"
   6.718 -apply (case_tac "c = 0", simp)
   6.719 -apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod] quorem_div)
   6.720 -done
   6.721 -
   6.722 -lemma zmod_zadd1_eq: "(a+b) mod (c::int) = (a mod c + b mod c) mod c"
   6.723 -apply (case_tac "c = 0", simp)
   6.724 -apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod] quorem_mod)
   6.725 -done
   6.726 -
   6.727 -lemma mod_div_trivial [simp]: "(a mod b) div b = (0::int)"
   6.728 -apply (case_tac "b = 0", simp)
   6.729 -apply (auto simp add: linorder_neq_iff div_pos_pos_trivial div_neg_neg_trivial)
   6.730 -done
   6.731 -
   6.732 -lemma mod_mod_trivial [simp]: "(a mod b) mod b = a mod (b::int)"
   6.733 -apply (case_tac "b = 0", simp)
   6.734 -apply (force simp add: linorder_neq_iff mod_pos_pos_trivial mod_neg_neg_trivial)
   6.735 -done
   6.736 -
   6.737 -lemma zmod_zadd_left_eq: "(a+b) mod (c::int) = ((a mod c) + b) mod c"
   6.738 -apply (rule trans [symmetric])
   6.739 -apply (rule zmod_zadd1_eq, simp)
   6.740 -apply (rule zmod_zadd1_eq [symmetric])
   6.741 -done
   6.742 -
   6.743 -lemma zmod_zadd_right_eq: "(a+b) mod (c::int) = (a + (b mod c)) mod c"
   6.744 -apply (rule trans [symmetric])
   6.745 -apply (rule zmod_zadd1_eq, simp)
   6.746 -apply (rule zmod_zadd1_eq [symmetric])
   6.747 -done
   6.748 -
   6.749 -lemma zdiv_zadd_self1[simp]: "a \<noteq> (0::int) ==> (a+b) div a = b div a + 1"
   6.750 -by (simp add: zdiv_zadd1_eq)
   6.751 -
   6.752 -lemma zdiv_zadd_self2[simp]: "a \<noteq> (0::int) ==> (b+a) div a = b div a + 1"
   6.753 -by (simp add: zdiv_zadd1_eq)
   6.754 -
   6.755 -lemma zmod_zadd_self1[simp]: "(a+b) mod a = b mod (a::int)"
   6.756 -apply (case_tac "a = 0", simp)
   6.757 -apply (simp add: zmod_zadd1_eq)
   6.758 -done
   6.759 -
   6.760 -lemma zmod_zadd_self2[simp]: "(b+a) mod a = b mod (a::int)"
   6.761 -apply (case_tac "a = 0", simp)
   6.762 -apply (simp add: zmod_zadd1_eq)
   6.763 -done
   6.764 -
   6.765 -
   6.766 -subsection{*Proving  @{term "a div (b*c) = (a div b) div c"} *}
   6.767 -
   6.768 -(*The condition c>0 seems necessary.  Consider that 7 div ~6 = ~2 but
   6.769 -  7 div 2 div ~3 = 3 div ~3 = ~1.  The subcase (a div b) mod c = 0 seems
   6.770 -  to cause particular problems.*)
   6.771 -
   6.772 -text{*first, four lemmas to bound the remainder for the cases b<0 and b>0 *}
   6.773 -
   6.774 -lemma zmult2_lemma_aux1: "[| (0::int) < c;  b < r;  r \<le> 0 |] ==> b*c < b*(q mod c) + r"
   6.775 -apply (subgoal_tac "b * (c - q mod c) < r * 1")
   6.776 -apply (simp add: right_diff_distrib)
   6.777 -apply (rule order_le_less_trans)
   6.778 -apply (erule_tac [2] mult_strict_right_mono)
   6.779 -apply (rule mult_left_mono_neg)
   6.780 -apply (auto simp add: compare_rls add_commute [of 1]
   6.781 -                      add1_zle_eq pos_mod_bound)
   6.782 -done
   6.783 -
   6.784 -lemma zmult2_lemma_aux2:
   6.785 -     "[| (0::int) < c;   b < r;  r \<le> 0 |] ==> b * (q mod c) + r \<le> 0"
   6.786 -apply (subgoal_tac "b * (q mod c) \<le> 0")
   6.787 - apply arith
   6.788 -apply (simp add: mult_le_0_iff)
   6.789 -done
   6.790 -
   6.791 -lemma zmult2_lemma_aux3: "[| (0::int) < c;  0 \<le> r;  r < b |] ==> 0 \<le> b * (q mod c) + r"
   6.792 -apply (subgoal_tac "0 \<le> b * (q mod c) ")
   6.793 -apply arith
   6.794 -apply (simp add: zero_le_mult_iff)
   6.795 -done
   6.796 -
   6.797 -lemma zmult2_lemma_aux4: "[| (0::int) < c; 0 \<le> r; r < b |] ==> b * (q mod c) + r < b * c"
   6.798 -apply (subgoal_tac "r * 1 < b * (c - q mod c) ")
   6.799 -apply (simp add: right_diff_distrib)
   6.800 -apply (rule order_less_le_trans)
   6.801 -apply (erule mult_strict_right_mono)
   6.802 -apply (rule_tac [2] mult_left_mono)
   6.803 -apply (auto simp add: compare_rls add_commute [of 1]
   6.804 -                      add1_zle_eq pos_mod_bound)
   6.805 -done
   6.806 -
   6.807 -lemma zmult2_lemma: "[| quorem ((a,b), (q,r));  b \<noteq> 0;  0 < c |]  
   6.808 -      ==> quorem ((a, b*c), (q div c, b*(q mod c) + r))"
   6.809 -by (auto simp add: mult_ac quorem_def linorder_neq_iff
   6.810 -                   zero_less_mult_iff right_distrib [symmetric] 
   6.811 -                   zmult2_lemma_aux1 zmult2_lemma_aux2 zmult2_lemma_aux3 zmult2_lemma_aux4)
   6.812 -
   6.813 -lemma zdiv_zmult2_eq: "(0::int) < c ==> a div (b*c) = (a div b) div c"
   6.814 -apply (case_tac "b = 0", simp)
   6.815 -apply (force simp add: quorem_div_mod [THEN zmult2_lemma, THEN quorem_div])
   6.816 -done
   6.817 -
   6.818 -lemma zmod_zmult2_eq:
   6.819 -     "(0::int) < c ==> a mod (b*c) = b*(a div b mod c) + a mod b"
   6.820 -apply (case_tac "b = 0", simp)
   6.821 -apply (force simp add: quorem_div_mod [THEN zmult2_lemma, THEN quorem_mod])
   6.822 -done
   6.823 -
   6.824 -
   6.825 -subsection{*Cancellation of Common Factors in div*}
   6.826 -
   6.827 -lemma zdiv_zmult_zmult1_aux1:
   6.828 -     "[| (0::int) < b;  c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
   6.829 -by (subst zdiv_zmult2_eq, auto)
   6.830 -
   6.831 -lemma zdiv_zmult_zmult1_aux2:
   6.832 -     "[| b < (0::int);  c \<noteq> 0 |] ==> (c*a) div (c*b) = a div b"
   6.833 -apply (subgoal_tac " (c * (-a)) div (c * (-b)) = (-a) div (-b) ")
   6.834 -apply (rule_tac [2] zdiv_zmult_zmult1_aux1, auto)
   6.835 -done
   6.836 -
   6.837 -lemma zdiv_zmult_zmult1: "c \<noteq> (0::int) ==> (c*a) div (c*b) = a div b"
   6.838 -apply (case_tac "b = 0", simp)
   6.839 -apply (auto simp add: linorder_neq_iff zdiv_zmult_zmult1_aux1 zdiv_zmult_zmult1_aux2)
   6.840 -done
   6.841 -
   6.842 -lemma zdiv_zmult_zmult2: "c \<noteq> (0::int) ==> (a*c) div (b*c) = a div b"
   6.843 -apply (drule zdiv_zmult_zmult1)
   6.844 -apply (auto simp add: mult_commute)
   6.845 -done
   6.846 -
   6.847 -
   6.848 -
   6.849 -subsection{*Distribution of Factors over mod*}
   6.850 -
   6.851 -lemma zmod_zmult_zmult1_aux1:
   6.852 -     "[| (0::int) < b;  c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
   6.853 -by (subst zmod_zmult2_eq, auto)
   6.854 -
   6.855 -lemma zmod_zmult_zmult1_aux2:
   6.856 -     "[| b < (0::int);  c \<noteq> 0 |] ==> (c*a) mod (c*b) = c * (a mod b)"
   6.857 -apply (subgoal_tac " (c * (-a)) mod (c * (-b)) = c * ((-a) mod (-b))")
   6.858 -apply (rule_tac [2] zmod_zmult_zmult1_aux1, auto)
   6.859 -done
   6.860 -
   6.861 -lemma zmod_zmult_zmult1: "(c*a) mod (c*b) = (c::int) * (a mod b)"
   6.862 -apply (case_tac "b = 0", simp)
   6.863 -apply (case_tac "c = 0", simp)
   6.864 -apply (auto simp add: linorder_neq_iff zmod_zmult_zmult1_aux1 zmod_zmult_zmult1_aux2)
   6.865 -done
   6.866 -
   6.867 -lemma zmod_zmult_zmult2: "(a*c) mod (b*c) = (a mod b) * (c::int)"
   6.868 -apply (cut_tac c = c in zmod_zmult_zmult1)
   6.869 -apply (auto simp add: mult_commute)
   6.870 -done
   6.871 -
   6.872 -
   6.873 -subsection {*Splitting Rules for div and mod*}
   6.874 -
   6.875 -text{*The proofs of the two lemmas below are essentially identical*}
   6.876 -
   6.877 -lemma split_pos_lemma:
   6.878 - "0<k ==> 
   6.879 -    P(n div k :: int)(n mod k) = (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P i j)"
   6.880 -apply (rule iffI, clarify)
   6.881 - apply (erule_tac P="P ?x ?y" in rev_mp)  
   6.882 - apply (subst zmod_zadd1_eq) 
   6.883 - apply (subst zdiv_zadd1_eq) 
   6.884 - apply (simp add: div_pos_pos_trivial mod_pos_pos_trivial)  
   6.885 -txt{*converse direction*}
   6.886 -apply (drule_tac x = "n div k" in spec) 
   6.887 -apply (drule_tac x = "n mod k" in spec, simp)
   6.888 -done
   6.889 -
   6.890 -lemma split_neg_lemma:
   6.891 - "k<0 ==>
   6.892 -    P(n div k :: int)(n mod k) = (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P i j)"
   6.893 -apply (rule iffI, clarify)
   6.894 - apply (erule_tac P="P ?x ?y" in rev_mp)  
   6.895 - apply (subst zmod_zadd1_eq) 
   6.896 - apply (subst zdiv_zadd1_eq) 
   6.897 - apply (simp add: div_neg_neg_trivial mod_neg_neg_trivial)  
   6.898 -txt{*converse direction*}
   6.899 -apply (drule_tac x = "n div k" in spec) 
   6.900 -apply (drule_tac x = "n mod k" in spec, simp)
   6.901 -done
   6.902 -
   6.903 -lemma split_zdiv:
   6.904 - "P(n div k :: int) =
   6.905 -  ((k = 0 --> P 0) & 
   6.906 -   (0<k --> (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P i)) & 
   6.907 -   (k<0 --> (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P i)))"
   6.908 -apply (case_tac "k=0", simp)
   6.909 -apply (simp only: linorder_neq_iff)
   6.910 -apply (erule disjE) 
   6.911 - apply (simp_all add: split_pos_lemma [of concl: "%x y. P x"] 
   6.912 -                      split_neg_lemma [of concl: "%x y. P x"])
   6.913 -done
   6.914 -
   6.915 -lemma split_zmod:
   6.916 - "P(n mod k :: int) =
   6.917 -  ((k = 0 --> P n) & 
   6.918 -   (0<k --> (\<forall>i j. 0\<le>j & j<k & n = k*i + j --> P j)) & 
   6.919 -   (k<0 --> (\<forall>i j. k<j & j\<le>0 & n = k*i + j --> P j)))"
   6.920 -apply (case_tac "k=0", simp)
   6.921 -apply (simp only: linorder_neq_iff)
   6.922 -apply (erule disjE) 
   6.923 - apply (simp_all add: split_pos_lemma [of concl: "%x y. P y"] 
   6.924 -                      split_neg_lemma [of concl: "%x y. P y"])
   6.925 -done
   6.926 -
   6.927 -(* Enable arith to deal with div 2 and mod 2: *)
   6.928 -declare split_zdiv [of _ _ "number_of k", simplified, standard, arith_split]
   6.929 -declare split_zmod [of _ _ "number_of k", simplified, standard, arith_split]
   6.930 -
   6.931 -
   6.932 -subsection{*Speeding up the Division Algorithm with Shifting*}
   6.933 -
   6.934 -text{*computing div by shifting *}
   6.935 -
   6.936 -lemma pos_zdiv_mult_2: "(0::int) \<le> a ==> (1 + 2*b) div (2*a) = b div a"
   6.937 -proof cases
   6.938 -  assume "a=0"
   6.939 -    thus ?thesis by simp
   6.940 -next
   6.941 -  assume "a\<noteq>0" and le_a: "0\<le>a"   
   6.942 -  hence a_pos: "1 \<le> a" by arith
   6.943 -  hence one_less_a2: "1 < 2*a" by arith
   6.944 -  hence le_2a: "2 * (1 + b mod a) \<le> 2 * a"
   6.945 -    by (simp add: mult_le_cancel_left add_commute [of 1] add1_zle_eq)
   6.946 -  with a_pos have "0 \<le> b mod a" by simp
   6.947 -  hence le_addm: "0 \<le> 1 mod (2*a) + 2*(b mod a)"
   6.948 -    by (simp add: mod_pos_pos_trivial one_less_a2)
   6.949 -  with  le_2a
   6.950 -  have "(1 mod (2*a) + 2*(b mod a)) div (2*a) = 0"
   6.951 -    by (simp add: div_pos_pos_trivial le_addm mod_pos_pos_trivial one_less_a2
   6.952 -                  right_distrib) 
   6.953 -  thus ?thesis
   6.954 -    by (subst zdiv_zadd1_eq,
   6.955 -        simp add: zdiv_zmult_zmult1 zmod_zmult_zmult1 one_less_a2
   6.956 -                  div_pos_pos_trivial)
   6.957 -qed
   6.958 -
   6.959 -lemma neg_zdiv_mult_2: "a \<le> (0::int) ==> (1 + 2*b) div (2*a) = (b+1) div a"
   6.960 -apply (subgoal_tac " (1 + 2* (-b - 1)) div (2 * (-a)) = (-b - 1) div (-a) ")
   6.961 -apply (rule_tac [2] pos_zdiv_mult_2)
   6.962 -apply (auto simp add: minus_mult_right [symmetric] right_diff_distrib)
   6.963 -apply (subgoal_tac " (-1 - (2 * b)) = - (1 + (2 * b))")
   6.964 -apply (simp only: zdiv_zminus_zminus diff_minus minus_add_distrib [symmetric],
   6.965 -       simp) 
   6.966 -done
   6.967 -
   6.968 -
   6.969 -(*Not clear why this must be proved separately; probably number_of causes
   6.970 -  simplification problems*)
   6.971 -lemma not_0_le_lemma: "~ 0 \<le> x ==> x \<le> (0::int)"
   6.972 -by auto
   6.973 -
   6.974 -lemma zdiv_number_of_BIT[simp]:
   6.975 -     "number_of (v BIT b) div number_of (w BIT bit.B0) =  
   6.976 -          (if b=bit.B0 | (0::int) \<le> number_of w                    
   6.977 -           then number_of v div (number_of w)     
   6.978 -           else (number_of v + (1::int)) div (number_of w))"
   6.979 -apply (simp only: number_of_eq numeral_simps UNIV_I split: split_if) 
   6.980 -apply (simp add: zdiv_zmult_zmult1 pos_zdiv_mult_2 neg_zdiv_mult_2 add_ac 
   6.981 -            split: bit.split)
   6.982 -done
   6.983 -
   6.984 -
   6.985 -subsection{*Computing mod by Shifting (proofs resemble those for div)*}
   6.986 -
   6.987 -lemma pos_zmod_mult_2:
   6.988 -     "(0::int) \<le> a ==> (1 + 2*b) mod (2*a) = 1 + 2 * (b mod a)"
   6.989 -apply (case_tac "a = 0", simp)
   6.990 -apply (subgoal_tac "1 < a * 2")
   6.991 - prefer 2 apply arith
   6.992 -apply (subgoal_tac "2* (1 + b mod a) \<le> 2*a")
   6.993 - apply (rule_tac [2] mult_left_mono)
   6.994 -apply (auto simp add: add_commute [of 1] mult_commute add1_zle_eq 
   6.995 -                      pos_mod_bound)
   6.996 -apply (subst zmod_zadd1_eq)
   6.997 -apply (simp add: zmod_zmult_zmult2 mod_pos_pos_trivial)
   6.998 -apply (rule mod_pos_pos_trivial)
   6.999 -apply (auto simp add: mod_pos_pos_trivial left_distrib)
  6.1000 -apply (subgoal_tac "0 \<le> b mod a", arith, simp)
  6.1001 -done
  6.1002 -
  6.1003 -lemma neg_zmod_mult_2:
  6.1004 -     "a \<le> (0::int) ==> (1 + 2*b) mod (2*a) = 2 * ((b+1) mod a) - 1"
  6.1005 -apply (subgoal_tac "(1 + 2* (-b - 1)) mod (2* (-a)) = 
  6.1006 -                    1 + 2* ((-b - 1) mod (-a))")
  6.1007 -apply (rule_tac [2] pos_zmod_mult_2)
  6.1008 -apply (auto simp add: minus_mult_right [symmetric] right_diff_distrib)
  6.1009 -apply (subgoal_tac " (-1 - (2 * b)) = - (1 + (2 * b))")
  6.1010 - prefer 2 apply simp 
  6.1011 -apply (simp only: zmod_zminus_zminus diff_minus minus_add_distrib [symmetric])
  6.1012 -done
  6.1013 -
  6.1014 -lemma zmod_number_of_BIT [simp]:
  6.1015 -     "number_of (v BIT b) mod number_of (w BIT bit.B0) =  
  6.1016 -      (case b of
  6.1017 -          bit.B0 => 2 * (number_of v mod number_of w)
  6.1018 -        | bit.B1 => if (0::int) \<le> number_of w  
  6.1019 -                then 2 * (number_of v mod number_of w) + 1     
  6.1020 -                else 2 * ((number_of v + (1::int)) mod number_of w) - 1)"
  6.1021 -apply (simp only: number_of_eq numeral_simps UNIV_I split: bit.split) 
  6.1022 -apply (simp add: zmod_zmult_zmult1 pos_zmod_mult_2 
  6.1023 -                 not_0_le_lemma neg_zmod_mult_2 add_ac)
  6.1024 -done
  6.1025 -
  6.1026 -
  6.1027 -subsection{*Quotients of Signs*}
  6.1028 -
  6.1029 -lemma div_neg_pos_less0: "[| a < (0::int);  0 < b |] ==> a div b < 0"
  6.1030 -apply (subgoal_tac "a div b \<le> -1", force)
  6.1031 -apply (rule order_trans)
  6.1032 -apply (rule_tac a' = "-1" in zdiv_mono1)
  6.1033 -apply (auto simp add: zdiv_minus1)
  6.1034 -done
  6.1035 -
  6.1036 -lemma div_nonneg_neg_le0: "[| (0::int) \<le> a;  b < 0 |] ==> a div b \<le> 0"
  6.1037 -by (drule zdiv_mono1_neg, auto)
  6.1038 -
  6.1039 -lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)"
  6.1040 -apply auto
  6.1041 -apply (drule_tac [2] zdiv_mono1)
  6.1042 -apply (auto simp add: linorder_neq_iff)
  6.1043 -apply (simp (no_asm_use) add: linorder_not_less [symmetric])
  6.1044 -apply (blast intro: div_neg_pos_less0)
  6.1045 -done
  6.1046 -
  6.1047 -lemma neg_imp_zdiv_nonneg_iff:
  6.1048 -     "b < (0::int) ==> (0 \<le> a div b) = (a \<le> (0::int))"
  6.1049 -apply (subst zdiv_zminus_zminus [symmetric])
  6.1050 -apply (subst pos_imp_zdiv_nonneg_iff, auto)
  6.1051 -done
  6.1052 -
  6.1053 -(*But not (a div b \<le> 0 iff a\<le>0); consider a=1, b=2 when a div b = 0.*)
  6.1054 -lemma pos_imp_zdiv_neg_iff: "(0::int) < b ==> (a div b < 0) = (a < 0)"
  6.1055 -by (simp add: linorder_not_le [symmetric] pos_imp_zdiv_nonneg_iff)
  6.1056 -
  6.1057 -(*Again the law fails for \<le>: consider a = -1, b = -2 when a div b = 0*)
  6.1058 -lemma neg_imp_zdiv_neg_iff: "b < (0::int) ==> (a div b < 0) = (0 < a)"
  6.1059 -by (simp add: linorder_not_le [symmetric] neg_imp_zdiv_nonneg_iff)
  6.1060 -
  6.1061 -
  6.1062 -subsection {* The Divides Relation *}
  6.1063 -
  6.1064 -lemma zdvd_iff_zmod_eq_0: "(m dvd n) = (n mod m = (0::int))"
  6.1065 -by(simp add:dvd_def zmod_eq_0_iff)
  6.1066 -
  6.1067 -lemmas zdvd_iff_zmod_eq_0_number_of [simp] =
  6.1068 -  zdvd_iff_zmod_eq_0 [of "number_of x" "number_of y", standard]
  6.1069 -
  6.1070 -lemma zdvd_0_right [iff]: "(m::int) dvd 0"
  6.1071 -by (simp add: dvd_def)
  6.1072 -
  6.1073 -lemma zdvd_0_left [iff]: "(0 dvd (m::int)) = (m = 0)"
  6.1074 -  by (simp add: dvd_def)
  6.1075 -
  6.1076 -lemma zdvd_1_left [iff]: "1 dvd (m::int)"
  6.1077 -  by (simp add: dvd_def)
  6.1078 -
  6.1079 -lemma zdvd_refl [simp]: "m dvd (m::int)"
  6.1080 -by (auto simp add: dvd_def intro: zmult_1_right [symmetric])
  6.1081 -
  6.1082 -lemma zdvd_trans: "m dvd n ==> n dvd k ==> m dvd (k::int)"
  6.1083 -by (auto simp add: dvd_def intro: mult_assoc)
  6.1084 -
  6.1085 -lemma zdvd_zminus_iff: "(m dvd -n) = (m dvd (n::int))"
  6.1086 -  apply (simp add: dvd_def, auto)
  6.1087 -   apply (rule_tac [!] x = "-k" in exI, auto)
  6.1088 -  done
  6.1089 -
  6.1090 -lemma zdvd_zminus2_iff: "(-m dvd n) = (m dvd (n::int))"
  6.1091 -  apply (simp add: dvd_def, auto)
  6.1092 -   apply (rule_tac [!] x = "-k" in exI, auto)
  6.1093 -  done
  6.1094 -lemma zdvd_abs1: "( \<bar>i::int\<bar> dvd j) = (i dvd j)" 
  6.1095 -  apply (cases "i > 0", simp)
  6.1096 -  apply (simp add: dvd_def)
  6.1097 -  apply (rule iffI)
  6.1098 -  apply (erule exE)
  6.1099 -  apply (rule_tac x="- k" in exI, simp)
  6.1100 -  apply (erule exE)
  6.1101 -  apply (rule_tac x="- k" in exI, simp)
  6.1102 -  done
  6.1103 -lemma zdvd_abs2: "( (i::int) dvd \<bar>j\<bar>) = (i dvd j)" 
  6.1104 -  apply (cases "j > 0", simp)
  6.1105 -  apply (simp add: dvd_def)
  6.1106 -  apply (rule iffI)
  6.1107 -  apply (erule exE)
  6.1108 -  apply (rule_tac x="- k" in exI, simp)
  6.1109 -  apply (erule exE)
  6.1110 -  apply (rule_tac x="- k" in exI, simp)
  6.1111 -  done
  6.1112 -
  6.1113 -lemma zdvd_anti_sym:
  6.1114 -    "0 < m ==> 0 < n ==> m dvd n ==> n dvd m ==> m = (n::int)"
  6.1115 -  apply (simp add: dvd_def, auto)
  6.1116 -  apply (simp add: mult_assoc zero_less_mult_iff zmult_eq_1_iff)
  6.1117 -  done
  6.1118 -
  6.1119 -lemma zdvd_zadd: "k dvd m ==> k dvd n ==> k dvd (m + n :: int)"
  6.1120 -  apply (simp add: dvd_def)
  6.1121 -  apply (blast intro: right_distrib [symmetric])
  6.1122 -  done
  6.1123 -
  6.1124 -lemma zdvd_dvd_eq: assumes anz:"a \<noteq> 0" and ab: "(a::int) dvd b" and ba:"b dvd a" 
  6.1125 -  shows "\<bar>a\<bar> = \<bar>b\<bar>"
  6.1126 -proof-
  6.1127 -  from ab obtain k where k:"b = a*k" unfolding dvd_def by blast 
  6.1128 -  from ba obtain k' where k':"a = b*k'" unfolding dvd_def by blast 
  6.1129 -  from k k' have "a = a*k*k'" by simp
  6.1130 -  with mult_cancel_left1[where c="a" and b="k*k'"]
  6.1131 -  have kk':"k*k' = 1" using anz by (simp add: mult_assoc)
  6.1132 -  hence "k = 1 \<and> k' = 1 \<or> k = -1 \<and> k' = -1" by (simp add: zmult_eq_1_iff)
  6.1133 -  thus ?thesis using k k' by auto
  6.1134 -qed
  6.1135 -
  6.1136 -lemma zdvd_zdiff: "k dvd m ==> k dvd n ==> k dvd (m - n :: int)"
  6.1137 -  apply (simp add: dvd_def)
  6.1138 -  apply (blast intro: right_diff_distrib [symmetric])
  6.1139 -  done
  6.1140 -
  6.1141 -lemma zdvd_zdiffD: "k dvd m - n ==> k dvd n ==> k dvd (m::int)"
  6.1142 -  apply (subgoal_tac "m = n + (m - n)")
  6.1143 -   apply (erule ssubst)
  6.1144 -   apply (blast intro: zdvd_zadd, simp)
  6.1145 -  done
  6.1146 -
  6.1147 -lemma zdvd_zmult: "k dvd (n::int) ==> k dvd m * n"
  6.1148 -  apply (simp add: dvd_def)
  6.1149 -  apply (blast intro: mult_left_commute)
  6.1150 -  done
  6.1151 -
  6.1152 -lemma zdvd_zmult2: "k dvd (m::int) ==> k dvd m * n"
  6.1153 -  apply (subst mult_commute)
  6.1154 -  apply (erule zdvd_zmult)
  6.1155 -  done
  6.1156 -
  6.1157 -lemma zdvd_triv_right [iff]: "(k::int) dvd m * k"
  6.1158 -  apply (rule zdvd_zmult)
  6.1159 -  apply (rule zdvd_refl)
  6.1160 -  done
  6.1161 -
  6.1162 -lemma zdvd_triv_left [iff]: "(k::int) dvd k * m"
  6.1163 -  apply (rule zdvd_zmult2)
  6.1164 -  apply (rule zdvd_refl)
  6.1165 -  done
  6.1166 -
  6.1167 -lemma zdvd_zmultD2: "j * k dvd n ==> j dvd (n::int)"
  6.1168 -  apply (simp add: dvd_def)
  6.1169 -  apply (simp add: mult_assoc, blast)
  6.1170 -  done
  6.1171 -
  6.1172 -lemma zdvd_zmultD: "j * k dvd n ==> k dvd (n::int)"
  6.1173 -  apply (rule zdvd_zmultD2)
  6.1174 -  apply (subst mult_commute, assumption)
  6.1175 -  done
  6.1176 -
  6.1177 -lemma zdvd_zmult_mono: "i dvd m ==> j dvd (n::int) ==> i * j dvd m * n"
  6.1178 -  apply (simp add: dvd_def, clarify)
  6.1179 -  apply (rule_tac x = "k * ka" in exI)
  6.1180 -  apply (simp add: mult_ac)
  6.1181 -  done
  6.1182 -
  6.1183 -lemma zdvd_reduce: "(k dvd n + k * m) = (k dvd (n::int))"
  6.1184 -  apply (rule iffI)
  6.1185 -   apply (erule_tac [2] zdvd_zadd)
  6.1186 -   apply (subgoal_tac "n = (n + k * m) - k * m")
  6.1187 -    apply (erule ssubst)
  6.1188 -    apply (erule zdvd_zdiff, simp_all)
  6.1189 -  done
  6.1190 -
  6.1191 -lemma zdvd_zmod: "f dvd m ==> f dvd (n::int) ==> f dvd m mod n"
  6.1192 -  apply (simp add: dvd_def)
  6.1193 -  apply (auto simp add: zmod_zmult_zmult1)
  6.1194 -  done
  6.1195 -
  6.1196 -lemma zdvd_zmod_imp_zdvd: "k dvd m mod n ==> k dvd n ==> k dvd (m::int)"
  6.1197 -  apply (subgoal_tac "k dvd n * (m div n) + m mod n")
  6.1198 -   apply (simp add: zmod_zdiv_equality [symmetric])
  6.1199 -  apply (simp only: zdvd_zadd zdvd_zmult2)
  6.1200 -  done
  6.1201 -
  6.1202 -lemma zdvd_not_zless: "0 < m ==> m < n ==> \<not> n dvd (m::int)"
  6.1203 -  apply (simp add: dvd_def, auto)
  6.1204 -  apply (subgoal_tac "0 < n")
  6.1205 -   prefer 2
  6.1206 -   apply (blast intro: order_less_trans)
  6.1207 -  apply (simp add: zero_less_mult_iff)
  6.1208 -  apply (subgoal_tac "n * k < n * 1")
  6.1209 -   apply (drule mult_less_cancel_left [THEN iffD1], auto)
  6.1210 -  done
  6.1211 -lemma zmult_div_cancel: "(n::int) * (m div n) = m - (m mod n)"
  6.1212 -  using zmod_zdiv_equality[where a="m" and b="n"]
  6.1213 -  by (simp add: ring_eq_simps)
  6.1214 -
  6.1215 -lemma zdvd_mult_div_cancel:"(n::int) dvd m \<Longrightarrow> n * (m div n) = m"
  6.1216 -apply (subgoal_tac "m mod n = 0")
  6.1217 - apply (simp add: zmult_div_cancel)
  6.1218 -apply (simp only: zdvd_iff_zmod_eq_0)
  6.1219 -done
  6.1220 -
  6.1221 -lemma zdvd_mult_cancel: assumes d:"k * m dvd k * n" and kz:"k \<noteq> (0::int)"
  6.1222 -  shows "m dvd n"
  6.1223 -proof-
  6.1224 -  from d obtain h where h: "k*n = k*m * h" unfolding dvd_def by blast
  6.1225 -  {assume "n \<noteq> m*h" hence "k* n \<noteq> k* (m*h)" using kz by simp
  6.1226 -    with h have False by (simp add: mult_assoc)}
  6.1227 -  hence "n = m * h" by blast
  6.1228 -  thus ?thesis by blast
  6.1229 -qed
  6.1230 -
  6.1231 -theorem ex_nat: "(\<exists>x::nat. P x) = (\<exists>x::int. 0 <= x \<and> P (nat x))"
  6.1232 -  apply (simp split add: split_nat)
  6.1233 -  apply (rule iffI)
  6.1234 -  apply (erule exE)
  6.1235 -  apply (rule_tac x = "int x" in exI)
  6.1236 -  apply simp
  6.1237 -  apply (erule exE)
  6.1238 -  apply (rule_tac x = "nat x" in exI)
  6.1239 -  apply (erule conjE)
  6.1240 -  apply (erule_tac x = "nat x" in allE)
  6.1241 -  apply simp
  6.1242 -  done
  6.1243 -
  6.1244 -theorem zdvd_int: "(x dvd y) = (int x dvd int y)"
  6.1245 -  apply (simp only: dvd_def ex_nat int_int_eq [symmetric] zmult_int [symmetric]
  6.1246 -    nat_0_le cong add: conj_cong)
  6.1247 -  apply (rule iffI)
  6.1248 -  apply iprover
  6.1249 -  apply (erule exE)
  6.1250 -  apply (case_tac "x=0")
  6.1251 -  apply (rule_tac x=0 in exI)
  6.1252 -  apply simp
  6.1253 -  apply (case_tac "0 \<le> k")
  6.1254 -  apply iprover
  6.1255 -  apply (simp add: linorder_not_le)
  6.1256 -  apply (drule mult_strict_left_mono_neg [OF iffD2 [OF zero_less_int_conv]])
  6.1257 -  apply assumption
  6.1258 -  apply (simp add: mult_ac)
  6.1259 -  done
  6.1260 -
  6.1261 -lemma zdvd1_eq[simp]: "(x::int) dvd 1 = ( \<bar>x\<bar> = 1)"
  6.1262 -proof
  6.1263 -  assume d: "x dvd 1" hence "int (nat \<bar>x\<bar>) dvd int (nat 1)" by (simp add: zdvd_abs1)
  6.1264 -  hence "nat \<bar>x\<bar> dvd 1" by (simp add: zdvd_int)
  6.1265 -  hence "nat \<bar>x\<bar> = 1"  by simp
  6.1266 -  thus "\<bar>x\<bar> = 1" by (cases "x < 0", auto)
  6.1267 -next
  6.1268 -  assume "\<bar>x\<bar>=1" thus "x dvd 1" 
  6.1269 -    by(cases "x < 0",simp_all add: minus_equation_iff zdvd_iff_zmod_eq_0)
  6.1270 -qed
  6.1271 -lemma zdvd_mult_cancel1: 
  6.1272 -  assumes mp:"m \<noteq>(0::int)" shows "(m * n dvd m) = (\<bar>n\<bar> = 1)"
  6.1273 -proof
  6.1274 -  assume n1: "\<bar>n\<bar> = 1" thus "m * n dvd m" 
  6.1275 -    by (cases "n >0", auto simp add: zdvd_zminus2_iff minus_equation_iff)
  6.1276 -next
  6.1277 -  assume H: "m * n dvd m" hence H2: "m * n dvd m * 1" by simp
  6.1278 -  from zdvd_mult_cancel[OF H2 mp] show "\<bar>n\<bar> = 1" by (simp only: zdvd1_eq)
  6.1279 -qed
  6.1280 -
  6.1281 -lemma int_dvd_iff: "(int m dvd z) = (m dvd nat (abs z))"
  6.1282 -  apply (auto simp add: dvd_def nat_abs_mult_distrib)
  6.1283 -  apply (auto simp add: nat_eq_iff abs_if split add: split_if_asm)
  6.1284 -   apply (rule_tac x = "-(int k)" in exI)
  6.1285 -  apply (auto simp add: int_mult)
  6.1286 -  done
  6.1287 -
  6.1288 -lemma dvd_int_iff: "(z dvd int m) = (nat (abs z) dvd m)"
  6.1289 -  apply (auto simp add: dvd_def abs_if int_mult)
  6.1290 -    apply (rule_tac [3] x = "nat k" in exI)
  6.1291 -    apply (rule_tac [2] x = "-(int k)" in exI)
  6.1292 -    apply (rule_tac x = "nat (-k)" in exI)
  6.1293 -    apply (cut_tac [3] k = m in int_less_0_conv)
  6.1294 -    apply (cut_tac k = m in int_less_0_conv)
  6.1295 -    apply (auto simp add: zero_le_mult_iff mult_less_0_iff
  6.1296 -      nat_mult_distrib [symmetric] nat_eq_iff2)
  6.1297 -  done
  6.1298 -
  6.1299 -lemma nat_dvd_iff: "(nat z dvd m) = (if 0 \<le> z then (z dvd int m) else m = 0)"
  6.1300 -  apply (auto simp add: dvd_def int_mult)
  6.1301 -  apply (rule_tac x = "nat k" in exI)
  6.1302 -  apply (cut_tac k = m in int_less_0_conv)
  6.1303 -  apply (auto simp add: zero_le_mult_iff mult_less_0_iff
  6.1304 -    nat_mult_distrib [symmetric] nat_eq_iff2)
  6.1305 -  done
  6.1306 -
  6.1307 -lemma zminus_dvd_iff [iff]: "(-z dvd w) = (z dvd (w::int))"
  6.1308 -  apply (auto simp add: dvd_def)
  6.1309 -   apply (rule_tac [!] x = "-k" in exI, auto)
  6.1310 -  done
  6.1311 -
  6.1312 -lemma dvd_zminus_iff [iff]: "(z dvd -w) = (z dvd (w::int))"
  6.1313 -  apply (auto simp add: dvd_def)
  6.1314 -   apply (drule minus_equation_iff [THEN iffD1])
  6.1315 -   apply (rule_tac [!] x = "-k" in exI, auto)
  6.1316 -  done
  6.1317 -
  6.1318 -lemma zdvd_imp_le: "[| z dvd n; 0 < n |] ==> z \<le> (n::int)"
  6.1319 -  apply (rule_tac z=n in int_cases)
  6.1320 -  apply (auto simp add: dvd_int_iff) 
  6.1321 -  apply (rule_tac z=z in int_cases) 
  6.1322 -  apply (auto simp add: dvd_imp_le) 
  6.1323 -  done
  6.1324 -
  6.1325 -
  6.1326 -subsection{*Integer Powers*} 
  6.1327 -
  6.1328 -instance int :: power ..
  6.1329 -
  6.1330 -primrec
  6.1331 -  "p ^ 0 = 1"
  6.1332 -  "p ^ (Suc n) = (p::int) * (p ^ n)"
  6.1333 -
  6.1334 -
  6.1335 -instance int :: recpower
  6.1336 -proof
  6.1337 -  fix z :: int
  6.1338 -  fix n :: nat
  6.1339 -  show "z^0 = 1" by simp
  6.1340 -  show "z^(Suc n) = z * (z^n)" by simp
  6.1341 -qed
  6.1342 -
  6.1343 -
  6.1344 -lemma zpower_zmod: "((x::int) mod m)^y mod m = x^y mod m"
  6.1345 -apply (induct "y", auto)
  6.1346 -apply (rule zmod_zmult1_eq [THEN trans])
  6.1347 -apply (simp (no_asm_simp))
  6.1348 -apply (rule zmod_zmult_distrib [symmetric])
  6.1349 -done
  6.1350 -
  6.1351 -lemma zpower_zadd_distrib: "x^(y+z) = ((x^y)*(x^z)::int)"
  6.1352 -  by (rule Power.power_add)
  6.1353 -
  6.1354 -lemma zpower_zpower: "(x^y)^z = (x^(y*z)::int)"
  6.1355 -  by (rule Power.power_mult [symmetric])
  6.1356 -
  6.1357 -lemma zero_less_zpower_abs_iff [simp]:
  6.1358 -     "(0 < (abs x)^n) = (x \<noteq> (0::int) | n=0)"
  6.1359 -apply (induct "n")
  6.1360 -apply (auto simp add: zero_less_mult_iff)
  6.1361 -done
  6.1362 -
  6.1363 -lemma zero_le_zpower_abs [simp]: "(0::int) <= (abs x)^n"
  6.1364 -apply (induct "n")
  6.1365 -apply (auto simp add: zero_le_mult_iff)
  6.1366 -done
  6.1367 -
  6.1368 -lemma int_power: "int (m^n) = (int m) ^ n"
  6.1369 -  by (induct n, simp_all add: int_mult)
  6.1370 -
  6.1371 -text{*Compatibility binding*}
  6.1372 -lemmas zpower_int = int_power [symmetric]
  6.1373 -
  6.1374 -lemma zdiv_int: "int (a div b) = (int a) div (int b)"
  6.1375 -apply (subst split_div, auto)
  6.1376 -apply (subst split_zdiv, auto)
  6.1377 -apply (rule_tac a="int (b * i) + int j" and b="int b" and r="int j" and r'=ja in IntDiv.unique_quotient)
  6.1378 -apply (auto simp add: IntDiv.quorem_def int_eq_of_nat)
  6.1379 -done
  6.1380 -
  6.1381 -lemma zmod_int: "int (a mod b) = (int a) mod (int b)"
  6.1382 -apply (subst split_mod, auto)
  6.1383 -apply (subst split_zmod, auto)
  6.1384 -apply (rule_tac a="int (b * i) + int j" and b="int b" and q="int i" and q'=ia 
  6.1385 -       in unique_remainder)
  6.1386 -apply (auto simp add: IntDiv.quorem_def int_eq_of_nat)
  6.1387 -done
  6.1388 -
  6.1389 -text{*Suggested by Matthias Daum*}
  6.1390 -lemma int_power_div_base:
  6.1391 -     "\<lbrakk>0 < m; 0 < k\<rbrakk> \<Longrightarrow> k ^ m div k = (k::int) ^ (m - Suc 0)"
  6.1392 -apply (subgoal_tac "k ^ m = k ^ ((m - 1) + 1)")
  6.1393 - apply (erule ssubst)
  6.1394 - apply (simp only: power_add)
  6.1395 - apply simp_all
  6.1396 -done
  6.1397 -
  6.1398 -text {* code serializer setup *}
  6.1399 -
  6.1400 -code_modulename SML
  6.1401 -  IntDiv Integer
  6.1402 -
  6.1403 -code_modulename OCaml
  6.1404 -  IntDiv Integer
  6.1405 -
  6.1406 -code_modulename Haskell
  6.1407 -  IntDiv Divides
  6.1408 -
  6.1409 -end
     7.1 --- a/src/HOL/Integ/NatBin.thy	Thu May 31 18:16:51 2007 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,903 +0,0 @@
     7.4 -(*  Title:      HOL/NatBin.thy
     7.5 -    ID:         $Id$
     7.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     7.7 -    Copyright   1999  University of Cambridge
     7.8 -*)
     7.9 -
    7.10 -header {* Binary arithmetic for the natural numbers *}
    7.11 -
    7.12 -theory NatBin
    7.13 -imports IntDiv
    7.14 -begin
    7.15 -
    7.16 -text {*
    7.17 -  Arithmetic for naturals is reduced to that for the non-negative integers.
    7.18 -*}
    7.19 -
    7.20 -instance nat :: number
    7.21 -  nat_number_of_def [code inline]: "number_of v == nat (number_of (v\<Colon>int))" ..
    7.22 -
    7.23 -abbreviation (xsymbols)
    7.24 -  square :: "'a::power => 'a"  ("(_\<twosuperior>)" [1000] 999) where
    7.25 -  "x\<twosuperior> == x^2"
    7.26 -
    7.27 -notation (latex output)
    7.28 -  square  ("(_\<twosuperior>)" [1000] 999)
    7.29 -
    7.30 -notation (HTML output)
    7.31 -  square  ("(_\<twosuperior>)" [1000] 999)
    7.32 -
    7.33 -
    7.34 -subsection{*Function @{term nat}: Coercion from Type @{typ int} to @{typ nat}*}
    7.35 -
    7.36 -declare nat_0 [simp] nat_1 [simp]
    7.37 -
    7.38 -lemma nat_number_of [simp]: "nat (number_of w) = number_of w"
    7.39 -by (simp add: nat_number_of_def)
    7.40 -
    7.41 -lemma nat_numeral_0_eq_0 [simp]: "Numeral0 = (0::nat)"
    7.42 -by (simp add: nat_number_of_def)
    7.43 -
    7.44 -lemma nat_numeral_1_eq_1 [simp]: "Numeral1 = (1::nat)"
    7.45 -by (simp add: nat_1 nat_number_of_def)
    7.46 -
    7.47 -lemma numeral_1_eq_Suc_0: "Numeral1 = Suc 0"
    7.48 -by (simp add: nat_numeral_1_eq_1)
    7.49 -
    7.50 -lemma numeral_2_eq_2: "2 = Suc (Suc 0)"
    7.51 -apply (unfold nat_number_of_def)
    7.52 -apply (rule nat_2)
    7.53 -done
    7.54 -
    7.55 -
    7.56 -text{*Distributive laws for type @{text nat}.  The others are in theory
    7.57 -   @{text IntArith}, but these require div and mod to be defined for type
    7.58 -   "int".  They also need some of the lemmas proved above.*}
    7.59 -
    7.60 -lemma nat_div_distrib: "(0::int) <= z ==> nat (z div z') = nat z div nat z'"
    7.61 -apply (case_tac "0 <= z'")
    7.62 -apply (auto simp add: div_nonneg_neg_le0 DIVISION_BY_ZERO_DIV)
    7.63 -apply (case_tac "z' = 0", simp add: DIVISION_BY_ZERO)
    7.64 -apply (auto elim!: nonneg_eq_int)
    7.65 -apply (rename_tac m m')
    7.66 -apply (subgoal_tac "0 <= int m div int m'")
    7.67 - prefer 2 apply (simp add: nat_numeral_0_eq_0 pos_imp_zdiv_nonneg_iff) 
    7.68 -apply (rule inj_int [THEN injD], simp)
    7.69 -apply (rule_tac r = "int (m mod m') " in quorem_div)
    7.70 - prefer 2 apply force
    7.71 -apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0 zadd_int 
    7.72 -                 zmult_int)
    7.73 -done
    7.74 -
    7.75 -(*Fails if z'<0: the LHS collapses to (nat z) but the RHS doesn't*)
    7.76 -lemma nat_mod_distrib:
    7.77 -     "[| (0::int) <= z;  0 <= z' |] ==> nat (z mod z') = nat z mod nat z'"
    7.78 -apply (case_tac "z' = 0", simp add: DIVISION_BY_ZERO)
    7.79 -apply (auto elim!: nonneg_eq_int)
    7.80 -apply (rename_tac m m')
    7.81 -apply (subgoal_tac "0 <= int m mod int m'")
    7.82 - prefer 2 apply (simp add: nat_less_iff nat_numeral_0_eq_0 pos_mod_sign) 
    7.83 -apply (rule inj_int [THEN injD], simp)
    7.84 -apply (rule_tac q = "int (m div m') " in quorem_mod)
    7.85 - prefer 2 apply force
    7.86 -apply (simp add: nat_less_iff [symmetric] quorem_def nat_numeral_0_eq_0 zadd_int zmult_int)
    7.87 -done
    7.88 -
    7.89 -text{*Suggested by Matthias Daum*}
    7.90 -lemma int_div_less_self: "\<lbrakk>0 < x; 1 < k\<rbrakk> \<Longrightarrow> x div k < (x::int)"
    7.91 -apply (subgoal_tac "nat x div nat k < nat x")
    7.92 - apply (simp (asm_lr) add: nat_div_distrib [symmetric])
    7.93 -apply (rule Divides.div_less_dividend, simp_all) 
    7.94 -done
    7.95 -
    7.96 -subsection{*Function @{term int}: Coercion from Type @{typ nat} to @{typ int}*}
    7.97 -
    7.98 -(*"neg" is used in rewrite rules for binary comparisons*)
    7.99 -lemma int_nat_number_of [simp]:
   7.100 -     "int (number_of v :: nat) =  
   7.101 -         (if neg (number_of v :: int) then 0  
   7.102 -          else (number_of v :: int))"
   7.103 -by (simp del: nat_number_of
   7.104 -	 add: neg_nat nat_number_of_def not_neg_nat add_assoc)
   7.105 -
   7.106 -
   7.107 -subsubsection{*Successor *}
   7.108 -
   7.109 -lemma Suc_nat_eq_nat_zadd1: "(0::int) <= z ==> Suc (nat z) = nat (1 + z)"
   7.110 -apply (rule sym)
   7.111 -apply (simp add: nat_eq_iff int_Suc)
   7.112 -done
   7.113 -
   7.114 -lemma Suc_nat_number_of_add:
   7.115 -     "Suc (number_of v + n) =  
   7.116 -        (if neg (number_of v :: int) then 1+n else number_of (Numeral.succ v) + n)" 
   7.117 -by (simp del: nat_number_of 
   7.118 -         add: nat_number_of_def neg_nat
   7.119 -              Suc_nat_eq_nat_zadd1 number_of_succ) 
   7.120 -
   7.121 -lemma Suc_nat_number_of [simp]:
   7.122 -     "Suc (number_of v) =  
   7.123 -        (if neg (number_of v :: int) then 1 else number_of (Numeral.succ v))"
   7.124 -apply (cut_tac n = 0 in Suc_nat_number_of_add)
   7.125 -apply (simp cong del: if_weak_cong)
   7.126 -done
   7.127 -
   7.128 -
   7.129 -subsubsection{*Addition *}
   7.130 -
   7.131 -(*"neg" is used in rewrite rules for binary comparisons*)
   7.132 -lemma add_nat_number_of [simp]:
   7.133 -     "(number_of v :: nat) + number_of v' =  
   7.134 -         (if neg (number_of v :: int) then number_of v'  
   7.135 -          else if neg (number_of v' :: int) then number_of v  
   7.136 -          else number_of (v + v'))"
   7.137 -by (force dest!: neg_nat
   7.138 -          simp del: nat_number_of
   7.139 -          simp add: nat_number_of_def nat_add_distrib [symmetric]) 
   7.140 -
   7.141 -
   7.142 -subsubsection{*Subtraction *}
   7.143 -
   7.144 -lemma diff_nat_eq_if:
   7.145 -     "nat z - nat z' =  
   7.146 -        (if neg z' then nat z   
   7.147 -         else let d = z-z' in     
   7.148 -              if neg d then 0 else nat d)"
   7.149 -apply (simp add: Let_def nat_diff_distrib [symmetric] neg_eq_less_0 not_neg_eq_ge_0)
   7.150 -done
   7.151 -
   7.152 -lemma diff_nat_number_of [simp]: 
   7.153 -     "(number_of v :: nat) - number_of v' =  
   7.154 -        (if neg (number_of v' :: int) then number_of v  
   7.155 -         else let d = number_of (v + uminus v') in     
   7.156 -              if neg d then 0 else nat d)"
   7.157 -by (simp del: nat_number_of add: diff_nat_eq_if nat_number_of_def) 
   7.158 -
   7.159 -
   7.160 -
   7.161 -subsubsection{*Multiplication *}
   7.162 -
   7.163 -lemma mult_nat_number_of [simp]:
   7.164 -     "(number_of v :: nat) * number_of v' =  
   7.165 -       (if neg (number_of v :: int) then 0 else number_of (v * v'))"
   7.166 -by (force dest!: neg_nat
   7.167 -          simp del: nat_number_of
   7.168 -          simp add: nat_number_of_def nat_mult_distrib [symmetric]) 
   7.169 -
   7.170 -
   7.171 -
   7.172 -subsubsection{*Quotient *}
   7.173 -
   7.174 -lemma div_nat_number_of [simp]:
   7.175 -     "(number_of v :: nat)  div  number_of v' =  
   7.176 -          (if neg (number_of v :: int) then 0  
   7.177 -           else nat (number_of v div number_of v'))"
   7.178 -by (force dest!: neg_nat
   7.179 -          simp del: nat_number_of
   7.180 -          simp add: nat_number_of_def nat_div_distrib [symmetric]) 
   7.181 -
   7.182 -lemma one_div_nat_number_of [simp]:
   7.183 -     "(Suc 0)  div  number_of v' = (nat (1 div number_of v'))" 
   7.184 -by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric]) 
   7.185 -
   7.186 -
   7.187 -subsubsection{*Remainder *}
   7.188 -
   7.189 -lemma mod_nat_number_of [simp]:
   7.190 -     "(number_of v :: nat)  mod  number_of v' =  
   7.191 -        (if neg (number_of v :: int) then 0  
   7.192 -         else if neg (number_of v' :: int) then number_of v  
   7.193 -         else nat (number_of v mod number_of v'))"
   7.194 -by (force dest!: neg_nat
   7.195 -          simp del: nat_number_of
   7.196 -          simp add: nat_number_of_def nat_mod_distrib [symmetric]) 
   7.197 -
   7.198 -lemma one_mod_nat_number_of [simp]:
   7.199 -     "(Suc 0)  mod  number_of v' =  
   7.200 -        (if neg (number_of v' :: int) then Suc 0
   7.201 -         else nat (1 mod number_of v'))"
   7.202 -by (simp del: nat_numeral_1_eq_1 add: numeral_1_eq_Suc_0 [symmetric]) 
   7.203 -
   7.204 -
   7.205 -subsubsection{* Divisibility *}
   7.206 -
   7.207 -lemmas dvd_eq_mod_eq_0_number_of =
   7.208 -  dvd_eq_mod_eq_0 [of "number_of x" "number_of y", standard]
   7.209 -
   7.210 -declare dvd_eq_mod_eq_0_number_of [simp]
   7.211 -
   7.212 -ML
   7.213 -{*
   7.214 -val nat_number_of_def = thm"nat_number_of_def";
   7.215 -
   7.216 -val nat_number_of = thm"nat_number_of";
   7.217 -val nat_numeral_0_eq_0 = thm"nat_numeral_0_eq_0";
   7.218 -val nat_numeral_1_eq_1 = thm"nat_numeral_1_eq_1";
   7.219 -val numeral_1_eq_Suc_0 = thm"numeral_1_eq_Suc_0";
   7.220 -val numeral_2_eq_2 = thm"numeral_2_eq_2";
   7.221 -val nat_div_distrib = thm"nat_div_distrib";
   7.222 -val nat_mod_distrib = thm"nat_mod_distrib";
   7.223 -val int_nat_number_of = thm"int_nat_number_of";
   7.224 -val Suc_nat_eq_nat_zadd1 = thm"Suc_nat_eq_nat_zadd1";
   7.225 -val Suc_nat_number_of_add = thm"Suc_nat_number_of_add";
   7.226 -val Suc_nat_number_of = thm"Suc_nat_number_of";
   7.227 -val add_nat_number_of = thm"add_nat_number_of";
   7.228 -val diff_nat_eq_if = thm"diff_nat_eq_if";
   7.229 -val diff_nat_number_of = thm"diff_nat_number_of";
   7.230 -val mult_nat_number_of = thm"mult_nat_number_of";
   7.231 -val div_nat_number_of = thm"div_nat_number_of";
   7.232 -val mod_nat_number_of = thm"mod_nat_number_of";
   7.233 -*}
   7.234 -
   7.235 -
   7.236 -subsection{*Comparisons*}
   7.237 -
   7.238 -subsubsection{*Equals (=) *}
   7.239 -
   7.240 -lemma eq_nat_nat_iff:
   7.241 -     "[| (0::int) <= z;  0 <= z' |] ==> (nat z = nat z') = (z=z')"
   7.242 -by (auto elim!: nonneg_eq_int)
   7.243 -
   7.244 -(*"neg" is used in rewrite rules for binary comparisons*)
   7.245 -lemma eq_nat_number_of [simp]:
   7.246 -     "((number_of v :: nat) = number_of v') =  
   7.247 -      (if neg (number_of v :: int) then (iszero (number_of v' :: int) | neg (number_of v' :: int))  
   7.248 -       else if neg (number_of v' :: int) then iszero (number_of v :: int)  
   7.249 -       else iszero (number_of (v + uminus v') :: int))"
   7.250 -apply (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def
   7.251 -                  eq_nat_nat_iff eq_number_of_eq nat_0 iszero_def
   7.252 -            split add: split_if cong add: imp_cong)
   7.253 -apply (simp only: nat_eq_iff nat_eq_iff2)
   7.254 -apply (simp add: not_neg_eq_ge_0 [symmetric])
   7.255 -done
   7.256 -
   7.257 -
   7.258 -subsubsection{*Less-than (<) *}
   7.259 -
   7.260 -(*"neg" is used in rewrite rules for binary comparisons*)
   7.261 -lemma less_nat_number_of [simp]:
   7.262 -     "((number_of v :: nat) < number_of v') =  
   7.263 -         (if neg (number_of v :: int) then neg (number_of (uminus v') :: int)  
   7.264 -          else neg (number_of (v + uminus v') :: int))"
   7.265 -by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def
   7.266 -                nat_less_eq_zless less_number_of_eq_neg zless_nat_eq_int_zless
   7.267 -         cong add: imp_cong, simp add: Pls_def)
   7.268 -
   7.269 -
   7.270 -(*Maps #n to n for n = 0, 1, 2*)
   7.271 -lemmas numerals = nat_numeral_0_eq_0 nat_numeral_1_eq_1 numeral_2_eq_2
   7.272 -
   7.273 -
   7.274 -subsection{*Powers with Numeric Exponents*}
   7.275 -
   7.276 -text{*We cannot refer to the number @{term 2} in @{text Ring_and_Field.thy}.
   7.277 -We cannot prove general results about the numeral @{term "-1"}, so we have to
   7.278 -use @{term "- 1"} instead.*}
   7.279 -
   7.280 -lemma power2_eq_square: "(a::'a::{comm_semiring_1_cancel,recpower})\<twosuperior> = a * a"
   7.281 -  by (simp add: numeral_2_eq_2 Power.power_Suc)
   7.282 -
   7.283 -lemma zero_power2 [simp]: "(0::'a::{comm_semiring_1_cancel,recpower})\<twosuperior> = 0"
   7.284 -  by (simp add: power2_eq_square)
   7.285 -
   7.286 -lemma one_power2 [simp]: "(1::'a::{comm_semiring_1_cancel,recpower})\<twosuperior> = 1"
   7.287 -  by (simp add: power2_eq_square)
   7.288 -
   7.289 -lemma power3_eq_cube: "(x::'a::recpower) ^ 3 = x * x * x"
   7.290 -  apply (subgoal_tac "3 = Suc (Suc (Suc 0))")
   7.291 -  apply (erule ssubst)
   7.292 -  apply (simp add: power_Suc mult_ac)
   7.293 -  apply (unfold nat_number_of_def)
   7.294 -  apply (subst nat_eq_iff)
   7.295 -  apply simp
   7.296 -done
   7.297 -
   7.298 -text{*Squares of literal numerals will be evaluated.*}
   7.299 -lemmas power2_eq_square_number_of =
   7.300 -    power2_eq_square [of "number_of w", standard]
   7.301 -declare power2_eq_square_number_of [simp]
   7.302 -
   7.303 -
   7.304 -lemma zero_le_power2[simp]: "0 \<le> (a\<twosuperior>::'a::{ordered_idom,recpower})"
   7.305 -  by (simp add: power2_eq_square)
   7.306 -
   7.307 -lemma zero_less_power2[simp]:
   7.308 -     "(0 < a\<twosuperior>) = (a \<noteq> (0::'a::{ordered_idom,recpower}))"
   7.309 -  by (force simp add: power2_eq_square zero_less_mult_iff linorder_neq_iff)
   7.310 -
   7.311 -lemma power2_less_0[simp]:
   7.312 -  fixes a :: "'a::{ordered_idom,recpower}"
   7.313 -  shows "~ (a\<twosuperior> < 0)"
   7.314 -by (force simp add: power2_eq_square mult_less_0_iff) 
   7.315 -
   7.316 -lemma zero_eq_power2[simp]:
   7.317 -     "(a\<twosuperior> = 0) = (a = (0::'a::{ordered_idom,recpower}))"
   7.318 -  by (force simp add: power2_eq_square mult_eq_0_iff)
   7.319 -
   7.320 -lemma abs_power2[simp]:
   7.321 -     "abs(a\<twosuperior>) = (a\<twosuperior>::'a::{ordered_idom,recpower})"
   7.322 -  by (simp add: power2_eq_square abs_mult abs_mult_self)
   7.323 -
   7.324 -lemma power2_abs[simp]:
   7.325 -     "(abs a)\<twosuperior> = (a\<twosuperior>::'a::{ordered_idom,recpower})"
   7.326 -  by (simp add: power2_eq_square abs_mult_self)
   7.327 -
   7.328 -lemma power2_minus[simp]:
   7.329 -     "(- a)\<twosuperior> = (a\<twosuperior>::'a::{comm_ring_1,recpower})"
   7.330 -  by (simp add: power2_eq_square)
   7.331 -
   7.332 -lemma power2_le_imp_le:
   7.333 -  fixes x y :: "'a::{ordered_semidom,recpower}"
   7.334 -  shows "\<lbrakk>x\<twosuperior> \<le> y\<twosuperior>; 0 \<le> y\<rbrakk> \<Longrightarrow> x \<le> y"
   7.335 -unfolding numeral_2_eq_2 by (rule power_le_imp_le_base)
   7.336 -
   7.337 -lemma power2_less_imp_less:
   7.338 -  fixes x y :: "'a::{ordered_semidom,recpower}"
   7.339 -  shows "\<lbrakk>x\<twosuperior> < y\<twosuperior>; 0 \<le> y\<rbrakk> \<Longrightarrow> x < y"
   7.340 -by (rule power_less_imp_less_base)
   7.341 -
   7.342 -lemma power2_eq_imp_eq:
   7.343 -  fixes x y :: "'a::{ordered_semidom,recpower}"
   7.344 -  shows "\<lbrakk>x\<twosuperior> = y\<twosuperior>; 0 \<le> x; 0 \<le> y\<rbrakk> \<Longrightarrow> x = y"
   7.345 -unfolding numeral_2_eq_2 by (erule (2) power_eq_imp_eq_base, simp)
   7.346 -
   7.347 -lemma power_minus1_even[simp]: "(- 1) ^ (2*n) = (1::'a::{comm_ring_1,recpower})"
   7.348 -apply (induct "n")
   7.349 -apply (auto simp add: power_Suc power_add)
   7.350 -done
   7.351 -
   7.352 -lemma power_even_eq: "(a::'a::recpower) ^ (2*n) = (a^n)^2"
   7.353 -by (subst mult_commute) (simp add: power_mult)
   7.354 -
   7.355 -lemma power_odd_eq: "(a::int) ^ Suc(2*n) = a * (a^n)^2"
   7.356 -by (simp add: power_even_eq) 
   7.357 -
   7.358 -lemma power_minus_even [simp]:
   7.359 -     "(-a) ^ (2*n) = (a::'a::{comm_ring_1,recpower}) ^ (2*n)"
   7.360 -by (simp add: power_minus1_even power_minus [of a]) 
   7.361 -
   7.362 -lemma zero_le_even_power'[simp]:
   7.363 -     "0 \<le> (a::'a::{ordered_idom,recpower}) ^ (2*n)"
   7.364 -proof (induct "n")
   7.365 -  case 0
   7.366 -    show ?case by (simp add: zero_le_one)
   7.367 -next
   7.368 -  case (Suc n)
   7.369 -    have "a ^ (2 * Suc n) = (a*a) * a ^ (2*n)" 
   7.370 -      by (simp add: mult_ac power_add power2_eq_square)
   7.371 -    thus ?case
   7.372 -      by (simp add: prems zero_le_mult_iff)
   7.373 -qed
   7.374 -
   7.375 -lemma odd_power_less_zero:
   7.376 -     "(a::'a::{ordered_idom,recpower}) < 0 ==> a ^ Suc(2*n) < 0"
   7.377 -proof (induct "n")
   7.378 -  case 0
   7.379 -    show ?case by (simp add: Power.power_Suc)
   7.380 -next
   7.381 -  case (Suc n)
   7.382 -    have "a ^ Suc (2 * Suc n) = (a*a) * a ^ Suc(2*n)" 
   7.383 -      by (simp add: mult_ac power_add power2_eq_square Power.power_Suc)
   7.384 -    thus ?case
   7.385 -      by (simp add: prems mult_less_0_iff mult_neg_neg)
   7.386 -qed
   7.387 -
   7.388 -lemma odd_0_le_power_imp_0_le:
   7.389 -     "0 \<le> a  ^ Suc(2*n) ==> 0 \<le> (a::'a::{ordered_idom,recpower})"
   7.390 -apply (insert odd_power_less_zero [of a n]) 
   7.391 -apply (force simp add: linorder_not_less [symmetric]) 
   7.392 -done
   7.393 -
   7.394 -text{*Simprules for comparisons where common factors can be cancelled.*}
   7.395 -lemmas zero_compare_simps =
   7.396 -    add_strict_increasing add_strict_increasing2 add_increasing
   7.397 -    zero_le_mult_iff zero_le_divide_iff 
   7.398 -    zero_less_mult_iff zero_less_divide_iff 
   7.399 -    mult_le_0_iff divide_le_0_iff 
   7.400 -    mult_less_0_iff divide_less_0_iff 
   7.401 -    zero_le_power2 power2_less_0
   7.402 -
   7.403 -subsubsection{*Nat *}
   7.404 -
   7.405 -lemma Suc_pred': "0 < n ==> n = Suc(n - 1)"
   7.406 -by (simp add: numerals)
   7.407 -
   7.408 -(*Expresses a natural number constant as the Suc of another one.
   7.409 -  NOT suitable for rewriting because n recurs in the condition.*)
   7.410 -lemmas expand_Suc = Suc_pred' [of "number_of v", standard]
   7.411 -
   7.412 -subsubsection{*Arith *}
   7.413 -
   7.414 -lemma Suc_eq_add_numeral_1: "Suc n = n + 1"
   7.415 -by (simp add: numerals)
   7.416 -
   7.417 -lemma Suc_eq_add_numeral_1_left: "Suc n = 1 + n"
   7.418 -by (simp add: numerals)
   7.419 -
   7.420 -(* These two can be useful when m = number_of... *)
   7.421 -
   7.422 -lemma add_eq_if: "(m::nat) + n = (if m=0 then n else Suc ((m - 1) + n))"
   7.423 -apply (case_tac "m")
   7.424 -apply (simp_all add: numerals)
   7.425 -done
   7.426 -
   7.427 -lemma mult_eq_if: "(m::nat) * n = (if m=0 then 0 else n + ((m - 1) * n))"
   7.428 -apply (case_tac "m")
   7.429 -apply (simp_all add: numerals)
   7.430 -done
   7.431 -
   7.432 -lemma power_eq_if: "(p ^ m :: nat) = (if m=0 then 1 else p * (p ^ (m - 1)))"
   7.433 -apply (case_tac "m")
   7.434 -apply (simp_all add: numerals)
   7.435 -done
   7.436 -
   7.437 -
   7.438 -subsection{*Comparisons involving (0::nat) *}
   7.439 -
   7.440 -text{*Simplification already does @{term "n<0"}, @{term "n\<le>0"} and @{term "0\<le>n"}.*}
   7.441 -
   7.442 -lemma eq_number_of_0 [simp]:
   7.443 -     "(number_of v = (0::nat)) =  
   7.444 -      (if neg (number_of v :: int) then True else iszero (number_of v :: int))"
   7.445 -by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric] iszero_0)
   7.446 -
   7.447 -lemma eq_0_number_of [simp]:
   7.448 -     "((0::nat) = number_of v) =  
   7.449 -      (if neg (number_of v :: int) then True else iszero (number_of v :: int))"
   7.450 -by (rule trans [OF eq_sym_conv eq_number_of_0])
   7.451 -
   7.452 -lemma less_0_number_of [simp]:
   7.453 -     "((0::nat) < number_of v) = neg (number_of (uminus v) :: int)"
   7.454 -by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric] Pls_def)
   7.455 -
   7.456 -
   7.457 -lemma neg_imp_number_of_eq_0: "neg (number_of v :: int) ==> number_of v = (0::nat)"
   7.458 -by (simp del: nat_numeral_0_eq_0 add: nat_numeral_0_eq_0 [symmetric] iszero_0)
   7.459 -
   7.460 -
   7.461 -
   7.462 -subsection{*Comparisons involving  @{term Suc} *}
   7.463 -
   7.464 -lemma eq_number_of_Suc [simp]:
   7.465 -     "(number_of v = Suc n) =  
   7.466 -        (let pv = number_of (Numeral.pred v) in  
   7.467 -         if neg pv then False else nat pv = n)"
   7.468 -apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   7.469 -                  number_of_pred nat_number_of_def 
   7.470 -            split add: split_if)
   7.471 -apply (rule_tac x = "number_of v" in spec)
   7.472 -apply (auto simp add: nat_eq_iff)
   7.473 -done
   7.474 -
   7.475 -lemma Suc_eq_number_of [simp]:
   7.476 -     "(Suc n = number_of v) =  
   7.477 -        (let pv = number_of (Numeral.pred v) in  
   7.478 -         if neg pv then False else nat pv = n)"
   7.479 -by (rule trans [OF eq_sym_conv eq_number_of_Suc])
   7.480 -
   7.481 -lemma less_number_of_Suc [simp]:
   7.482 -     "(number_of v < Suc n) =  
   7.483 -        (let pv = number_of (Numeral.pred v) in  
   7.484 -         if neg pv then True else nat pv < n)"
   7.485 -apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   7.486 -                  number_of_pred nat_number_of_def  
   7.487 -            split add: split_if)
   7.488 -apply (rule_tac x = "number_of v" in spec)
   7.489 -apply (auto simp add: nat_less_iff)
   7.490 -done
   7.491 -
   7.492 -lemma less_Suc_number_of [simp]:
   7.493 -     "(Suc n < number_of v) =  
   7.494 -        (let pv = number_of (Numeral.pred v) in  
   7.495 -         if neg pv then False else n < nat pv)"
   7.496 -apply (simp only: simp_thms Let_def neg_eq_less_0 linorder_not_less 
   7.497 -                  number_of_pred nat_number_of_def
   7.498 -            split add: split_if)
   7.499 -apply (rule_tac x = "number_of v" in spec)
   7.500 -apply (auto simp add: zless_nat_eq_int_zless)
   7.501 -done
   7.502 -
   7.503 -lemma le_number_of_Suc [simp]:
   7.504 -     "(number_of v <= Suc n) =  
   7.505 -        (let pv = number_of (Numeral.pred v) in  
   7.506 -         if neg pv then True else nat pv <= n)"
   7.507 -by (simp add: Let_def less_Suc_number_of linorder_not_less [symmetric])
   7.508 -
   7.509 -lemma le_Suc_number_of [simp]:
   7.510 -     "(Suc n <= number_of v) =  
   7.511 -        (let pv = number_of (Numeral.pred v) in  
   7.512 -         if neg pv then False else n <= nat pv)"
   7.513 -by (simp add: Let_def less_number_of_Suc linorder_not_less [symmetric])
   7.514 -
   7.515 -
   7.516 -(* Push int(.) inwards: *)
   7.517 -declare zadd_int [symmetric, simp]
   7.518 -
   7.519 -lemma lemma1: "(m+m = n+n) = (m = (n::int))"
   7.520 -by auto
   7.521 -
   7.522 -lemma lemma2: "m+m ~= (1::int) + (n + n)"
   7.523 -apply auto
   7.524 -apply (drule_tac f = "%x. x mod 2" in arg_cong)
   7.525 -apply (simp add: zmod_zadd1_eq)
   7.526 -done
   7.527 -
   7.528 -lemma eq_number_of_BIT_BIT:
   7.529 -     "((number_of (v BIT x) ::int) = number_of (w BIT y)) =  
   7.530 -      (x=y & (((number_of v) ::int) = number_of w))"
   7.531 -apply (simp only: number_of_BIT lemma1 lemma2 eq_commute
   7.532 -               OrderedGroup.add_left_cancel add_assoc OrderedGroup.add_0_left
   7.533 -            split add: bit.split)
   7.534 -apply simp
   7.535 -done
   7.536 -
   7.537 -lemma eq_number_of_BIT_Pls:
   7.538 -     "((number_of (v BIT x) ::int) = Numeral0) =  
   7.539 -      (x=bit.B0 & (((number_of v) ::int) = Numeral0))"
   7.540 -apply (simp only: simp_thms  add: number_of_BIT number_of_Pls eq_commute
   7.541 -            split add: bit.split cong: imp_cong)
   7.542 -apply (rule_tac x = "number_of v" in spec, safe)
   7.543 -apply (simp_all (no_asm_use))
   7.544 -apply (drule_tac f = "%x. x mod 2" in arg_cong)
   7.545 -apply (simp add: zmod_zadd1_eq)
   7.546 -done
   7.547 -
   7.548 -lemma eq_number_of_BIT_Min:
   7.549 -     "((number_of (v BIT x) ::int) = number_of Numeral.Min) =  
   7.550 -      (x=bit.B1 & (((number_of v) ::int) = number_of Numeral.Min))"
   7.551 -apply (simp only: simp_thms  add: number_of_BIT number_of_Min eq_commute
   7.552 -            split add: bit.split cong: imp_cong)
   7.553 -apply (rule_tac x = "number_of v" in spec, auto)
   7.554 -apply (drule_tac f = "%x. x mod 2" in arg_cong, auto)
   7.555 -done
   7.556 -
   7.557 -lemma eq_number_of_Pls_Min: "(Numeral0 ::int) ~= number_of Numeral.Min"
   7.558 -by auto
   7.559 -
   7.560 -
   7.561 -
   7.562 -subsection{*Max and Min Combined with @{term Suc} *}
   7.563 -
   7.564 -lemma max_number_of_Suc [simp]:
   7.565 -     "max (Suc n) (number_of v) =  
   7.566 -        (let pv = number_of (Numeral.pred v) in  
   7.567 -         if neg pv then Suc n else Suc(max n (nat pv)))"
   7.568 -apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def 
   7.569 -            split add: split_if nat.split)
   7.570 -apply (rule_tac x = "number_of v" in spec) 
   7.571 -apply auto
   7.572 -done
   7.573 - 
   7.574 -lemma max_Suc_number_of [simp]:
   7.575 -     "max (number_of v) (Suc n) =  
   7.576 -        (let pv = number_of (Numeral.pred v) in  
   7.577 -         if neg pv then Suc n else Suc(max (nat pv) n))"
   7.578 -apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def 
   7.579 -            split add: split_if nat.split)
   7.580 -apply (rule_tac x = "number_of v" in spec) 
   7.581 -apply auto
   7.582 -done
   7.583 - 
   7.584 -lemma min_number_of_Suc [simp]:
   7.585 -     "min (Suc n) (number_of v) =  
   7.586 -        (let pv = number_of (Numeral.pred v) in  
   7.587 -         if neg pv then 0 else Suc(min n (nat pv)))"
   7.588 -apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def 
   7.589 -            split add: split_if nat.split)
   7.590 -apply (rule_tac x = "number_of v" in spec) 
   7.591 -apply auto
   7.592 -done
   7.593 - 
   7.594 -lemma min_Suc_number_of [simp]:
   7.595 -     "min (number_of v) (Suc n) =  
   7.596 -        (let pv = number_of (Numeral.pred v) in  
   7.597 -         if neg pv then 0 else Suc(min (nat pv) n))"
   7.598 -apply (simp only: Let_def neg_eq_less_0 number_of_pred nat_number_of_def 
   7.599 -            split add: split_if nat.split)
   7.600 -apply (rule_tac x = "number_of v" in spec) 
   7.601 -apply auto
   7.602 -done
   7.603 - 
   7.604 -subsection{*Literal arithmetic involving powers*}
   7.605 -
   7.606 -lemma nat_power_eq: "(0::int) <= z ==> nat (z^n) = nat z ^ n"
   7.607 -apply (induct "n")
   7.608 -apply (simp_all (no_asm_simp) add: nat_mult_distrib)
   7.609 -done
   7.610 -
   7.611 -lemma power_nat_number_of:
   7.612 -     "(number_of v :: nat) ^ n =  
   7.613 -       (if neg (number_of v :: int) then 0^n else nat ((number_of v :: int) ^ n))"
   7.614 -by (simp only: simp_thms neg_nat not_neg_eq_ge_0 nat_number_of_def nat_power_eq
   7.615 -         split add: split_if cong: imp_cong)
   7.616 -
   7.617 -
   7.618 -lemmas power_nat_number_of_number_of = power_nat_number_of [of _ "number_of w", standard]
   7.619 -declare power_nat_number_of_number_of [simp]
   7.620 -
   7.621 -
   7.622 -
   7.623 -text{*For the integers*}
   7.624 -
   7.625 -lemma zpower_number_of_even:
   7.626 -  "(z::int) ^ number_of (w BIT bit.B0) = (let w = z ^ (number_of w) in w * w)"
   7.627 -unfolding Let_def nat_number_of_def number_of_BIT bit.cases
   7.628 -apply (rule_tac x = "number_of w" in spec, clarify)
   7.629 -apply (case_tac " (0::int) <= x")
   7.630 -apply (auto simp add: nat_mult_distrib power_even_eq power2_eq_square)
   7.631 -done
   7.632 -
   7.633 -lemma zpower_number_of_odd:
   7.634 -  "(z::int) ^ number_of (w BIT bit.B1) = (if (0::int) <= number_of w                    
   7.635 -     then (let w = z ^ (number_of w) in z * w * w) else 1)"
   7.636 -unfolding Let_def nat_number_of_def number_of_BIT bit.cases
   7.637 -apply (rule_tac x = "number_of w" in spec, auto)
   7.638 -apply (simp only: nat_add_distrib nat_mult_distrib)
   7.639 -apply simp
   7.640 -apply (auto simp add: nat_add_distrib nat_mult_distrib power_even_eq power2_eq_square neg_nat)
   7.641 -done
   7.642 -
   7.643 -lemmas zpower_number_of_even_number_of =
   7.644 -    zpower_number_of_even [of "number_of v", standard]
   7.645 -declare zpower_number_of_even_number_of [simp]
   7.646 -
   7.647 -lemmas zpower_number_of_odd_number_of =
   7.648 -    zpower_number_of_odd [of "number_of v", standard]
   7.649 -declare zpower_number_of_odd_number_of [simp]
   7.650 -
   7.651 -
   7.652 -
   7.653 -
   7.654 -ML
   7.655 -{*
   7.656 -val numerals = thms"numerals";
   7.657 -val numeral_ss = simpset() addsimps numerals;
   7.658 -
   7.659 -val nat_bin_arith_setup =
   7.660 - Fast_Arith.map_data
   7.661 -   (fn {add_mono_thms, mult_mono_thms, inj_thms, lessD, neqE, simpset} =>
   7.662 -     {add_mono_thms = add_mono_thms, mult_mono_thms = mult_mono_thms,
   7.663 -      inj_thms = inj_thms,
   7.664 -      lessD = lessD, neqE = neqE,
   7.665 -      simpset = simpset addsimps [Suc_nat_number_of, int_nat_number_of,
   7.666 -                                  not_neg_number_of_Pls,
   7.667 -                                  neg_number_of_Min,neg_number_of_BIT]})
   7.668 -*}
   7.669 -
   7.670 -setup nat_bin_arith_setup
   7.671 -
   7.672 -(* Enable arith to deal with div/mod k where k is a numeral: *)
   7.673 -declare split_div[of _ _ "number_of k", standard, arith_split]
   7.674 -declare split_mod[of _ _ "number_of k", standard, arith_split]
   7.675 -
   7.676 -lemma nat_number_of_Pls: "Numeral0 = (0::nat)"
   7.677 -  by (simp add: number_of_Pls nat_number_of_def)
   7.678 -
   7.679 -lemma nat_number_of_Min: "number_of Numeral.Min = (0::nat)"
   7.680 -  apply (simp only: number_of_Min nat_number_of_def nat_zminus_int)
   7.681 -  done
   7.682 -
   7.683 -lemma nat_number_of_BIT_1:
   7.684 -  "number_of (w BIT bit.B1) =
   7.685 -    (if neg (number_of w :: int) then 0
   7.686 -     else let n = number_of w in Suc (n + n))"
   7.687 -  apply (simp only: nat_number_of_def Let_def split: split_if)
   7.688 -  apply (intro conjI impI)
   7.689 -   apply (simp add: neg_nat neg_number_of_BIT)
   7.690 -  apply (rule int_int_eq [THEN iffD1])
   7.691 -  apply (simp only: not_neg_nat neg_number_of_BIT int_Suc zadd_int [symmetric] simp_thms)
   7.692 -  apply (simp only: number_of_BIT zadd_assoc split: bit.split)
   7.693 -  apply simp
   7.694 -  done
   7.695 -
   7.696 -lemma nat_number_of_BIT_0:
   7.697 -    "number_of (w BIT bit.B0) = (let n::nat = number_of w in n + n)"
   7.698 -  apply (simp only: nat_number_of_def Let_def)
   7.699 -  apply (cases "neg (number_of w :: int)")
   7.700 -   apply (simp add: neg_nat neg_number_of_BIT)
   7.701 -  apply (rule int_int_eq [THEN iffD1])
   7.702 -  apply (simp only: not_neg_nat neg_number_of_BIT int_Suc zadd_int [symmetric] simp_thms)
   7.703 -  apply (simp only: number_of_BIT zadd_assoc)
   7.704 -  apply simp
   7.705 -  done
   7.706 -
   7.707 -lemmas nat_number =
   7.708 -  nat_number_of_Pls nat_number_of_Min
   7.709 -  nat_number_of_BIT_1 nat_number_of_BIT_0
   7.710 -
   7.711 -lemma Let_Suc [simp]: "Let (Suc n) f == f (Suc n)"
   7.712 -  by (simp add: Let_def)
   7.713 -
   7.714 -lemma power_m1_even: "(-1) ^ (2*n) = (1::'a::{number_ring,recpower})"
   7.715 -by (simp add: power_mult); 
   7.716 -
   7.717 -lemma power_m1_odd: "(-1) ^ Suc(2*n) = (-1::'a::{number_ring,recpower})"
   7.718 -by (simp add: power_mult power_Suc); 
   7.719 -
   7.720 -
   7.721 -subsection{*Literal arithmetic and @{term of_nat}*}
   7.722 -
   7.723 -lemma of_nat_double:
   7.724 -     "0 \<le> x ==> of_nat (nat (2 * x)) = of_nat (nat x) + of_nat (nat x)"
   7.725 -by (simp only: mult_2 nat_add_distrib of_nat_add) 
   7.726 -
   7.727 -lemma nat_numeral_m1_eq_0: "-1 = (0::nat)"
   7.728 -by (simp only: nat_number_of_def)
   7.729 -
   7.730 -lemma of_nat_number_of_lemma:
   7.731 -     "of_nat (number_of v :: nat) =  
   7.732 -         (if 0 \<le> (number_of v :: int) 
   7.733 -          then (number_of v :: 'a :: number_ring)
   7.734 -          else 0)"
   7.735 -by (simp add: int_number_of_def nat_number_of_def number_of_eq of_nat_nat);
   7.736 -
   7.737 -lemma of_nat_number_of_eq [simp]:
   7.738 -     "of_nat (number_of v :: nat) =  
   7.739 -         (if neg (number_of v :: int) then 0  
   7.740 -          else (number_of v :: 'a :: number_ring))"
   7.741 -by (simp only: of_nat_number_of_lemma neg_def, simp) 
   7.742 -
   7.743 -
   7.744 -subsection {*Lemmas for the Combination and Cancellation Simprocs*}
   7.745 -
   7.746 -lemma nat_number_of_add_left:
   7.747 -     "number_of v + (number_of v' + (k::nat)) =  
   7.748 -         (if neg (number_of v :: int) then number_of v' + k  
   7.749 -          else if neg (number_of v' :: int) then number_of v + k  
   7.750 -          else number_of (v + v') + k)"
   7.751 -by simp
   7.752 -
   7.753 -lemma nat_number_of_mult_left:
   7.754 -     "number_of v * (number_of v' * (k::nat)) =  
   7.755 -         (if neg (number_of v :: int) then 0
   7.756 -          else number_of (v * v') * k)"
   7.757 -by simp
   7.758 -
   7.759 -
   7.760 -subsubsection{*For @{text combine_numerals}*}
   7.761 -
   7.762 -lemma left_add_mult_distrib: "i*u + (j*u + k) = (i+j)*u + (k::nat)"
   7.763 -by (simp add: add_mult_distrib)
   7.764 -
   7.765 -
   7.766 -subsubsection{*For @{text cancel_numerals}*}
   7.767 -
   7.768 -lemma nat_diff_add_eq1:
   7.769 -     "j <= (i::nat) ==> ((i*u + m) - (j*u + n)) = (((i-j)*u + m) - n)"
   7.770 -by (simp split add: nat_diff_split add: add_mult_distrib)
   7.771 -
   7.772 -lemma nat_diff_add_eq2:
   7.773 -     "i <= (j::nat) ==> ((i*u + m) - (j*u + n)) = (m - ((j-i)*u + n))"
   7.774 -by (simp split add: nat_diff_split add: add_mult_distrib)
   7.775 -
   7.776 -lemma nat_eq_add_iff1:
   7.777 -     "j <= (i::nat) ==> (i*u + m = j*u + n) = ((i-j)*u + m = n)"
   7.778 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.779 -
   7.780 -lemma nat_eq_add_iff2:
   7.781 -     "i <= (j::nat) ==> (i*u + m = j*u + n) = (m = (j-i)*u + n)"
   7.782 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.783 -
   7.784 -lemma nat_less_add_iff1:
   7.785 -     "j <= (i::nat) ==> (i*u + m < j*u + n) = ((i-j)*u + m < n)"
   7.786 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.787 -
   7.788 -lemma nat_less_add_iff2:
   7.789 -     "i <= (j::nat) ==> (i*u + m < j*u + n) = (m < (j-i)*u + n)"
   7.790 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.791 -
   7.792 -lemma nat_le_add_iff1:
   7.793 -     "j <= (i::nat) ==> (i*u + m <= j*u + n) = ((i-j)*u + m <= n)"
   7.794 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.795 -
   7.796 -lemma nat_le_add_iff2:
   7.797 -     "i <= (j::nat) ==> (i*u + m <= j*u + n) = (m <= (j-i)*u + n)"
   7.798 -by (auto split add: nat_diff_split simp add: add_mult_distrib)
   7.799 -
   7.800 -
   7.801 -subsubsection{*For @{text cancel_numeral_factors} *}
   7.802 -
   7.803 -lemma nat_mult_le_cancel1: "(0::nat) < k ==> (k*m <= k*n) = (m<=n)"
   7.804 -by auto
   7.805 -
   7.806 -lemma nat_mult_less_cancel1: "(0::nat) < k ==> (k*m < k*n) = (m<n)"
   7.807 -by auto
   7.808 -
   7.809 -lemma nat_mult_eq_cancel1: "(0::nat) < k ==> (k*m = k*n) = (m=n)"
   7.810 -by auto
   7.811 -
   7.812 -lemma nat_mult_div_cancel1: "(0::nat) < k ==> (k*m) div (k*n) = (m div n)"
   7.813 -by auto
   7.814 -
   7.815 -
   7.816 -subsubsection{*For @{text cancel_factor} *}
   7.817 -
   7.818 -lemma nat_mult_le_cancel_disj: "(k*m <= k*n) = ((0::nat) < k --> m<=n)"
   7.819 -by auto
   7.820 -
   7.821 -lemma nat_mult_less_cancel_disj: "(k*m < k*n) = ((0::nat) < k & m<n)"
   7.822 -by auto
   7.823 -
   7.824 -lemma nat_mult_eq_cancel_disj: "(k*m = k*n) = (k = (0::nat) | m=n)"
   7.825 -by auto
   7.826 -
   7.827 -lemma nat_mult_div_cancel_disj:
   7.828 -     "(k*m) div (k*n) = (if k = (0::nat) then 0 else m div n)"
   7.829 -by (simp add: nat_mult_div_cancel1)
   7.830 -
   7.831 -
   7.832 -subsection {* legacy ML bindings *}
   7.833 -
   7.834 -ML
   7.835 -{*
   7.836 -val eq_nat_nat_iff = thm"eq_nat_nat_iff";
   7.837 -val eq_nat_number_of = thm"eq_nat_number_of";
   7.838 -val less_nat_number_of = thm"less_nat_number_of";
   7.839 -val power2_eq_square = thm "power2_eq_square";
   7.840 -val zero_le_power2 = thm "zero_le_power2";
   7.841 -val zero_less_power2 = thm "zero_less_power2";
   7.842 -val zero_eq_power2 = thm "zero_eq_power2";
   7.843 -val abs_power2 = thm "abs_power2";
   7.844 -val power2_abs = thm "power2_abs";
   7.845 -val power2_minus = thm "power2_minus";
   7.846 -val power_minus1_even = thm "power_minus1_even";
   7.847 -val power_minus_even = thm "power_minus_even";
   7.848 -val odd_power_less_zero = thm "odd_power_less_zero";
   7.849 -val odd_0_le_power_imp_0_le = thm "odd_0_le_power_imp_0_le";
   7.850 -
   7.851 -val Suc_pred' = thm"Suc_pred'";
   7.852 -val expand_Suc = thm"expand_Suc";
   7.853 -val Suc_eq_add_numeral_1 = thm"Suc_eq_add_numeral_1";
   7.854 -val Suc_eq_add_numeral_1_left = thm"Suc_eq_add_numeral_1_left";
   7.855 -val add_eq_if = thm"add_eq_if";
   7.856 -val mult_eq_if = thm"mult_eq_if";
   7.857 -val power_eq_if = thm"power_eq_if";
   7.858 -val eq_number_of_0 = thm"eq_number_of_0";
   7.859 -val eq_0_number_of = thm"eq_0_number_of";
   7.860 -val less_0_number_of = thm"less_0_number_of";
   7.861 -val neg_imp_number_of_eq_0 = thm"neg_imp_number_of_eq_0";
   7.862 -val eq_number_of_Suc = thm"eq_number_of_Suc";
   7.863 -val Suc_eq_number_of = thm"Suc_eq_number_of";
   7.864 -val less_number_of_Suc = thm"less_number_of_Suc";
   7.865 -val less_Suc_number_of = thm"less_Suc_number_of";
   7.866 -val le_number_of_Suc = thm"le_number_of_Suc";
   7.867 -val le_Suc_number_of = thm"le_Suc_number_of";
   7.868 -val eq_number_of_BIT_BIT = thm"eq_number_of_BIT_BIT";
   7.869 -val eq_number_of_BIT_Pls = thm"eq_number_of_BIT_Pls";
   7.870 -val eq_number_of_BIT_Min = thm"eq_number_of_BIT_Min";
   7.871 -val eq_number_of_Pls_Min = thm"eq_number_of_Pls_Min";
   7.872 -val of_nat_number_of_eq = thm"of_nat_number_of_eq";
   7.873 -val nat_power_eq = thm"nat_power_eq";
   7.874 -val power_nat_number_of = thm"power_nat_number_of";
   7.875 -val zpower_number_of_even = thm"zpower_number_of_even";
   7.876 -val zpower_number_of_odd = thm"zpower_number_of_odd";
   7.877 -val nat_number_of_Pls = thm"nat_number_of_Pls";
   7.878 -val nat_number_of_Min = thm"nat_number_of_Min";
   7.879 -val Let_Suc = thm"Let_Suc";
   7.880 -
   7.881 -val nat_number = thms"nat_number";
   7.882 -
   7.883 -val nat_number_of_add_left = thm"nat_number_of_add_left";
   7.884 -val nat_number_of_mult_left = thm"nat_number_of_mult_left";
   7.885 -val left_add_mult_distrib = thm"left_add_mult_distrib";
   7.886 -val nat_diff_add_eq1 = thm"nat_diff_add_eq1";
   7.887 -val nat_diff_add_eq2 = thm"nat_diff_add_eq2";
   7.888 -val nat_eq_add_iff1 = thm"nat_eq_add_iff1";
   7.889 -val nat_eq_add_iff2 = thm"nat_eq_add_iff2";
   7.890 -val nat_less_add_iff1 = thm"nat_less_add_iff1";
   7.891 -val nat_less_add_iff2 = thm"nat_less_add_iff2";
   7.892 -val nat_le_add_iff1 = thm"nat_le_add_iff1";
   7.893 -val nat_le_add_iff2 = thm"nat_le_add_iff2";
   7.894 -val nat_mult_le_cancel1 = thm"nat_mult_le_cancel1";
   7.895 -val nat_mult_less_cancel1 = thm"nat_mult_less_cancel1";
   7.896 -val nat_mult_eq_cancel1 = thm"nat_mult_eq_cancel1";
   7.897 -val nat_mult_div_cancel1 = thm"nat_mult_div_cancel1";
   7.898 -val nat_mult_le_cancel_disj = thm"nat_mult_le_cancel_disj";
   7.899 -val nat_mult_less_cancel_disj = thm"nat_mult_less_cancel_disj";
   7.900 -val nat_mult_eq_cancel_disj = thm"nat_mult_eq_cancel_disj";
   7.901 -val nat_mult_div_cancel_disj = thm"nat_mult_div_cancel_disj";
   7.902 -
   7.903 -val power_minus_even = thm"power_minus_even";
   7.904 -*}
   7.905 -
   7.906 -end
     8.1 --- a/src/HOL/Integ/NatSimprocs.thy	Thu May 31 18:16:51 2007 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,391 +0,0 @@
     8.4 -(*  Title:      HOL/NatSimprocs.thy
     8.5 -    ID:         $Id$
     8.6 -    Copyright   2003 TU Muenchen
     8.7 -*)
     8.8 -
     8.9 -header {*Simprocs for the Naturals*}
    8.10 -
    8.11 -theory NatSimprocs
    8.12 -imports NatBin
    8.13 -uses "int_factor_simprocs.ML" "nat_simprocs.ML"
    8.14 -begin
    8.15 -
    8.16 -setup nat_simprocs_setup
    8.17 -
    8.18 -subsection{*For simplifying @{term "Suc m - K"} and  @{term "K - Suc m"}*}
    8.19 -
    8.20 -text{*Where K above is a literal*}
    8.21 -
    8.22 -lemma Suc_diff_eq_diff_pred: "Numeral0 < n ==> Suc m - n = m - (n - Numeral1)"
    8.23 -by (simp add: numeral_0_eq_0 numeral_1_eq_1 split add: nat_diff_split)
    8.24 -
    8.25 -text {*Now just instantiating @{text n} to @{text "number_of v"} does
    8.26 -  the right simplification, but with some redundant inequality
    8.27 -  tests.*}
    8.28 -lemma neg_number_of_pred_iff_0:
    8.29 -  "neg (number_of (Numeral.pred v)::int) = (number_of v = (0::nat))"
    8.30 -apply (subgoal_tac "neg (number_of (Numeral.pred v)) = (number_of v < Suc 0) ")
    8.31 -apply (simp only: less_Suc_eq_le le_0_eq)
    8.32 -apply (subst less_number_of_Suc, simp)
    8.33 -done
    8.34 -
    8.35 -text{*No longer required as a simprule because of the @{text inverse_fold}
    8.36 -   simproc*}
    8.37 -lemma Suc_diff_number_of:
    8.38 -     "neg (number_of (uminus v)::int) ==>  
    8.39 -      Suc m - (number_of v) = m - (number_of (Numeral.pred v))"
    8.40 -apply (subst Suc_diff_eq_diff_pred)
    8.41 -apply simp
    8.42 -apply (simp del: nat_numeral_1_eq_1)
    8.43 -apply (auto simp only: diff_nat_number_of less_0_number_of [symmetric] 
    8.44 -                        neg_number_of_pred_iff_0)
    8.45 -done
    8.46 -
    8.47 -lemma diff_Suc_eq_diff_pred: "m - Suc n = (m - 1) - n"
    8.48 -by (simp add: numerals split add: nat_diff_split)
    8.49 -
    8.50 -
    8.51 -subsection{*For @{term nat_case} and @{term nat_rec}*}
    8.52 -
    8.53 -lemma nat_case_number_of [simp]:
    8.54 -     "nat_case a f (number_of v) =  
    8.55 -        (let pv = number_of (Numeral.pred v) in  
    8.56 -         if neg pv then a else f (nat pv))"
    8.57 -by (simp split add: nat.split add: Let_def neg_number_of_pred_iff_0)
    8.58 -
    8.59 -lemma nat_case_add_eq_if [simp]:
    8.60 -     "nat_case a f ((number_of v) + n) =  
    8.61 -       (let pv = number_of (Numeral.pred v) in  
    8.62 -         if neg pv then nat_case a f n else f (nat pv + n))"
    8.63 -apply (subst add_eq_if)
    8.64 -apply (simp split add: nat.split
    8.65 -            del: nat_numeral_1_eq_1
    8.66 -	    add: numeral_1_eq_Suc_0 [symmetric] Let_def 
    8.67 -                 neg_imp_number_of_eq_0 neg_number_of_pred_iff_0)
    8.68 -done
    8.69 -
    8.70 -lemma nat_rec_number_of [simp]:
    8.71 -     "nat_rec a f (number_of v) =  
    8.72 -        (let pv = number_of (Numeral.pred v) in  
    8.73 -         if neg pv then a else f (nat pv) (nat_rec a f (nat pv)))"
    8.74 -apply (case_tac " (number_of v) ::nat")
    8.75 -apply (simp_all (no_asm_simp) add: Let_def neg_number_of_pred_iff_0)
    8.76 -apply (simp split add: split_if_asm)
    8.77 -done
    8.78 -
    8.79 -lemma nat_rec_add_eq_if [simp]:
    8.80 -     "nat_rec a f (number_of v + n) =  
    8.81 -        (let pv = number_of (Numeral.pred v) in  
    8.82 -         if neg pv then nat_rec a f n  
    8.83 -                   else f (nat pv + n) (nat_rec a f (nat pv + n)))"
    8.84 -apply (subst add_eq_if)
    8.85 -apply (simp split add: nat.split
    8.86 -            del: nat_numeral_1_eq_1
    8.87 -            add: numeral_1_eq_Suc_0 [symmetric] Let_def neg_imp_number_of_eq_0
    8.88 -                 neg_number_of_pred_iff_0)
    8.89 -done
    8.90 -
    8.91 -
    8.92 -subsection{*Various Other Lemmas*}
    8.93 -
    8.94 -subsubsection{*Evens and Odds, for Mutilated Chess Board*}
    8.95 -
    8.96 -text{*Lemmas for specialist use, NOT as default simprules*}
    8.97 -lemma nat_mult_2: "2 * z = (z+z::nat)"
    8.98 -proof -
    8.99 -  have "2*z = (1 + 1)*z" by simp
   8.100 -  also have "... = z+z" by (simp add: left_distrib)
   8.101 -  finally show ?thesis .
   8.102 -qed
   8.103 -
   8.104 -lemma nat_mult_2_right: "z * 2 = (z+z::nat)"
   8.105 -by (subst mult_commute, rule nat_mult_2)
   8.106 -
   8.107 -text{*Case analysis on @{term "n<2"}*}
   8.108 -lemma less_2_cases: "(n::nat) < 2 ==> n = 0 | n = Suc 0"
   8.109 -by arith
   8.110 -
   8.111 -lemma div2_Suc_Suc [simp]: "Suc(Suc m) div 2 = Suc (m div 2)"
   8.112 -by arith
   8.113 -
   8.114 -lemma add_self_div_2 [simp]: "(m + m) div 2 = (m::nat)"
   8.115 -by (simp add: nat_mult_2 [symmetric])
   8.116 -
   8.117 -lemma mod2_Suc_Suc [simp]: "Suc(Suc(m)) mod 2 = m mod 2"
   8.118 -apply (subgoal_tac "m mod 2 < 2")
   8.119 -apply (erule less_2_cases [THEN disjE])
   8.120 -apply (simp_all (no_asm_simp) add: Let_def mod_Suc nat_1)
   8.121 -done
   8.122 -
   8.123 -lemma mod2_gr_0 [simp]: "!!m::nat. (0 < m mod 2) = (m mod 2 = 1)"
   8.124 -apply (subgoal_tac "m mod 2 < 2")
   8.125 -apply (force simp del: mod_less_divisor, simp) 
   8.126 -done
   8.127 -
   8.128 -subsubsection{*Removal of Small Numerals: 0, 1 and (in additive positions) 2*}
   8.129 -
   8.130 -lemma add_2_eq_Suc [simp]: "2 + n = Suc (Suc n)"
   8.131 -by simp
   8.132 -
   8.133 -lemma add_2_eq_Suc' [simp]: "n + 2 = Suc (Suc n)"
   8.134 -by simp
   8.135 -
   8.136 -text{*Can be used to eliminate long strings of Sucs, but not by default*}
   8.137 -lemma Suc3_eq_add_3: "Suc (Suc (Suc n)) = 3 + n"
   8.138 -by simp
   8.139 -
   8.140 -
   8.141 -text{*These lemmas collapse some needless occurrences of Suc:
   8.142 -    at least three Sucs, since two and fewer are rewritten back to Suc again!
   8.143 -    We already have some rules to simplify operands smaller than 3.*}
   8.144 -
   8.145 -lemma div_Suc_eq_div_add3 [simp]: "m div (Suc (Suc (Suc n))) = m div (3+n)"
   8.146 -by (simp add: Suc3_eq_add_3)
   8.147 -
   8.148 -lemma mod_Suc_eq_mod_add3 [simp]: "m mod (Suc (Suc (Suc n))) = m mod (3+n)"
   8.149 -by (simp add: Suc3_eq_add_3)
   8.150 -
   8.151 -lemma Suc_div_eq_add3_div: "(Suc (Suc (Suc m))) div n = (3+m) div n"
   8.152 -by (simp add: Suc3_eq_add_3)
   8.153 -
   8.154 -lemma Suc_mod_eq_add3_mod: "(Suc (Suc (Suc m))) mod n = (3+m) mod n"
   8.155 -by (simp add: Suc3_eq_add_3)
   8.156 -
   8.157 -lemmas Suc_div_eq_add3_div_number_of =
   8.158 -    Suc_div_eq_add3_div [of _ "number_of v", standard]
   8.159 -declare Suc_div_eq_add3_div_number_of [simp]
   8.160 -
   8.161 -lemmas Suc_mod_eq_add3_mod_number_of =
   8.162 -    Suc_mod_eq_add3_mod [of _ "number_of v", standard]
   8.163 -declare Suc_mod_eq_add3_mod_number_of [simp]
   8.164 -
   8.165 -
   8.166 -
   8.167 -subsection{*Special Simplification for Constants*}
   8.168 -
   8.169 -text{*These belong here, late in the development of HOL, to prevent their
   8.170 -interfering with proofs of abstract properties of instances of the function
   8.171 -@{term number_of}*}
   8.172 -
   8.173 -text{*These distributive laws move literals inside sums and differences.*}
   8.174 -lemmas left_distrib_number_of = left_distrib [of _ _ "number_of v", standard]
   8.175 -declare left_distrib_number_of [simp]
   8.176 -
   8.177 -lemmas right_distrib_number_of = right_distrib [of "number_of v", standard]
   8.178 -declare right_distrib_number_of [simp]
   8.179 -
   8.180 -
   8.181 -lemmas left_diff_distrib_number_of =
   8.182 -    left_diff_distrib [of _ _ "number_of v", standard]
   8.183 -declare left_diff_distrib_number_of [simp]
   8.184 -
   8.185 -lemmas right_diff_distrib_number_of =
   8.186 -    right_diff_distrib [of "number_of v", standard]
   8.187 -declare right_diff_distrib_number_of [simp]
   8.188 -
   8.189 -
   8.190 -text{*These are actually for fields, like real: but where else to put them?*}
   8.191 -lemmas zero_less_divide_iff_number_of =
   8.192 -    zero_less_divide_iff [of "number_of w", standard]
   8.193 -declare zero_less_divide_iff_number_of [simp]
   8.194 -
   8.195 -lemmas divide_less_0_iff_number_of =
   8.196 -    divide_less_0_iff [of "number_of w", standard]
   8.197 -declare divide_less_0_iff_number_of [simp]
   8.198 -
   8.199 -lemmas zero_le_divide_iff_number_of =
   8.200 -    zero_le_divide_iff [of "number_of w", standard]
   8.201 -declare zero_le_divide_iff_number_of [simp]
   8.202 -
   8.203 -lemmas divide_le_0_iff_number_of =
   8.204 -    divide_le_0_iff [of "number_of w", standard]
   8.205 -declare divide_le_0_iff_number_of [simp]
   8.206 -
   8.207 -
   8.208 -(****
   8.209 -IF times_divide_eq_right and times_divide_eq_left are removed as simprules,
   8.210 -then these special-case declarations may be useful.
   8.211 -
   8.212 -text{*These simprules move numerals into numerators and denominators.*}
   8.213 -lemma times_recip_eq_right [simp]: "a * (1/c) = a / (c::'a::field)"
   8.214 -by (simp add: times_divide_eq)
   8.215 -
   8.216 -lemma times_recip_eq_left [simp]: "(1/c) * a = a / (c::'a::field)"
   8.217 -by (simp add: times_divide_eq)
   8.218 -
   8.219 -lemmas times_divide_eq_right_number_of =
   8.220 -    times_divide_eq_right [of "number_of w", standard]
   8.221 -declare times_divide_eq_right_number_of [simp]
   8.222 -
   8.223 -lemmas times_divide_eq_right_number_of =
   8.224 -    times_divide_eq_right [of _ _ "number_of w", standard]
   8.225 -declare times_divide_eq_right_number_of [simp]
   8.226 -
   8.227 -lemmas times_divide_eq_left_number_of =
   8.228 -    times_divide_eq_left [of _ "number_of w", standard]
   8.229 -declare times_divide_eq_left_number_of [simp]
   8.230 -
   8.231 -lemmas times_divide_eq_left_number_of =
   8.232 -    times_divide_eq_left [of _ _ "number_of w", standard]
   8.233 -declare times_divide_eq_left_number_of [simp]
   8.234 -
   8.235 -****)
   8.236 -
   8.237 -text {*Replaces @{text "inverse #nn"} by @{text "1/#nn"}.  It looks
   8.238 -  strange, but then other simprocs simplify the quotient.*}
   8.239 -
   8.240 -lemmas inverse_eq_divide_number_of =
   8.241 -    inverse_eq_divide [of "number_of w", standard]
   8.242 -declare inverse_eq_divide_number_of [simp]
   8.243 -
   8.244 -
   8.245 -subsubsection{*These laws simplify inequalities, moving unary minus from a term
   8.246 -into the literal.*}
   8.247 -lemmas less_minus_iff_number_of =
   8.248 -    less_minus_iff [of "number_of v", standard]
   8.249 -declare less_minus_iff_number_of [simp]
   8.250 -
   8.251 -lemmas le_minus_iff_number_of =
   8.252 -    le_minus_iff [of "number_of v", standard]
   8.253 -declare le_minus_iff_number_of [simp]
   8.254 -
   8.255 -lemmas equation_minus_iff_number_of =
   8.256 -    equation_minus_iff [of "number_of v", standard]
   8.257 -declare equation_minus_iff_number_of [simp]
   8.258 -
   8.259 -
   8.260 -lemmas minus_less_iff_number_of =
   8.261 -    minus_less_iff [of _ "number_of v", standard]
   8.262 -declare minus_less_iff_number_of [simp]
   8.263 -
   8.264 -lemmas minus_le_iff_number_of =
   8.265 -    minus_le_iff [of _ "number_of v", standard]
   8.266 -declare minus_le_iff_number_of [simp]
   8.267 -
   8.268 -lemmas minus_equation_iff_number_of =
   8.269 -    minus_equation_iff [of _ "number_of v", standard]
   8.270 -declare minus_equation_iff_number_of [simp]
   8.271 -
   8.272 -
   8.273 -subsubsection{*To Simplify Inequalities Where One Side is the Constant 1*}
   8.274 -
   8.275 -lemma less_minus_iff_1 [simp]: 
   8.276 -  fixes b::"'b::{ordered_idom,number_ring}" 
   8.277 -  shows "(1 < - b) = (b < -1)"
   8.278 -by auto
   8.279 -
   8.280 -lemma le_minus_iff_1 [simp]: 
   8.281 -  fixes b::"'b::{ordered_idom,number_ring}" 
   8.282 -  shows "(1 \<le> - b) = (b \<le> -1)"
   8.283 -by auto
   8.284 -
   8.285 -lemma equation_minus_iff_1 [simp]: 
   8.286 -  fixes b::"'b::number_ring" 
   8.287 -  shows "(1 = - b) = (b = -1)"
   8.288 -by (subst equation_minus_iff, auto) 
   8.289 -
   8.290 -lemma minus_less_iff_1 [simp]: 
   8.291 -  fixes a::"'b::{ordered_idom,number_ring}" 
   8.292 -  shows "(- a < 1) = (-1 < a)"
   8.293 -by auto
   8.294 -
   8.295 -lemma minus_le_iff_1 [simp]: 
   8.296 -  fixes a::"'b::{ordered_idom,number_ring}" 
   8.297 -  shows "(- a \<le> 1) = (-1 \<le> a)"
   8.298 -by auto
   8.299 -
   8.300 -lemma minus_equation_iff_1 [simp]: 
   8.301 -  fixes a::"'b::number_ring" 
   8.302 -  shows "(- a = 1) = (a = -1)"
   8.303 -by (subst minus_equation_iff, auto) 
   8.304 -
   8.305 -
   8.306 -subsubsection {*Cancellation of constant factors in comparisons (@{text "<"} and @{text "\<le>"}) *}
   8.307 -
   8.308 -lemmas mult_less_cancel_left_number_of =
   8.309 -    mult_less_cancel_left [of "number_of v", standard]
   8.310 -declare mult_less_cancel_left_number_of [simp]
   8.311 -
   8.312 -lemmas mult_less_cancel_right_number_of =
   8.313 -    mult_less_cancel_right [of _ "number_of v", standard]
   8.314 -declare mult_less_cancel_right_number_of [simp]
   8.315 -
   8.316 -lemmas mult_le_cancel_left_number_of =
   8.317 -    mult_le_cancel_left [of "number_of v", standard]
   8.318 -declare mult_le_cancel_left_number_of [simp]
   8.319 -
   8.320 -lemmas mult_le_cancel_right_number_of =
   8.321 -    mult_le_cancel_right [of _ "number_of v", standard]
   8.322 -declare mult_le_cancel_right_number_of [simp]
   8.323 -
   8.324 -
   8.325 -subsubsection {*Multiplying out constant divisors in comparisons (@{text "<"}, @{text "\<le>"} and @{text "="}) *}
   8.326 -
   8.327 -lemmas le_divide_eq_number_of = le_divide_eq [of _ _ "number_of w", standard]
   8.328 -declare le_divide_eq_number_of [simp]
   8.329 -
   8.330 -lemmas divide_le_eq_number_of = divide_le_eq [of _ "number_of w", standard]
   8.331 -declare divide_le_eq_number_of [simp]
   8.332 -
   8.333 -lemmas less_divide_eq_number_of = less_divide_eq [of _ _ "number_of w", standard]
   8.334 -declare less_divide_eq_number_of [simp]
   8.335 -
   8.336 -lemmas divide_less_eq_number_of = divide_less_eq [of _ "number_of w", standard]
   8.337 -declare divide_less_eq_number_of [simp]
   8.338 -
   8.339 -lemmas eq_divide_eq_number_of = eq_divide_eq [of _ _ "number_of w", standard]
   8.340 -declare eq_divide_eq_number_of [simp]
   8.341 -
   8.342 -lemmas divide_eq_eq_number_of = divide_eq_eq [of _ "number_of w", standard]
   8.343 -declare divide_eq_eq_number_of [simp]
   8.344 -
   8.345 -
   8.346 -
   8.347 -subsection{*Optional Simplification Rules Involving Constants*}
   8.348 -
   8.349 -text{*Simplify quotients that are compared with a literal constant.*}
   8.350 -
   8.351 -lemmas le_divide_eq_number_of = le_divide_eq [of "number_of w", standard]
   8.352 -lemmas divide_le_eq_number_of = divide_le_eq [of _ _ "number_of w", standard]
   8.353 -lemmas less_divide_eq_number_of = less_divide_eq [of "number_of w", standard]
   8.354 -lemmas divide_less_eq_number_of = divide_less_eq [of _ _ "number_of w", standard]
   8.355 -lemmas eq_divide_eq_number_of = eq_divide_eq [of "number_of w", standard]
   8.356 -lemmas divide_eq_eq_number_of = divide_eq_eq [of _ _ "number_of w", standard]
   8.357 -
   8.358 -
   8.359 -text{*Not good as automatic simprules because they cause case splits.*}
   8.360 -lemmas divide_const_simps =
   8.361 -  le_divide_eq_number_of divide_le_eq_number_of less_divide_eq_number_of
   8.362 -  divide_less_eq_number_of eq_divide_eq_number_of divide_eq_eq_number_of
   8.363 -  le_divide_eq_1 divide_le_eq_1 less_divide_eq_1 divide_less_eq_1
   8.364 -
   8.365 -subsubsection{*Division By @{text "-1"}*}
   8.366 -
   8.367 -lemma divide_minus1 [simp]:
   8.368 -     "x/-1 = -(x::'a::{field,division_by_zero,number_ring})" 
   8.369 -by simp
   8.370 -
   8.371 -lemma minus1_divide [simp]:
   8.372 -     "-1 / (x::'a::{field,division_by_zero,number_ring}) = - (1/x)"
   8.373 -by (simp add: divide_inverse inverse_minus_eq)
   8.374 -
   8.375 -lemma half_gt_zero_iff:
   8.376 -     "(0 < r/2) = (0 < (r::'a::{ordered_field,division_by_zero,number_ring}))"
   8.377 -by auto
   8.378 -
   8.379 -lemmas half_gt_zero = half_gt_zero_iff [THEN iffD2, standard]
   8.380 -declare half_gt_zero [simp]
   8.381 -
   8.382 -(* The following lemma should appear in Divides.thy, but there the proof
   8.383 -   doesn't work. *)
   8.384 -
   8.385 -lemma nat_dvd_not_less:
   8.386 -  "[| 0 < m; m < n |] ==> \<not> n dvd (m::nat)"
   8.387 -  by (unfold dvd_def) auto
   8.388 -
   8.389 -ML {*
   8.390 -val divide_minus1 = @{thm divide_minus1};
   8.391 -val minus1_divide = @{thm minus1_divide};
   8.392 -*}
   8.393 -
   8.394 -end
     9.1 --- a/src/HOL/Integ/Numeral.thy	Thu May 31 18:16:51 2007 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,685 +0,0 @@
     9.4 -(*  Title:      HOL/Integ/Numeral.thy
     9.5 -    ID:         $Id$
     9.6 -    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     9.7 -    Copyright   1994  University of Cambridge
     9.8 -*)
     9.9 -
    9.10 -header {* Arithmetic on Binary Integers *}
    9.11 -
    9.12 -theory Numeral
    9.13 -imports IntDef
    9.14 -uses ("../Tools/numeral_syntax.ML")
    9.15 -begin
    9.16 -
    9.17 -subsection {* Binary representation *}
    9.18 -
    9.19 -text {*
    9.20 -  This formalization defines binary arithmetic in terms of the integers
    9.21 -  rather than using a datatype. This avoids multiple representations (leading
    9.22 -  zeroes, etc.)  See @{text "ZF/Integ/twos-compl.ML"}, function @{text
    9.23 -  int_of_binary}, for the numerical interpretation.
    9.24 -
    9.25 -  The representation expects that @{text "(m mod 2)"} is 0 or 1,
    9.26 -  even if m is negative;
    9.27 -  For instance, @{text "-5 div 2 = -3"} and @{text "-5 mod 2 = 1"}; thus
    9.28 -  @{text "-5 = (-3)*2 + 1"}.
    9.29 -*}
    9.30 -
    9.31 -datatype bit = B0 | B1
    9.32 -
    9.33 -text{*
    9.34 -  Type @{typ bit} avoids the use of type @{typ bool}, which would make
    9.35 -  all of the rewrite rules higher-order.
    9.36 -*}
    9.37 -
    9.38 -definition
    9.39 -  Pls :: int where
    9.40 -  [code func del]:"Pls = 0"
    9.41 -
    9.42 -definition
    9.43 -  Min :: int where
    9.44 -  [code func del]:"Min = - 1"
    9.45 -
    9.46 -definition
    9.47 -  Bit :: "int \<Rightarrow> bit \<Rightarrow> int" (infixl "BIT" 90) where
    9.48 -  [code func del]: "k BIT b = (case b of B0 \<Rightarrow> 0 | B1 \<Rightarrow> 1) + k + k"
    9.49 -
    9.50 -class number = type + -- {* for numeric types: nat, int, real, \dots *}
    9.51 -  fixes number_of :: "int \<Rightarrow> 'a"
    9.52 -
    9.53 -syntax
    9.54 -  "_Numeral" :: "num_const \<Rightarrow> 'a"    ("_")
    9.55 -
    9.56 -use "../Tools/numeral_syntax.ML"
    9.57 -setup NumeralSyntax.setup
    9.58 -
    9.59 -abbreviation
    9.60 -  "Numeral0 \<equiv> number_of Pls"
    9.61 -
    9.62 -abbreviation
    9.63 -  "Numeral1 \<equiv> number_of (Pls BIT B1)"
    9.64 -
    9.65 -lemma Let_number_of [simp]: "Let (number_of v) f = f (number_of v)"
    9.66 -  -- {* Unfold all @{text let}s involving constants *}
    9.67 -  unfolding Let_def ..
    9.68 -
    9.69 -lemma Let_0 [simp]: "Let 0 f = f 0"
    9.70 -  unfolding Let_def ..
    9.71 -
    9.72 -lemma Let_1 [simp]: "Let 1 f = f 1"
    9.73 -  unfolding Let_def ..
    9.74 -
    9.75 -definition
    9.76 -  succ :: "int \<Rightarrow> int" where
    9.77 -  [code func del]: "succ k = k + 1"
    9.78 -
    9.79 -definition
    9.80 -  pred :: "int \<Rightarrow> int" where
    9.81 -  [code func del]: "pred k = k - 1"
    9.82 -
    9.83 -lemmas
    9.84 -  max_number_of [simp] = max_def
    9.85 -    [of "number_of u" "number_of v", standard, simp]
    9.86 -and
    9.87 -  min_number_of [simp] = min_def 
    9.88 -    [of "number_of u" "number_of v", standard, simp]
    9.89 -  -- {* unfolding @{text minx} and @{text max} on numerals *}
    9.90 -
    9.91 -lemmas numeral_simps = 
    9.92 -  succ_def pred_def Pls_def Min_def Bit_def
    9.93 -
    9.94 -text {* Removal of leading zeroes *}
    9.95 -
    9.96 -lemma Pls_0_eq [simp, normal post]:
    9.97 -  "Pls BIT B0 = Pls"
    9.98 -  unfolding numeral_simps by simp
    9.99 -
   9.100 -lemma Min_1_eq [simp, normal post]:
   9.101 -  "Min BIT B1 = Min"
   9.102 -  unfolding numeral_simps by simp
   9.103 -
   9.104 -
   9.105 -subsection {* The Functions @{term succ}, @{term pred} and @{term uminus} *}
   9.106 -
   9.107 -lemma succ_Pls [simp]:
   9.108 -  "succ Pls = Pls BIT B1"
   9.109 -  unfolding numeral_simps by simp
   9.110 -
   9.111 -lemma succ_Min [simp]:
   9.112 -  "succ Min = Pls"
   9.113 -  unfolding numeral_simps by simp
   9.114 -
   9.115 -lemma succ_1 [simp]:
   9.116 -  "succ (k BIT B1) = succ k BIT B0"
   9.117 -  unfolding numeral_simps by simp
   9.118 -
   9.119 -lemma succ_0 [simp]:
   9.120 -  "succ (k BIT B0) = k BIT B1"
   9.121 -  unfolding numeral_simps by simp
   9.122 -
   9.123 -lemma pred_Pls [simp]:
   9.124 -  "pred Pls = Min"
   9.125 -  unfolding numeral_simps by simp
   9.126 -
   9.127 -lemma pred_Min [simp]:
   9.128 -  "pred Min = Min BIT B0"
   9.129 -  unfolding numeral_simps by simp
   9.130 -
   9.131 -lemma pred_1 [simp]:
   9.132 -  "pred (k BIT B1) = k BIT B0"
   9.133 -  unfolding numeral_simps by simp
   9.134 -
   9.135 -lemma pred_0 [simp]:
   9.136 -  "pred (k BIT B0) = pred k BIT B1"
   9.137 -  unfolding numeral_simps by simp 
   9.138 -
   9.139 -lemma minus_Pls [simp]:
   9.140 -  "- Pls = Pls"
   9.141 -  unfolding numeral_simps by simp 
   9.142 -
   9.143 -lemma minus_Min [simp]:
   9.144 -  "- Min = Pls BIT B1"
   9.145 -  unfolding numeral_simps by simp 
   9.146 -
   9.147 -lemma minus_1 [simp]:
   9.148 -  "- (k BIT B1) = pred (- k) BIT B1"
   9.149 -  unfolding numeral_simps by simp 
   9.150 -
   9.151 -lemma minus_0 [simp]:
   9.152 -  "- (k BIT B0) = (- k) BIT B0"
   9.153 -  unfolding numeral_simps by simp 
   9.154 -
   9.155 -
   9.156 -subsection {*
   9.157 -  Binary Addition and Multiplication: @{term "op + \<Colon> int \<Rightarrow> int \<Rightarrow> int"}
   9.158 -    and @{term "op * \<Colon> int \<Rightarrow> int \<Rightarrow> int"}
   9.159 -*}
   9.160 -
   9.161 -lemma add_Pls [simp]:
   9.162 -  "Pls + k = k"
   9.163 -  unfolding numeral_simps by simp 
   9.164 -
   9.165 -lemma add_Min [simp]:
   9.166 -  "Min + k = pred k"
   9.167 -  unfolding numeral_simps by simp
   9.168 -
   9.169 -lemma add_BIT_11 [simp]:
   9.170 -  "(k BIT B1) + (l BIT B1) = (k + succ l) BIT B0"
   9.171 -  unfolding numeral_simps by simp
   9.172 -
   9.173 -lemma add_BIT_10 [simp]:
   9.174 -  "(k BIT B1) + (l BIT B0) = (k + l) BIT B1"
   9.175 -  unfolding numeral_simps by simp
   9.176 -
   9.177 -lemma add_BIT_0 [simp]:
   9.178 -  "(k BIT B0) + (l BIT b) = (k + l) BIT b"
   9.179 -  unfolding numeral_simps by simp 
   9.180 -
   9.181 -lemma add_Pls_right [simp]:
   9.182 -  "k + Pls = k"
   9.183 -  unfolding numeral_simps by simp 
   9.184 -
   9.185 -lemma add_Min_right [simp]:
   9.186 -  "k + Min = pred k"
   9.187 -  unfolding numeral_simps by simp 
   9.188 -
   9.189 -lemma mult_Pls [simp]:
   9.190 -  "Pls * w = Pls"
   9.191 -  unfolding numeral_simps by simp 
   9.192 -
   9.193 -lemma mult_Min [simp]:
   9.194 -  "Min * k = - k"
   9.195 -  unfolding numeral_simps by simp 
   9.196 -
   9.197 -lemma mult_num1 [simp]:
   9.198 -  "(k BIT B1) * l = ((k * l) BIT B0) + l"
   9.199 -  unfolding numeral_simps int_distrib by simp 
   9.200 -
   9.201 -lemma mult_num0 [simp]:
   9.202 -  "(k BIT B0) * l = (k * l) BIT B0"
   9.203 -  unfolding numeral_simps int_distrib by simp 
   9.204 -
   9.205 -
   9.206 -
   9.207 -subsection {* Converting Numerals to Rings: @{term number_of} *}
   9.208 -
   9.209 -axclass number_ring \<subseteq> number, comm_ring_1
   9.210 -  number_of_eq: "number_of k = of_int k"
   9.211 -
   9.212 -text {* self-embedding of the intergers *}
   9.213 -
   9.214 -instance int :: number_ring
   9.215 -  int_number_of_def: "number_of w \<equiv> of_int w"
   9.216 -  by intro_classes (simp only: int_number_of_def)
   9.217 -
   9.218 -lemmas [code func del] = int_number_of_def
   9.219 -
   9.220 -lemma number_of_is_id:
   9.221 -  "number_of (k::int) = k"
   9.222 -  unfolding int_number_of_def by simp
   9.223 -
   9.224 -lemma number_of_succ:
   9.225 -  "number_of (succ k) = (1 + number_of k ::'a::number_ring)"
   9.226 -  unfolding number_of_eq numeral_simps by simp
   9.227 -
   9.228 -lemma number_of_pred:
   9.229 -  "number_of (pred w) = (- 1 + number_of w ::'a::number_ring)"
   9.230 -  unfolding number_of_eq numeral_simps by simp
   9.231 -
   9.232 -lemma number_of_minus:
   9.233 -  "number_of (uminus w) = (- (number_of w)::'a::number_ring)"
   9.234 -  unfolding number_of_eq numeral_simps by simp
   9.235 -
   9.236 -lemma number_of_add:
   9.237 -  "number_of (v + w) = (number_of v + number_of w::'a::number_ring)"
   9.238 -  unfolding number_of_eq numeral_simps by simp
   9.239 -
   9.240 -lemma number_of_mult:
   9.241 -  "number_of (v * w) = (number_of v * number_of w::'a::number_ring)"
   9.242 -  unfolding number_of_eq numeral_simps by simp
   9.243 -
   9.244 -text {*
   9.245 -  The correctness of shifting.
   9.246 -  But it doesn't seem to give a measurable speed-up.
   9.247 -*}
   9.248 -
   9.249 -lemma double_number_of_BIT:
   9.250 -  "(1 + 1) * number_of w = (number_of (w BIT B0) ::'a::number_ring)"
   9.251 -  unfolding number_of_eq numeral_simps left_distrib by simp
   9.252 -
   9.253 -text {*
   9.254 -  Converting numerals 0 and 1 to their abstract versions.
   9.255 -*}
   9.256 -
   9.257 -lemma numeral_0_eq_0 [simp]:
   9.258 -  "Numeral0 = (0::'a::number_ring)"
   9.259 -  unfolding number_of_eq numeral_simps by simp
   9.260 -
   9.261 -lemma numeral_1_eq_1 [simp]:
   9.262 -  "Numeral1 = (1::'a::number_ring)"
   9.263 -  unfolding number_of_eq numeral_simps by simp
   9.264 -
   9.265 -text {*
   9.266 -  Special-case simplification for small constants.
   9.267 -*}
   9.268 -
   9.269 -text{*
   9.270 -  Unary minus for the abstract constant 1. Cannot be inserted
   9.271 -  as a simprule until later: it is @{text number_of_Min} re-oriented!
   9.272 -*}
   9.273 -
   9.274 -lemma numeral_m1_eq_minus_1:
   9.275 -  "(-1::'a::number_ring) = - 1"
   9.276 -  unfolding number_of_eq numeral_simps by simp
   9.277 -
   9.278 -lemma mult_minus1 [simp]:
   9.279 -  "-1 * z = -(z::'a::number_ring)"
   9.280 -  unfolding number_of_eq numeral_simps by simp
   9.281 -
   9.282 -lemma mult_minus1_right [simp]:
   9.283 -  "z * -1 = -(z::'a::number_ring)"
   9.284 -  unfolding number_of_eq numeral_simps by simp
   9.285 -
   9.286 -(*Negation of a coefficient*)
   9.287 -lemma minus_number_of_mult [simp]:
   9.288 -   "- (number_of w) * z = number_of (uminus w) * (z::'a::number_ring)"
   9.289 -   unfolding number_of_eq by simp
   9.290 -
   9.291 -text {* Subtraction *}
   9.292 -
   9.293 -lemma diff_number_of_eq:
   9.294 -  "number_of v - number_of w =
   9.295 -    (number_of (v + uminus w)::'a::number_ring)"
   9.296 -  unfolding number_of_eq by simp
   9.297 -
   9.298 -lemma number_of_Pls:
   9.299 -  "number_of Pls = (0::'a::number_ring)"
   9.300 -  unfolding number_of_eq numeral_simps by simp
   9.301 -
   9.302 -lemma number_of_Min:
   9.303 -  "number_of Min = (- 1::'a::number_ring)"
   9.304 -  unfolding number_of_eq numeral_simps by simp
   9.305 -
   9.306 -lemma number_of_BIT:
   9.307 -  "number_of(w BIT x) = (case x of B0 => 0 | B1 => (1::'a::number_ring))
   9.308 -    + (number_of w) + (number_of w)"
   9.309 -  unfolding number_of_eq numeral_simps by (simp split: bit.split)
   9.310 -
   9.311 -
   9.312 -subsection {* Equality of Binary Numbers *}
   9.313 -
   9.314 -text {* First version by Norbert Voelker *}
   9.315 -
   9.316 -lemma eq_number_of_eq:
   9.317 -  "((number_of x::'a::number_ring) = number_of y) =
   9.318 -   iszero (number_of (x + uminus y) :: 'a)"
   9.319 -  unfolding iszero_def number_of_add number_of_minus
   9.320 -  by (simp add: compare_rls)
   9.321 -
   9.322 -lemma iszero_number_of_Pls:
   9.323 -  "iszero ((number_of Pls)::'a::number_ring)"
   9.324 -  unfolding iszero_def numeral_0_eq_0 ..
   9.325 -
   9.326 -lemma nonzero_number_of_Min:
   9.327 -  "~ iszero ((number_of Min)::'a::number_ring)"
   9.328 -  unfolding iszero_def numeral_m1_eq_minus_1 by simp
   9.329 -
   9.330 -
   9.331 -subsection {* Comparisons, for Ordered Rings *}
   9.332 -
   9.333 -lemma double_eq_0_iff:
   9.334 -  "(a + a = 0) = (a = (0::'a::ordered_idom))"
   9.335 -proof -
   9.336 -  have "a + a = (1 + 1) * a" unfolding left_distrib by simp
   9.337 -  with zero_less_two [where 'a = 'a]
   9.338 -  show ?thesis by force
   9.339 -qed
   9.340 -
   9.341 -lemma le_imp_0_less: 
   9.342 -  assumes le: "0 \<le> z"
   9.343 -  shows "(0::int) < 1 + z"
   9.344 -proof -
   9.345 -  have "0 \<le> z" .
   9.346 -  also have "... < z + 1" by (rule less_add_one) 
   9.347 -  also have "... = 1 + z" by (simp add: add_ac)
   9.348 -  finally show "0 < 1 + z" .
   9.349 -qed
   9.350 -
   9.351 -lemma odd_nonzero:
   9.352 -  "1 + z + z \<noteq> (0::int)";
   9.353 -proof (cases z rule: int_cases)
   9.354 -  case (nonneg n)
   9.355 -  have le: "0 \<le> z+z" by (simp add: nonneg add_increasing) 
   9.356 -  thus ?thesis using  le_imp_0_less [OF le]
   9.357 -    by (auto simp add: add_assoc) 
   9.358 -next
   9.359 -  case (neg n)
   9.360 -  show ?thesis
   9.361 -  proof
   9.362 -    assume eq: "1 + z + z = 0"
   9.363 -    have "0 < 1 + (int n + int n)"
   9.364 -      by (simp add: le_imp_0_less add_increasing) 
   9.365 -    also have "... = - (1 + z + z)" 
   9.366 -      by (simp add: neg add_assoc [symmetric]) 
   9.367 -    also have "... = 0" by (simp add: eq) 
   9.368 -    finally have "0<0" ..
   9.369 -    thus False by blast
   9.370 -  qed
   9.371 -qed
   9.372 -
   9.373 -text {* The premise involving @{term Ints} prevents @{term "a = 1/2"}. *}
   9.374 -
   9.375 -lemma Ints_double_eq_0_iff:
   9.376 -  assumes in_Ints: "a \<in> Ints"
   9.377 -  shows "(a + a = 0) = (a = (0::'a::ring_char_0))"
   9.378 -proof -
   9.379 -  from in_Ints have "a \<in> range of_int" unfolding Ints_def [symmetric] .
   9.380 -  then obtain z where a: "a = of_int z" ..
   9.381 -  show ?thesis
   9.382 -  proof
   9.383 -    assume "a = 0"
   9.384 -    thus "a + a = 0" by simp
   9.385 -  next
   9.386 -    assume eq: "a + a = 0"
   9.387 -    hence "of_int (z + z) = (of_int 0 :: 'a)" by (simp add: a)
   9.388 -    hence "z + z = 0" by (simp only: of_int_eq_iff)
   9.389 -    hence "z = 0" by (simp only: double_eq_0_iff)
   9.390 -    thus "a = 0" by (simp add: a)
   9.391 -  qed
   9.392 -qed
   9.393 -
   9.394 -lemma Ints_odd_nonzero:
   9.395 -  assumes in_Ints: "a \<in> Ints"
   9.396 -  shows "1 + a + a \<noteq> (0::'a::ring_char_0)"
   9.397 -proof -
   9.398 -  from in_Ints have "a \<in> range of_int" unfolding Ints_def [symmetric] .
   9.399 -  then obtain z where a: "a = of_int z" ..
   9.400 -  show ?thesis
   9.401 -  proof
   9.402 -    assume eq: "1 + a + a = 0"
   9.403 -    hence "of_int (1 + z + z) = (of_int 0 :: 'a)" by (simp add: a)
   9.404 -    hence "1 + z + z = 0" by (simp only: of_int_eq_iff)
   9.405 -    with odd_nonzero show False by blast
   9.406 -  qed
   9.407 -qed 
   9.408 -
   9.409 -lemma Ints_number_of:
   9.410 -  "(number_of w :: 'a::number_ring) \<in> Ints"
   9.411 -  unfolding number_of_eq Ints_def by simp
   9.412 -
   9.413 -lemma iszero_number_of_BIT:
   9.414 -  "iszero (number_of (w BIT x)::'a) = 
   9.415 -   (x = B0 \<and> iszero (number_of w::'a::{ring_char_0,number_ring}))"
   9.416 -  by (simp add: iszero_def number_of_eq numeral_simps Ints_double_eq_0_iff 
   9.417 -    Ints_odd_nonzero Ints_def split: bit.split)
   9.418 -
   9.419 -lemma iszero_number_of_0:
   9.420 -  "iszero (number_of (w BIT B0) :: 'a::{ring_char_0,number_ring}) = 
   9.421 -  iszero (number_of w :: 'a)"
   9.422 -  by (simp only: iszero_number_of_BIT simp_thms)
   9.423 -
   9.424 -lemma iszero_number_of_1:
   9.425 -  "~ iszero (number_of (w BIT B1)::'a::{ring_char_0,number_ring})"
   9.426 -  by (simp add: iszero_number_of_BIT) 
   9.427 -
   9.428 -
   9.429 -subsection {* The Less-Than Relation *}
   9.430 -
   9.431 -lemma less_number_of_eq_neg:
   9.432 -  "((number_of x::'a::{ordered_idom,number_ring}) < number_of y)
   9.433 -  = neg (number_of (x + uminus y) :: 'a)"
   9.434 -apply (subst less_iff_diff_less_0) 
   9.435 -apply (simp add: neg_def diff_minus number_of_add number_of_minus)
   9.436 -done
   9.437 -
   9.438 -text {*
   9.439 -  If @{term Numeral0} is rewritten to 0 then this rule can't be applied:
   9.440 -  @{term Numeral0} IS @{term "number_of Pls"}
   9.441 -*}
   9.442 -
   9.443 -lemma not_neg_number_of_Pls:
   9.444 -  "~ neg (number_of Pls ::'a::{ordered_idom,number_ring})"
   9.445 -  by (simp add: neg_def numeral_0_eq_0)
   9.446 -
   9.447 -lemma neg_number_of_Min:
   9.448 -  "neg (number_of Min ::'a::{ordered_idom,number_ring})"
   9.449 -  by (simp add: neg_def zero_less_one numeral_m1_eq_minus_1)
   9.450 -
   9.451 -lemma double_less_0_iff:
   9.452 -  "(a + a < 0) = (a < (0::'a::ordered_idom))"
   9.453 -proof -
   9.454 -  have "(a + a < 0) = ((1+1)*a < 0)" by (simp add: left_distrib)
   9.455 -  also have "... = (a < 0)"
   9.456 -    by (simp add: mult_less_0_iff zero_less_two 
   9.457 -                  order_less_not_sym [OF zero_less_two]) 
   9.458 -  finally show ?thesis .
   9.459 -qed
   9.460 -
   9.461 -lemma odd_less_0:
   9.462 -  "(1 + z + z < 0) = (z < (0::int))";
   9.463 -proof (cases z rule: int_cases)
   9.464 -  case (nonneg n)
   9.465 -  thus ?thesis by (simp add: linorder_not_less add_assoc add_increasing
   9.466 -                             le_imp_0_less [THEN order_less_imp_le])  
   9.467 -next
   9.468 -  case (neg n)
   9.469 -  thus ?thesis by (simp del: int_Suc
   9.470 -    add: int_Suc0_eq_1 [symmetric] zadd_int compare_rls)
   9.471 -qed
   9.472 -
   9.473 -text {* The premise involving @{term Ints} prevents @{term "a = 1/2"}. *}
   9.474 -
   9.475 -lemma Ints_odd_less_0: 
   9.476 -  assumes in_Ints: "a \<in> Ints"
   9.477 -  shows "(1 + a + a < 0) = (a < (0::'a::ordered_idom))";
   9.478 -proof -
   9.479 -  from in_Ints have "a \<in> range of_int" unfolding Ints_def [symmetric] .
   9.480 -  then obtain z where a: "a = of_int z" ..
   9.481 -  hence "((1::'a) + a + a < 0) = (of_int (1 + z + z) < (of_int 0 :: 'a))"
   9.482 -    by (simp add: a)
   9.483 -  also have "... = (z < 0)" by (simp only: of_int_less_iff odd_less_0)
   9.484 -  also have "... = (a < 0)" by (simp add: a)
   9.485 -  finally show ?thesis .
   9.486 -qed
   9.487 -
   9.488 -lemma neg_number_of_BIT:
   9.489 -  "neg (number_of (w BIT x)::'a) = 
   9.490 -  neg (number_of w :: 'a::{ordered_idom,number_ring})"
   9.491 -  by (simp add: neg_def number_of_eq numeral_simps double_less_0_iff
   9.492 -    Ints_odd_less_0 Ints_def split: bit.split)
   9.493 -
   9.494 -
   9.495 -text {* Less-Than or Equals *}
   9.496 -
   9.497 -text {* Reduces @{term "a\<le>b"} to @{term "~ (b<a)"} for ALL numerals. *}
   9.498 -
   9.499 -lemmas le_number_of_eq_not_less =
   9.500 -  linorder_not_less [of "number_of w" "number_of v", symmetric, 
   9.501 -  standard]
   9.502 -
   9.503 -lemma le_number_of_eq:
   9.504 -    "((number_of x::'a::{ordered_idom,number_ring}) \<le> number_of y)
   9.505 -     = (~ (neg (number_of (y + uminus x) :: 'a)))"
   9.506 -by (simp add: le_number_of_eq_not_less less_number_of_eq_neg)
   9.507 -
   9.508 -
   9.509 -text {* Absolute value (@{term abs}) *}
   9.510 -
   9.511 -lemma abs_number_of:
   9.512 -  "abs(number_of x::'a::{ordered_idom,number_ring}) =
   9.513 -   (if number_of x < (0::'a) then -number_of x else number_of x)"
   9.514 -  by (simp add: abs_if)
   9.515 -
   9.516 -
   9.517 -text {* Re-orientation of the equation nnn=x *}
   9.518 -
   9.519 -lemma number_of_reorient:
   9.520 -  "(number_of w = x) = (x = number_of w)"
   9.521 -  by auto
   9.522 -
   9.523 -
   9.524 -subsection {* Simplification of arithmetic operations on integer constants. *}
   9.525 -
   9.526 -lemmas arith_extra_simps [standard, simp] =
   9.527 -  number_of_add [symmetric]
   9.528 -  number_of_minus [symmetric] numeral_m1_eq_minus_1 [symmetric]
   9.529 -  number_of_mult [symmetric]
   9.530 -  diff_number_of_eq abs_number_of 
   9.531 -
   9.532 -text {*
   9.533 -  For making a minimal simpset, one must include these default simprules.
   9.534 -  Also include @{text simp_thms}.
   9.535 -*}
   9.536 -
   9.537 -lemmas arith_simps = 
   9.538 -  bit.distinct
   9.539 -  Pls_0_eq Min_1_eq
   9.540 -  pred_Pls pred_Min pred_1 pred_0
   9.541 -  succ_Pls succ_Min succ_1 succ_0
   9.542 -  add_Pls add_Min add_BIT_0 add_BIT_10 add_BIT_11
   9.543 -  minus_Pls minus_Min minus_1 minus_0
   9.544 -  mult_Pls mult_Min mult_num1 mult_num0 
   9.545 -  add_Pls_right add_Min_right
   9.546 -  abs_zero abs_one arith_extra_simps
   9.547 -
   9.548 -text {* Simplification of relational operations *}
   9.549 -
   9.550 -lemmas rel_simps [simp] = 
   9.551 -  eq_number_of_eq iszero_number_of_Pls nonzero_number_of_Min
   9.552 -  iszero_number_of_0 iszero_number_of_1
   9.553 -  less_number_of_eq_neg
   9.554 -  not_neg_number_of_Pls not_neg_0 not_neg_1 not_iszero_1
   9.555 -  neg_number_of_Min neg_number_of_BIT
   9.556 -  le_number_of_eq
   9.557 -
   9.558 -
   9.559 -subsection {* Simplification of arithmetic when nested to the right. *}
   9.560 -
   9.561 -lemma add_number_of_left [simp]:
   9.562 -  "number_of v + (number_of w + z) =
   9.563 -   (number_of(v + w) + z::'a::number_ring)"
   9.564 -  by (simp add: add_assoc [symmetric])
   9.565 -
   9.566 -lemma mult_number_of_left [simp]:
   9.567 -  "number_of v * (number_of w * z) =
   9.568 -   (number_of(v * w) * z::'a::number_ring)"
   9.569 -  by (simp add: mult_assoc [symmetric])
   9.570 -
   9.571 -lemma add_number_of_diff1:
   9.572 -  "number_of v + (number_of w - c) = 
   9.573 -  number_of(v + w) - (c::'a::number_ring)"
   9.574 -  by (simp add: diff_minus add_number_of_left)
   9.575 -
   9.576 -lemma add_number_of_diff2 [simp]:
   9.577 -  "number_of v + (c - number_of w) =
   9.578 -   number_of (v + uminus w) + (c::'a::number_ring)"
   9.579 -apply (subst diff_number_of_eq [symmetric])
   9.580 -apply (simp only: compare_rls)
   9.581 -done
   9.582 -
   9.583 -
   9.584 -subsection {* Configuration of the code generator *}
   9.585 -
   9.586 -instance int :: eq ..
   9.587 -
   9.588 -code_datatype Pls Min Bit "number_of \<Colon> int \<Rightarrow> int"
   9.589 -
   9.590 -definition
   9.591 -  int_aux :: "int \<Rightarrow> nat \<Rightarrow> int" where
   9.592 -  "int_aux i n = (i + int n)"
   9.593 -
   9.594 -lemma [code]:
   9.595 -  "int_aux i 0 = i"
   9.596 -  "int_aux i (Suc n) = int_aux (i + 1) n" -- {* tail recursive *}
   9.597 -  by (simp add: int_aux_def)+
   9.598 -
   9.599 -lemma [code]:
   9.600 -  "int n = int_aux 0 n"
   9.601 -  by (simp add: int_aux_def)
   9.602 -
   9.603 -definition
   9.604 -  nat_aux :: "nat \<Rightarrow> int \<Rightarrow> nat" where
   9.605 -  "nat_aux n i = (n + nat i)"
   9.606 -
   9.607 -lemma [code]: "nat_aux n i = (if i <= 0 then n else nat_aux (Suc n) (i - 1))"
   9.608 -  -- {* tail recursive *}
   9.609 -  by (auto simp add: nat_aux_def nat_eq_iff linorder_not_le order_less_imp_le
   9.610 -    dest: zless_imp_add1_zle)
   9.611 -
   9.612 -lemma [code]: "nat i = nat_aux 0 i"
   9.613 -  by (simp add: nat_aux_def)
   9.614 -
   9.615 -lemma zero_is_num_zero [code func, code inline, symmetric, normal post]:
   9.616 -  "(0\<Colon>int) = number_of Numeral.Pls" 
   9.617 -  by simp
   9.618 -
   9.619 -lemma one_is_num_one [code func, code inline, symmetric, normal post]:
   9.620 -  "(1\<Colon>int) = number_of (Numeral.Pls BIT bit.B1)" 
   9.621 -  by simp 
   9.622 -
   9.623 -code_modulename SML
   9.624 -  IntDef Integer
   9.625 -
   9.626 -code_modulename OCaml
   9.627 -  IntDef Integer
   9.628 -
   9.629 -code_modulename Haskell
   9.630 -  IntDef Integer
   9.631 -
   9.632 -code_modulename SML
   9.633 -  Numeral Integer
   9.634 -
   9.635 -code_modulename OCaml
   9.636 -  Numeral Integer
   9.637 -
   9.638 -code_modulename Haskell
   9.639 -  Numeral Integer
   9.640 -
   9.641 -(*FIXME: the IntInf.fromInt below hides a dependence on fixed-precision ints!*)
   9.642 -
   9.643 -types_code
   9.644 -  "int" ("int")
   9.645 -attach (term_of) {*
   9.646 -val term_of_int = HOLogic.mk_number HOLogic.intT o IntInf.fromInt;
   9.647 -*}
   9.648 -attach (test) {*
   9.649 -fun gen_int i = one_of [~1, 1] * random_range 0 i;
   9.650 -*}
   9.651 -
   9.652 -setup {*
   9.653 -let
   9.654 -
   9.655 -fun number_of_codegen thy defs gr dep module b (Const (@{const_name Numeral.number_of}, Type ("fun", [_, T])) $ t) =
   9.656 -      if T = HOLogic.intT then
   9.657 -        (SOME (fst (Codegen.invoke_tycodegen thy defs dep module false (gr, T)),
   9.658 -          (Pretty.str o IntInf.toString o HOLogic.dest_numeral) t) handle TERM _ => NONE)
   9.659 -      else if T = HOLogic.natT then
   9.660 -        SOME (Codegen.invoke_codegen thy defs dep module b (gr,
   9.661 -          Const ("IntDef.nat", HOLogic.intT --> HOLogic.natT) $
   9.662 -            (Const (@{const_name Numeral.number_of}, HOLogic.intT --> HOLogic.intT) $ t)))
   9.663 -      else NONE
   9.664 -  | number_of_codegen _ _ _ _ _ _ _ = NONE;
   9.665 -
   9.666 -in
   9.667 -
   9.668 -Codegen.add_codegen "number_of_codegen" number_of_codegen
   9.669 -
   9.670 -end
   9.671 -*}
   9.672 -
   9.673 -consts_code
   9.674 -  "0 :: int"                   ("0")
   9.675 -  "1 :: int"                   ("1")
   9.676 -  "uminus :: int => int"       ("~")
   9.677 -  "op + :: int => int => int"  ("(_ +/ _)")
   9.678 -  "op * :: int => int => int"  ("(_ */ _)")
   9.679 -  "op \<le> :: int => int => bool" ("(_ <=/ _)")
   9.680 -  "op < :: int => int => bool" ("(_ </ _)")
   9.681 -
   9.682 -quickcheck_params [default_type = int]
   9.683 -
   9.684 -(*setup continues in theory Presburger*)
   9.685 -
   9.686 -hide (open) const Pls Min B0 B1 succ pred
   9.687 -
   9.688 -end
    10.1 --- a/src/HOL/Integ/int_arith1.ML	Thu May 31 18:16:51 2007 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,610 +0,0 @@
    10.4 -(*  Title:      HOL/Integ/int_arith1.ML
    10.5 -    ID:         $Id$
    10.6 -    Authors:    Larry Paulson and Tobias Nipkow
    10.7 -
    10.8 -Simprocs and decision procedure for linear arithmetic.
    10.9 -*)
   10.10 -
   10.11 -(** Misc ML bindings **)
   10.12 -
   10.13 -val succ_Pls = thm "succ_Pls";
   10.14 -val succ_Min = thm "succ_Min";
   10.15 -val succ_1 = thm "succ_1";
   10.16 -val succ_0 = thm "succ_0";
   10.17 -
   10.18 -val pred_Pls = thm "pred_Pls";
   10.19 -val pred_Min = thm "pred_Min";
   10.20 -val pred_1 = thm "pred_1";
   10.21 -val pred_0 = thm "pred_0";
   10.22 -
   10.23 -val minus_Pls = thm "minus_Pls";
   10.24 -val minus_Min = thm "minus_Min";
   10.25 -val minus_1 = thm "minus_1";
   10.26 -val minus_0 = thm "minus_0";
   10.27 -
   10.28 -val add_Pls = thm "add_Pls";
   10.29 -val add_Min = thm "add_Min";
   10.30 -val add_BIT_11 = thm "add_BIT_11";
   10.31 -val add_BIT_10 = thm "add_BIT_10";
   10.32 -val add_BIT_0 = thm "add_BIT_0";
   10.33 -val add_Pls_right = thm "add_Pls_right";
   10.34 -val add_Min_right = thm "add_Min_right";
   10.35 -
   10.36 -val mult_Pls = thm "mult_Pls";
   10.37 -val mult_Min = thm "mult_Min";
   10.38 -val mult_num1 = thm "mult_num1";
   10.39 -val mult_num0 = thm "mult_num0";
   10.40 -
   10.41 -val neg_def = thm "neg_def";
   10.42 -val iszero_def = thm "iszero_def";
   10.43 -
   10.44 -val number_of_succ = thm "number_of_succ";
   10.45 -val number_of_pred = thm "number_of_pred";
   10.46 -val number_of_minus = thm "number_of_minus";
   10.47 -val number_of_add = thm "number_of_add";
   10.48 -val diff_number_of_eq = thm "diff_number_of_eq";
   10.49 -val number_of_mult = thm "number_of_mult";
   10.50 -val double_number_of_BIT = thm "double_number_of_BIT";
   10.51 -val numeral_0_eq_0 = thm "numeral_0_eq_0";
   10.52 -val numeral_1_eq_1 = thm "numeral_1_eq_1";
   10.53 -val numeral_m1_eq_minus_1 = thm "numeral_m1_eq_minus_1";
   10.54 -val mult_minus1 = thm "mult_minus1";
   10.55 -val mult_minus1_right = thm "mult_minus1_right";
   10.56 -val minus_number_of_mult = thm "minus_number_of_mult";
   10.57 -val zero_less_nat_eq = thm "zero_less_nat_eq";
   10.58 -val eq_number_of_eq = thm "eq_number_of_eq";
   10.59 -val iszero_number_of_Pls = thm "iszero_number_of_Pls";
   10.60 -val nonzero_number_of_Min = thm "nonzero_number_of_Min";
   10.61 -val iszero_number_of_BIT = thm "iszero_number_of_BIT";
   10.62 -val iszero_number_of_0 = thm "iszero_number_of_0";
   10.63 -val iszero_number_of_1 = thm "iszero_number_of_1";
   10.64 -val less_number_of_eq_neg = thm "less_number_of_eq_neg";
   10.65 -val le_number_of_eq = thm "le_number_of_eq";
   10.66 -val not_neg_number_of_Pls = thm "not_neg_number_of_Pls";
   10.67 -val neg_number_of_Min = thm "neg_number_of_Min";
   10.68 -val neg_number_of_BIT = thm "neg_number_of_BIT";
   10.69 -val le_number_of_eq_not_less = thm "le_number_of_eq_not_less";
   10.70 -val abs_number_of = thm "abs_number_of";
   10.71 -val number_of_reorient = thm "number_of_reorient";
   10.72 -val add_number_of_left = thm "add_number_of_left";
   10.73 -val mult_number_of_left = thm "mult_number_of_left";
   10.74 -val add_number_of_diff1 = thm "add_number_of_diff1";
   10.75 -val add_number_of_diff2 = thm "add_number_of_diff2";
   10.76 -val less_iff_diff_less_0 = thm "less_iff_diff_less_0";
   10.77 -val eq_iff_diff_eq_0 = thm "eq_iff_diff_eq_0";
   10.78 -val le_iff_diff_le_0 = thm "le_iff_diff_le_0";
   10.79 -
   10.80 -val arith_extra_simps = thms "arith_extra_simps";
   10.81 -val arith_simps = thms "arith_simps";
   10.82 -val rel_simps = thms "rel_simps";
   10.83 -
   10.84 -val zless_imp_add1_zle = thm "zless_imp_add1_zle";
   10.85 -
   10.86 -val combine_common_factor = thm "combine_common_factor";
   10.87 -val eq_add_iff1 = thm "eq_add_iff1";
   10.88 -val eq_add_iff2 = thm "eq_add_iff2";
   10.89 -val less_add_iff1 = thm "less_add_iff1";
   10.90 -val less_add_iff2 = thm "less_add_iff2";
   10.91 -val le_add_iff1 = thm "le_add_iff1";
   10.92 -val le_add_iff2 = thm "le_add_iff2";
   10.93 -
   10.94 -val arith_special = thms "arith_special";
   10.95 -
   10.96 -structure Int_Numeral_Base_Simprocs =
   10.97 -  struct
   10.98 -  fun prove_conv tacs ctxt (_: thm list) (t, u) =
   10.99 -    if t aconv u then NONE
  10.100 -    else
  10.101 -      let val eq = HOLogic.mk_Trueprop (HOLogic.mk_eq (t, u))
  10.102 -      in SOME (Goal.prove ctxt [] [] eq (K (EVERY tacs))) end
  10.103 -
  10.104 -  fun prove_conv_nohyps tacs sg = prove_conv tacs sg [];
  10.105 -
  10.106 -  fun prep_simproc (name, pats, proc) =
  10.107 -    Simplifier.simproc (the_context()) name pats proc;
  10.108 -
  10.109 -  fun is_numeral (Const(@{const_name Numeral.number_of}, _) $ w) = true
  10.110 -    | is_numeral _ = false
  10.111 -
  10.112 -  fun simplify_meta_eq f_number_of_eq f_eq =
  10.113 -      mk_meta_eq ([f_eq, f_number_of_eq] MRS trans)
  10.114 -
  10.115 -  (*reorientation simprules using ==, for the following simproc*)
  10.116 -  val meta_zero_reorient = zero_reorient RS eq_reflection
  10.117 -  val meta_one_reorient = one_reorient RS eq_reflection
  10.118 -  val meta_number_of_reorient = number_of_reorient RS eq_reflection
  10.119 -
  10.120 -  (*reorientation simplification procedure: reorients (polymorphic) 
  10.121 -    0 = x, 1 = x, nnn = x provided x isn't 0, 1 or a numeral.*)
  10.122 -  fun reorient_proc sg _ (_ $ t $ u) =
  10.123 -    case u of
  10.124 -	Const(@{const_name HOL.zero}, _) => NONE
  10.125 -      | Const(@{const_name HOL.one}, _) => NONE
  10.126 -      | Const(@{const_name Numeral.number_of}, _) $ _ => NONE
  10.127 -      | _ => SOME (case t of
  10.128 -		  Const(@{const_name HOL.zero}, _) => meta_zero_reorient
  10.129 -		| Const(@{const_name HOL.one}, _) => meta_one_reorient
  10.130 -		| Const(@{const_name Numeral.number_of}, _) $ _ => meta_number_of_reorient)
  10.131 -
  10.132 -  val reorient_simproc = 
  10.133 -      prep_simproc ("reorient_simproc", ["0=x", "1=x", "number_of w = x"], reorient_proc)
  10.134 -
  10.135 -  end;
  10.136 -
  10.137 -
  10.138 -Addsimprocs [Int_Numeral_Base_Simprocs.reorient_simproc];
  10.139 -
  10.140 -
  10.141 -structure Int_Numeral_Simprocs =
  10.142 -struct
  10.143 -
  10.144 -(*Maps 0 to Numeral0 and 1 to Numeral1 so that arithmetic in Int_Numeral_Base_Simprocs
  10.145 -  isn't complicated by the abstract 0 and 1.*)
  10.146 -val numeral_syms = [numeral_0_eq_0 RS sym, numeral_1_eq_1 RS sym];
  10.147 -
  10.148 -(** New term ordering so that AC-rewriting brings numerals to the front **)
  10.149 -
  10.150 -(*Order integers by absolute value and then by sign. The standard integer
  10.151 -  ordering is not well-founded.*)
  10.152 -fun num_ord (i,j) =
  10.153 -      (case IntInf.compare (IntInf.abs i, IntInf.abs j) of
  10.154 -            EQUAL => int_ord (IntInf.sign i, IntInf.sign j) 
  10.155 -          | ord => ord);
  10.156 -
  10.157 -(*This resembles Term.term_ord, but it puts binary numerals before other
  10.158 -  non-atomic terms.*)
  10.159 -local open Term 
  10.160 -in 
  10.161 -fun numterm_ord (Abs (_, T, t), Abs(_, U, u)) =
  10.162 -      (case numterm_ord (t, u) of EQUAL => typ_ord (T, U) | ord => ord)
  10.163 -  | numterm_ord
  10.164 -     (Const(@{const_name Numeral.number_of}, _) $ v, Const(@{const_name Numeral.number_of}, _) $ w) =
  10.165 -     num_ord (HOLogic.dest_numeral v, HOLogic.dest_numeral w)
  10.166 -  | numterm_ord (Const(@{const_name Numeral.number_of}, _) $ _, _) = LESS
  10.167 -  | numterm_ord (_, Const(@{const_name Numeral.number_of}, _) $ _) = GREATER
  10.168 -  | numterm_ord (t, u) =
  10.169 -      (case int_ord (size_of_term t, size_of_term u) of
  10.170 -        EQUAL =>
  10.171 -          let val (f, ts) = strip_comb t and (g, us) = strip_comb u in
  10.172 -            (case hd_ord (f, g) of EQUAL => numterms_ord (ts, us) | ord => ord)
  10.173 -          end
  10.174 -      | ord => ord)
  10.175 -and numterms_ord (ts, us) = list_ord numterm_ord (ts, us)
  10.176 -end;
  10.177 -
  10.178 -fun numtermless tu = (numterm_ord tu = LESS);
  10.179 -
  10.180 -(*Defined in this file, but perhaps needed only for Int_Numeral_Base_Simprocs of type nat.*)
  10.181 -val num_ss = HOL_ss settermless numtermless;
  10.182 -
  10.183 -
  10.184 -(** Utilities **)
  10.185 -
  10.186 -fun mk_number T n = HOLogic.number_of_const T $ HOLogic.mk_numeral n;
  10.187 -
  10.188 -fun find_first_numeral past (t::terms) =
  10.189 -        ((snd (HOLogic.dest_number t), rev past @ terms)
  10.190 -         handle TERM _ => find_first_numeral (t::past) terms)
  10.191 -  | find_first_numeral past [] = raise TERM("find_first_numeral", []);
  10.192 -
  10.193 -val mk_plus = HOLogic.mk_binop @{const_name HOL.plus};
  10.194 -
  10.195 -fun mk_minus t = 
  10.196 -  let val T = Term.fastype_of t
  10.197 -  in Const (@{const_name HOL.uminus}, T --> T) $ t
  10.198 -  end;
  10.199 -
  10.200 -(*Thus mk_sum[t] yields t+0; longer sums don't have a trailing zero*)
  10.201 -fun mk_sum T []        = mk_number T 0
  10.202 -  | mk_sum T [t,u]     = mk_plus (t, u)
  10.203 -  | mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
  10.204 -
  10.205 -(*this version ALWAYS includes a trailing zero*)
  10.206 -fun long_mk_sum T []        = mk_number T 0
  10.207 -  | long_mk_sum T (t :: ts) = mk_plus (t, mk_sum T ts);
  10.208 -
  10.209 -val dest_plus = HOLogic.dest_bin @{const_name HOL.plus} Term.dummyT;
  10.210 -
  10.211 -(*decompose additions AND subtractions as a sum*)
  10.212 -fun dest_summing (pos, Const (@{const_name HOL.plus}, _) $ t $ u, ts) =
  10.213 -        dest_summing (pos, t, dest_summing (pos, u, ts))
  10.214 -  | dest_summing (pos, Const (@{const_name HOL.minus}, _) $ t $ u, ts) =
  10.215 -        dest_summing (pos, t, dest_summing (not pos, u, ts))
  10.216 -  | dest_summing (pos, t, ts) =
  10.217 -        if pos then t::ts else mk_minus t :: ts;
  10.218 -
  10.219 -fun dest_sum t = dest_summing (true, t, []);
  10.220 -
  10.221 -val mk_diff = HOLogic.mk_binop @{const_name HOL.minus};
  10.222 -val dest_diff = HOLogic.dest_bin @{const_name HOL.minus} Term.dummyT;
  10.223 -
  10.224 -val mk_times = HOLogic.mk_binop @{const_name HOL.times};
  10.225 -
  10.226 -fun mk_prod T = 
  10.227 -  let val one = mk_number T 1
  10.228 -  fun mk [] = one
  10.229 -    | mk [t] = t
  10.230 -    | mk (t :: ts) = if t = one then mk ts else mk_times (t, mk ts)
  10.231 -  in mk end;
  10.232 -
  10.233 -(*This version ALWAYS includes a trailing one*)
  10.234 -fun long_mk_prod T []        = mk_number T 1
  10.235 -  | long_mk_prod T (t :: ts) = mk_times (t, mk_prod T ts);
  10.236 -
  10.237 -val dest_times = HOLogic.dest_bin @{const_name HOL.times} Term.dummyT;
  10.238 -
  10.239 -fun dest_prod t =
  10.240 -      let val (t,u) = dest_times t
  10.241 -      in  dest_prod t @ dest_prod u  end
  10.242 -      handle TERM _ => [t];
  10.243 -
  10.244 -(*DON'T do the obvious simplifications; that would create special cases*)
  10.245 -fun mk_coeff (k, t) = mk_times (mk_number (Term.fastype_of t) k, t);
  10.246 -
  10.247 -(*Express t as a product of (possibly) a numeral with other sorted terms*)
  10.248 -fun dest_coeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_coeff (~sign) t
  10.249 -  | dest_coeff sign t =
  10.250 -    let val ts = sort Term.term_ord (dest_prod t)
  10.251 -        val (n, ts') = find_first_numeral [] ts
  10.252 -                          handle TERM _ => (1, ts)
  10.253 -    in (sign*n, mk_prod (Term.fastype_of t) ts') end;
  10.254 -
  10.255 -(*Find first coefficient-term THAT MATCHES u*)
  10.256 -fun find_first_coeff past u [] = raise TERM("find_first_coeff", [])
  10.257 -  | find_first_coeff past u (t::terms) =
  10.258 -        let val (n,u') = dest_coeff 1 t
  10.259 -        in  if u aconv u' then (n, rev past @ terms)
  10.260 -                          else find_first_coeff (t::past) u terms
  10.261 -        end
  10.262 -        handle TERM _ => find_first_coeff (t::past) u terms;
  10.263 -
  10.264 -(*Fractions as pairs of ints. Can't use Rat.rat because the representation
  10.265 -  needs to preserve negative values in the denominator.*)
  10.266 -fun mk_frac (p, q : IntInf.int) = if q = 0 then raise Div else (p, q);
  10.267 -
  10.268 -(*Don't reduce fractions; sums must be proved by rule add_frac_eq.
  10.269 -  Fractions are reduced later by the cancel_numeral_factor simproc.*)
  10.270 -fun add_frac ((p1 : IntInf.int, q1 : IntInf.int), (p2, q2)) = (p1 * q2 + p2 * q1, q1 * q2);
  10.271 -
  10.272 -val mk_divide = HOLogic.mk_binop @{const_name HOL.divide};
  10.273 -
  10.274 -(*Build term (p / q) * t*)
  10.275 -fun mk_fcoeff ((p, q), t) =
  10.276 -  let val T = Term.fastype_of t
  10.277 -  in  mk_times (mk_divide (mk_number T p, mk_number T q), t) end;
  10.278 -
  10.279 -(*Express t as a product of a fraction with other sorted terms*)
  10.280 -fun dest_fcoeff sign (Const (@{const_name HOL.uminus}, _) $ t) = dest_fcoeff (~sign) t
  10.281 -  | dest_fcoeff sign (Const (@{const_name HOL.divide}, _) $ t $ u) =
  10.282 -    let val (p, t') = dest_coeff sign t
  10.283 -        val (q, u') = dest_coeff 1 u
  10.284 -    in  (mk_frac (p, q), mk_divide (t', u')) end
  10.285 -  | dest_fcoeff sign t =
  10.286 -    let val (p, t') = dest_coeff sign t
  10.287 -        val T = Term.fastype_of t
  10.288 -    in  (mk_frac (p, 1), mk_divide (t', mk_number T 1)) end;
  10.289 -
  10.290 -
  10.291 -(*Simplify Numeral0+n, n+Numeral0, Numeral1*n, n*Numeral1*)
  10.292 -val add_0s =  thms "add_0s";
  10.293 -val mult_1s = thms "mult_1s";
  10.294 -
  10.295 -(*Simplify inverse Numeral1, a/Numeral1*)
  10.296 -val inverse_1s = [@{thm inverse_numeral_1}];
  10.297 -val divide_1s = [@{thm divide_numeral_1}];
  10.298 -
  10.299 -(*To perform binary arithmetic.  The "left" rewriting handles patterns
  10.300 -  created by the Int_Numeral_Base_Simprocs, such as 3 * (5 * x). *)
  10.301 -val simps = [numeral_0_eq_0 RS sym, numeral_1_eq_1 RS sym,
  10.302 -                 add_number_of_left, mult_number_of_left] @
  10.303 -                arith_simps @ rel_simps;
  10.304 -
  10.305 -(*Binary arithmetic BUT NOT ADDITION since it may collapse adjacent terms
  10.306 -  during re-arrangement*)
  10.307 -val non_add_simps =
  10.308 -  subtract Thm.eq_thm [add_number_of_left, number_of_add RS sym] simps;
  10.309 -
  10.310 -(*To evaluate binary negations of coefficients*)
  10.311 -val minus_simps = [numeral_m1_eq_minus_1 RS sym, number_of_minus RS sym,
  10.312 -                   minus_1, minus_0, minus_Pls, minus_Min,
  10.313 -                   pred_1, pred_0, pred_Pls, pred_Min];
  10.314 -
  10.315 -(*To let us treat subtraction as addition*)
  10.316 -val diff_simps = [@{thm diff_minus}, @{thm minus_add_distrib}, @{thm minus_minus}];
  10.317 -
  10.318 -(*To let us treat division as multiplication*)
  10.319 -val divide_simps = [@{thm divide_inverse}, @{thm inverse_mult_distrib}, @{thm inverse_inverse_eq}];
  10.320 -
  10.321 -(*push the unary minus down: - x * y = x * - y *)
  10.322 -val minus_mult_eq_1_to_2 =
  10.323 -    [@{thm minus_mult_left} RS sym, @{thm minus_mult_right}] MRS trans |> standard;
  10.324 -
  10.325 -(*to extract again any uncancelled minuses*)
  10.326 -val minus_from_mult_simps =
  10.327 -    [@{thm minus_minus}, @{thm minus_mult_left} RS sym, @{thm minus_mult_right} RS sym];
  10.328 -
  10.329 -(*combine unary minus with numeric literals, however nested within a product*)
  10.330 -val mult_minus_simps =
  10.331 -    [@{thm mult_assoc}, @{thm minus_mult_left}, minus_mult_eq_1_to_2];
  10.332 -
  10.333 -(*Apply the given rewrite (if present) just once*)
  10.334 -fun trans_tac NONE      = all_tac
  10.335 -  | trans_tac (SOME th) = ALLGOALS (rtac (th RS trans));
  10.336 -
  10.337 -fun simplify_meta_eq rules =
  10.338 -  let val ss0 = HOL_basic_ss addeqcongs [eq_cong2] addsimps rules
  10.339 -  in fn ss => simplify (Simplifier.inherit_context ss ss0) o mk_meta_eq end
  10.340 -
  10.341 -structure CancelNumeralsCommon =
  10.342 -  struct
  10.343 -  val mk_sum            = mk_sum
  10.344 -  val dest_sum          = dest_sum
  10.345 -  val mk_coeff          = mk_coeff
  10.346 -  val dest_coeff        = dest_coeff 1
  10.347 -  val find_first_coeff  = find_first_coeff []
  10.348 -  val trans_tac         = fn _ => trans_tac
  10.349 -
  10.350 -  val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
  10.351 -    diff_simps @ minus_simps @ add_ac
  10.352 -  val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
  10.353 -  val norm_ss3 = num_ss addsimps minus_from_mult_simps @ add_ac @ mult_ac
  10.354 -  fun norm_tac ss =
  10.355 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
  10.356 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
  10.357 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
  10.358 -
  10.359 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
  10.360 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
  10.361 -  val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s)
  10.362 -  end;
  10.363 -
  10.364 -
  10.365 -structure EqCancelNumerals = CancelNumeralsFun
  10.366 - (open CancelNumeralsCommon
  10.367 -  val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
  10.368 -  val mk_bal   = HOLogic.mk_eq
  10.369 -  val dest_bal = HOLogic.dest_bin "op =" Term.dummyT
  10.370 -  val bal_add1 = eq_add_iff1 RS trans
  10.371 -  val bal_add2 = eq_add_iff2 RS trans
  10.372 -);
  10.373 -
  10.374 -structure LessCancelNumerals = CancelNumeralsFun
  10.375 - (open CancelNumeralsCommon
  10.376 -  val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
  10.377 -  val mk_bal   = HOLogic.mk_binrel @{const_name Orderings.less}
  10.378 -  val dest_bal = HOLogic.dest_bin @{const_name Orderings.less} Term.dummyT
  10.379 -  val bal_add1 = less_add_iff1 RS trans
  10.380 -  val bal_add2 = less_add_iff2 RS trans
  10.381 -);
  10.382 -
  10.383 -structure LeCancelNumerals = CancelNumeralsFun
  10.384 - (open CancelNumeralsCommon
  10.385 -  val prove_conv = Int_Numeral_Base_Simprocs.prove_conv
  10.386 -  val mk_bal   = HOLogic.mk_binrel @{const_name Orderings.less_eq}
  10.387 -  val dest_bal = HOLogic.dest_bin @{const_name Orderings.less_eq} Term.dummyT
  10.388 -  val bal_add1 = le_add_iff1 RS trans
  10.389 -  val bal_add2 = le_add_iff2 RS trans
  10.390 -);
  10.391 -
  10.392 -val cancel_numerals =
  10.393 -  map Int_Numeral_Base_Simprocs.prep_simproc
  10.394 -   [("inteq_cancel_numerals",
  10.395 -     ["(l::'a::number_ring) + m = n",
  10.396 -      "(l::'a::number_ring) = m + n",
  10.397 -      "(l::'a::number_ring) - m = n",
  10.398 -      "(l::'a::number_ring) = m - n",
  10.399 -      "(l::'a::number_ring) * m = n",
  10.400 -      "(l::'a::number_ring) = m * n"],
  10.401 -     K EqCancelNumerals.proc),
  10.402 -    ("intless_cancel_numerals",
  10.403 -     ["(l::'a::{ordered_idom,number_ring}) + m < n",
  10.404 -      "(l::'a::{ordered_idom,number_ring}) < m + n",
  10.405 -      "(l::'a::{ordered_idom,number_ring}) - m < n",
  10.406 -      "(l::'a::{ordered_idom,number_ring}) < m - n",
  10.407 -      "(l::'a::{ordered_idom,number_ring}) * m < n",
  10.408 -      "(l::'a::{ordered_idom,number_ring}) < m * n"],
  10.409 -     K LessCancelNumerals.proc),
  10.410 -    ("intle_cancel_numerals",
  10.411 -     ["(l::'a::{ordered_idom,number_ring}) + m <= n",
  10.412 -      "(l::'a::{ordered_idom,number_ring}) <= m + n",
  10.413 -      "(l::'a::{ordered_idom,number_ring}) - m <= n",
  10.414 -      "(l::'a::{ordered_idom,number_ring}) <= m - n",
  10.415 -      "(l::'a::{ordered_idom,number_ring}) * m <= n",
  10.416 -      "(l::'a::{ordered_idom,number_ring}) <= m * n"],
  10.417 -     K LeCancelNumerals.proc)];
  10.418 -
  10.419 -
  10.420 -structure CombineNumeralsData =
  10.421 -  struct
  10.422 -  type coeff            = IntInf.int
  10.423 -  val iszero            = (fn x : IntInf.int => x = 0)
  10.424 -  val add               = IntInf.+
  10.425 -  val mk_sum            = long_mk_sum    (*to work for e.g. 2*x + 3*x *)
  10.426 -  val dest_sum          = dest_sum
  10.427 -  val mk_coeff          = mk_coeff
  10.428 -  val dest_coeff        = dest_coeff 1
  10.429 -  val left_distrib      = combine_common_factor RS trans
  10.430 -  val prove_conv        = Int_Numeral_Base_Simprocs.prove_conv_nohyps
  10.431 -  val trans_tac         = fn _ => trans_tac
  10.432 -
  10.433 -  val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
  10.434 -    diff_simps @ minus_simps @ add_ac
  10.435 -  val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
  10.436 -  val norm_ss3 = num_ss addsimps minus_from_mult_simps @ add_ac @ mult_ac
  10.437 -  fun norm_tac ss =
  10.438 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
  10.439 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
  10.440 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
  10.441 -
  10.442 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps
  10.443 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
  10.444 -  val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s)
  10.445 -  end;
  10.446 -
  10.447 -structure CombineNumerals = CombineNumeralsFun(CombineNumeralsData);
  10.448 -
  10.449 -(*Version for fields, where coefficients can be fractions*)
  10.450 -structure FieldCombineNumeralsData =
  10.451 -  struct
  10.452 -  type coeff            = IntInf.int * IntInf.int
  10.453 -  val iszero            = (fn (p : IntInf.int, q) => p = 0)
  10.454 -  val add               = add_frac
  10.455 -  val mk_sum            = long_mk_sum
  10.456 -  val dest_sum          = dest_sum
  10.457 -  val mk_coeff          = mk_fcoeff
  10.458 -  val dest_coeff        = dest_fcoeff 1
  10.459 -  val left_distrib      = combine_common_factor RS trans
  10.460 -  val prove_conv        = Int_Numeral_Base_Simprocs.prove_conv_nohyps
  10.461 -  val trans_tac         = fn _ => trans_tac
  10.462 -
  10.463 -  val norm_ss1 = num_ss addsimps numeral_syms @ add_0s @ mult_1s @
  10.464 -    inverse_1s @ divide_simps @ diff_simps @ minus_simps @ add_ac
  10.465 -  val norm_ss2 = num_ss addsimps non_add_simps @ mult_minus_simps
  10.466 -  val norm_ss3 = num_ss addsimps minus_from_mult_simps @ add_ac @ mult_ac
  10.467 -  fun norm_tac ss =
  10.468 -    ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss1))
  10.469 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss2))
  10.470 -    THEN ALLGOALS (simp_tac (Simplifier.inherit_context ss norm_ss3))
  10.471 -
  10.472 -  val numeral_simp_ss = HOL_ss addsimps add_0s @ simps @ [@{thm add_frac_eq}]
  10.473 -  fun numeral_simp_tac ss = ALLGOALS (simp_tac (Simplifier.inherit_context ss numeral_simp_ss))
  10.474 -  val simplify_meta_eq = simplify_meta_eq (add_0s @ mult_1s @ divide_1s)
  10.475 -  end;
  10.476 -
  10.477 -structure FieldCombineNumerals = CombineNumeralsFun(FieldCombineNumeralsData);
  10.478 -
  10.479 -val combine_numerals =
  10.480 -  Int_Numeral_Base_Simprocs.prep_simproc
  10.481 -    ("int_combine_numerals", 
  10.482 -     ["(i::'a::number_ring) + j", "(i::'a::number_ring) - j"], 
  10.483 -     K CombineNumerals.proc);
  10.484 -
  10.485 -val field_combine_numerals =
  10.486 -  Int_Numeral_Base_Simprocs.prep_simproc
  10.487 -    ("field_combine_numerals", 
  10.488 -     ["(i::'a::{number_ring,field,division_by_zero}) + j",
  10.489 -      "(i::'a::{number_ring,field,division_by_zero}) - j"], 
  10.490 -     K FieldCombineNumerals.proc);
  10.491 -
  10.492 -end;
  10.493 -
  10.494 -Addsimprocs Int_Numeral_Simprocs.cancel_numerals;
  10.495 -Addsimprocs [Int_Numeral_Simprocs.combine_numerals];
  10.496 -Addsimprocs [Int_Numeral_Simprocs.field_combine_numerals];