1 (* Title: HOL/Integ/IntArith.thy
3 Authors: Larry Paulson and Tobias Nipkow
6 header {* Integer arithmetic *}
9 files ("int_arith1.ML"):
11 text{*Duplicate: can't understand why it's necessary*}
12 declare numeral_0_eq_0 [simp]
14 subsection{*Instantiating Binary Arithmetic for the Integers*}
19 primrec (*the type constraint is essential!*)
20 number_of_Pls: "number_of bin.Pls = 0"
21 number_of_Min: "number_of bin.Min = - (1::int)"
22 number_of_BIT: "number_of(w BIT x) = (if x then 1 else 0) +
23 (number_of w) + (number_of w)"
25 declare number_of_Pls [simp del]
26 number_of_Min [simp del]
27 number_of_BIT [simp del]
29 instance int :: number_ring
31 show "Numeral0 = (0::int)" by (rule number_of_Pls)
32 show "-1 = - (1::int)" by (rule number_of_Min)
33 fix w :: bin and x :: bool
34 show "(number_of (w BIT x) :: int) =
35 (if x then 1 else 0) + number_of w + number_of w"
36 by (rule number_of_BIT)
41 subsection{*Inequality Reasoning for the Arithmetic Simproc*}
43 lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)"
46 lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)"
49 lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)"
52 lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)"
55 text{*Theorem lists for the cancellation simprocs. The use of binary numerals
56 for 0 and 1 reduces the number of special cases.*}
58 lemmas add_0s = add_numeral_0 add_numeral_0_right
59 lemmas mult_1s = mult_numeral_1 mult_numeral_1_right
60 mult_minus1 mult_minus1_right
63 subsection{*Special Arithmetic Rules for Abstract 0 and 1*}
65 text{*Arithmetic computations are defined for binary literals, which leaves 0
66 and 1 as special cases. Addition already has rules for 0, but not 1.
67 Multiplication and unary minus already have rules for both 0 and 1.*}
70 lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'"
74 lemmas add_number_of_eq = number_of_add [symmetric]
76 text{*Allow 1 on either or both sides*}
77 lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)"
78 by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq)
82 binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard]
83 binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard]
85 text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*}
87 binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard]
88 binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard]
90 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
92 binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard]
93 binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard]
94 binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard]
95 binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard]
97 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
99 binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard]
100 binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard]
101 binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard]
102 binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard]
104 text{*Allow 0 or 1 on either side with a binary numeral on the other*}
106 binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard]
107 binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard]
108 binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard]
109 binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard]
111 lemmas arith_special =
112 add_special diff_special eq_special less_special le_special
116 setup int_arith_setup
119 subsection{*Lemmas About Small Numerals*}
121 lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)"
123 have "(of_int -1 :: 'a) = of_int (- 1)" by simp
124 also have "... = - of_int 1" by (simp only: of_int_minus)
125 also have "... = -1" by simp
126 finally show ?thesis .
129 lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_idom,number_ring})"
130 by (simp add: abs_if)
132 lemma abs_power_minus_one [simp]:
133 "abs(-1 ^ n) = (1::'a::{ordered_idom,number_ring,ringpower})"
134 by (simp add: power_abs)
136 lemma of_int_number_of_eq:
137 "of_int (number_of v) = (number_of v :: 'a :: number_ring)"
139 apply (simp_all only: number_of of_int_add, simp_all)
142 text{*Lemmas for specialist use, NOT as default simprules*}
143 lemma mult_2: "2 * z = (z+z::'a::number_ring)"
145 have "2*z = (1 + 1)*z" by simp
146 also have "... = z+z" by (simp add: left_distrib)
147 finally show ?thesis .
150 lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)"
151 by (subst mult_commute, rule mult_2)
154 subsection{*More Inequality Reasoning*}
156 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)"
159 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)"
162 lemma zle_diff1_eq [simp]: "(w \<le> z - (1::int)) = (w<z)"
165 lemma zle_add1_eq_le [simp]: "(w < z + (1::int)) = (w\<le>z)"
168 lemma int_one_le_iff_zero_less: "((1::int) \<le> z) = (0 < z)"
172 subsection{*The Functions @{term nat} and @{term int}*}
174 text{*Simplify the terms @{term "int 0"}, @{term "int(Suc 0)"} and
176 declare Zero_int_def [symmetric, simp]
177 declare One_int_def [symmetric, simp]
179 text{*cooper.ML refers to this theorem*}
180 lemmas diff_int_def_symmetric = diff_int_def [symmetric, simp]
182 lemma nat_0: "nat 0 = 0"
183 by (simp add: nat_eq_iff)
185 lemma nat_1: "nat 1 = Suc 0"
186 by (subst nat_eq_iff, simp)
188 lemma nat_2: "nat 2 = Suc (Suc 0)"
189 by (subst nat_eq_iff, simp)
191 text{*This simplifies expressions of the form @{term "int n = z"} where
192 z is an integer literal.*}
193 declare int_eq_iff [of _ "number_of v", standard, simp]
195 lemma split_nat [arith_split]:
196 "P(nat(i::int)) = ((\<forall>n. i = int n \<longrightarrow> P n) & (i < 0 \<longrightarrow> P 0))"
197 (is "?P = (?L & ?R)")
198 proof (cases "i < 0")
199 case True thus ?thesis by simp
204 assume ?P thus ?L using False by clarsimp
206 assume ?L thus ?P using False by simp
208 with False show ?thesis by simp
212 (*Analogous to zadd_int*)
213 lemma zdiff_int: "n \<le> m ==> int m - int n = int (m-n)"
214 by (induct m n rule: diff_induct, simp_all)
216 lemma nat_mult_distrib: "(0::int) \<le> z ==> nat (z*z') = nat z * nat z'"
217 apply (case_tac "0 \<le> z'")
218 apply (rule inj_int [THEN injD])
219 apply (simp add: zmult_int [symmetric] zero_le_mult_iff)
220 apply (simp add: mult_le_0_iff)
223 lemma nat_mult_distrib_neg: "z \<le> (0::int) ==> nat(z*z') = nat(-z) * nat(-z')"
225 apply (rule_tac [2] nat_mult_distrib, auto)
228 lemma nat_abs_mult_distrib: "nat (abs (w * z)) = nat (abs w) * nat (abs z)"
229 apply (case_tac "z=0 | w=0")
230 apply (auto simp add: zabs_def nat_mult_distrib [symmetric]
231 nat_mult_distrib_neg [symmetric] mult_less_0_iff)
235 subsubsection "Induction principles for int"
237 (* `set:int': dummy construction *)
238 theorem int_ge_induct[case_names base step,induct set:int]:
239 assumes ge: "k \<le> (i::int)" and
241 step: "\<And>i. \<lbrakk>k \<le> i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
244 { fix n have "\<And>i::int. n = nat(i-k) \<Longrightarrow> k \<le> i \<Longrightarrow> P i"
247 hence "i = k" by arith
248 thus "P i" using base by simp
251 hence "n = nat((i - 1) - k)" by arith
253 have ki1: "k \<le> i - 1" using Suc.prems by arith
255 have "P(i - 1)" by(rule Suc.hyps)
256 from step[OF ki1 this] show ?case by simp
259 with ge show ?thesis by fast
262 (* `set:int': dummy construction *)
263 theorem int_gr_induct[case_names base step,induct set:int]:
264 assumes gr: "k < (i::int)" and
266 step: "\<And>i. \<lbrakk>k < i; P i\<rbrakk> \<Longrightarrow> P(i+1)"
268 apply(rule int_ge_induct[of "k + 1"])
271 apply (rule step, simp+)
274 theorem int_le_induct[consumes 1,case_names base step]:
275 assumes le: "i \<le> (k::int)" and
277 step: "\<And>i. \<lbrakk>i \<le> k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
280 { fix n have "\<And>i::int. n = nat(k-i) \<Longrightarrow> i \<le> k \<Longrightarrow> P i"
283 hence "i = k" by arith
284 thus "P i" using base by simp
287 hence "n = nat(k - (i+1))" by arith
289 have ki1: "i + 1 \<le> k" using Suc.prems by arith
291 have "P(i+1)" by(rule Suc.hyps)
292 from step[OF ki1 this] show ?case by simp
295 with le show ?thesis by fast
298 theorem int_less_induct [consumes 1,case_names base step]:
299 assumes less: "(i::int) < k" and
301 step: "\<And>i. \<lbrakk>i < k; P i\<rbrakk> \<Longrightarrow> P(i - 1)"
303 apply(rule int_le_induct[of _ "k - 1"])
304 using less apply arith
306 apply (rule step, simp+)
309 subsection{*Intermediate value theorems*}
312 "(\<forall>i<n::nat. abs(f(i+1) - f i) \<le> 1) -->
313 f 0 \<le> k --> k \<le> f n --> (\<exists>i \<le> n. f i = (k::int))"
314 apply (induct_tac "n", simp)
316 apply (erule impE, simp)
317 apply (erule_tac x = n in allE, simp)
318 apply (case_tac "k = f (n+1) ")
321 apply (simp add: zabs_def split add: split_if_asm)
322 apply (blast intro: le_SucI)
325 lemmas nat0_intermed_int_val = int_val_lemma [rule_format (no_asm)]
327 lemma nat_intermed_int_val:
328 "[| \<forall>i. m \<le> i & i < n --> abs(f(i + 1::nat) - f i) \<le> 1; m < n;
329 f m \<le> k; k \<le> f n |] ==> ? i. m \<le> i & i \<le> n & f i = (k::int)"
330 apply (cut_tac n = "n-m" and f = "%i. f (i+m) " and k = k
335 apply (erule_tac x = "i+m" in allE, arith)
337 apply (rule_tac x = "i+m" in exI, arith)
341 subsection{*Products and 1, by T. M. Rasmussen*}
343 lemma zmult_eq_self_iff: "(m = m*(n::int)) = (n = 1 | m = 0)"
345 apply (subgoal_tac "m*1 = m*n")
346 apply (drule mult_cancel_left [THEN iffD1], auto)
350 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)"
352 apply (case_tac "m=1")
353 apply (case_tac [2] "n=1")
354 apply (case_tac [4] "m=1")
355 apply (case_tac [5] "n=1", auto)
356 apply (tactic"distinct_subgoals_tac")
357 apply (subgoal_tac "1<m*n", simp)
358 apply (rule less_1_mult, arith)
359 apply (subgoal_tac "0<n", arith)
360 apply (subgoal_tac "0<m*n")
361 apply (drule zero_less_mult_iff [THEN iffD1], auto)
364 lemma zmult_eq_1_iff: "(m*n = (1::int)) = ((m = 1 & n = 1) | (m = -1 & n = -1))"
365 apply (case_tac "0<m")
366 apply (simp add: pos_zmult_eq_1_iff)
367 apply (case_tac "m=0")
368 apply (simp del: number_of_reorient)
369 apply (subgoal_tac "0 < -m")
370 apply (drule_tac n = "-n" in pos_zmult_eq_1_iff, auto)
377 val zle_diff1_eq = thm "zle_diff1_eq";
378 val zle_add1_eq_le = thm "zle_add1_eq_le";
379 val nonneg_eq_int = thm "nonneg_eq_int";
380 val abs_minus_one = thm "abs_minus_one";
381 val of_int_number_of_eq = thm"of_int_number_of_eq";
382 val nat_eq_iff = thm "nat_eq_iff";
383 val nat_eq_iff2 = thm "nat_eq_iff2";
384 val nat_less_iff = thm "nat_less_iff";
385 val int_eq_iff = thm "int_eq_iff";
386 val nat_0 = thm "nat_0";
387 val nat_1 = thm "nat_1";
388 val nat_2 = thm "nat_2";
389 val nat_less_eq_zless = thm "nat_less_eq_zless";
390 val nat_le_eq_zle = thm "nat_le_eq_zle";
392 val nat_intermed_int_val = thm "nat_intermed_int_val";
393 val zmult_eq_self_iff = thm "zmult_eq_self_iff";
394 val pos_zmult_eq_1_iff = thm "pos_zmult_eq_1_iff";
395 val zmult_eq_1_iff = thm "zmult_eq_1_iff";
396 val nat_add_distrib = thm "nat_add_distrib";
397 val nat_diff_distrib = thm "nat_diff_distrib";
398 val nat_mult_distrib = thm "nat_mult_distrib";
399 val nat_mult_distrib_neg = thm "nat_mult_distrib_neg";
400 val nat_abs_mult_distrib = thm "nat_abs_mult_distrib";