6 header {* Integer arithmetic *} |
6 header {* Integer arithmetic *} |
7 |
7 |
8 theory IntArith = Bin |
8 theory IntArith = Bin |
9 files ("int_arith1.ML"): |
9 files ("int_arith1.ML"): |
10 |
10 |
|
11 text{*Duplicate: can't understand why it's necessary*} |
|
12 declare numeral_0_eq_0 [simp] |
|
13 |
|
14 subsection{*Instantiating Binary Arithmetic for the Integers*} |
|
15 |
|
16 instance |
|
17 int :: number .. |
|
18 |
|
19 primrec (*the type constraint is essential!*) |
|
20 number_of_Pls: "number_of bin.Pls = 0" |
|
21 number_of_Min: "number_of bin.Min = - (1::int)" |
|
22 number_of_BIT: "number_of(w BIT x) = (if x then 1 else 0) + |
|
23 (number_of w) + (number_of w)" |
|
24 |
|
25 declare number_of_Pls [simp del] |
|
26 number_of_Min [simp del] |
|
27 number_of_BIT [simp del] |
|
28 |
|
29 instance int :: number_ring |
|
30 proof |
|
31 show "Numeral0 = (0::int)" by (rule number_of_Pls) |
|
32 show "-1 = - (1::int)" by (rule number_of_Min) |
|
33 fix w :: bin and x :: bool |
|
34 show "(number_of (w BIT x) :: int) = |
|
35 (if x then 1 else 0) + number_of w + number_of w" |
|
36 by (rule number_of_BIT) |
|
37 qed |
|
38 |
|
39 |
11 |
40 |
12 subsection{*Inequality Reasoning for the Arithmetic Simproc*} |
41 subsection{*Inequality Reasoning for the Arithmetic Simproc*} |
|
42 |
|
43 lemma zero_less_nat_eq [simp]: "(0 < nat z) = (0 < z)" |
|
44 by (cut_tac w = 0 in zless_nat_conj, auto) |
13 |
45 |
14 lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z" |
46 lemma zless_imp_add1_zle: "w<z ==> w + (1::int) \<le> z" |
15 apply (rule eq_Abs_Integ [of z]) |
47 apply (rule eq_Abs_Integ [of z]) |
16 apply (rule eq_Abs_Integ [of w]) |
48 apply (rule eq_Abs_Integ [of w]) |
17 apply (simp add: linorder_not_le [symmetric] zle int_def zadd One_int_def) |
49 apply (simp add: linorder_not_le [symmetric] zle int_def zadd One_int_def) |
18 done |
50 done |
19 |
51 |
20 |
52 |
|
53 |
|
54 lemma add_numeral_0: "Numeral0 + a = (a::'a::number_ring)" |
|
55 by simp |
|
56 |
|
57 lemma add_numeral_0_right: "a + Numeral0 = (a::'a::number_ring)" |
|
58 by simp |
|
59 |
|
60 lemma mult_numeral_1: "Numeral1 * a = (a::'a::number_ring)" |
|
61 by simp |
|
62 |
|
63 lemma mult_numeral_1_right: "a * Numeral1 = (a::'a::number_ring)" |
|
64 by simp |
|
65 |
|
66 text{*Theorem lists for the cancellation simprocs. The use of binary numerals |
|
67 for 0 and 1 reduces the number of special cases.*} |
|
68 |
|
69 lemmas add_0s = add_numeral_0 add_numeral_0_right |
|
70 lemmas mult_1s = mult_numeral_1 mult_numeral_1_right |
|
71 mult_minus1 mult_minus1_right |
|
72 |
|
73 |
|
74 subsection{*Special Arithmetic Rules for Abstract 0 and 1*} |
|
75 |
|
76 text{*Arithmetic computations are defined for binary literals, which leaves 0 |
|
77 and 1 as special cases. Addition already has rules for 0, but not 1. |
|
78 Multiplication and unary minus already have rules for both 0 and 1.*} |
|
79 |
|
80 |
|
81 lemma binop_eq: "[|f x y = g x y; x = x'; y = y'|] ==> f x' y' = g x' y'" |
|
82 by simp |
|
83 |
|
84 |
|
85 lemmas add_number_of_eq = number_of_add [symmetric] |
|
86 |
|
87 text{*Allow 1 on either or both sides*} |
|
88 lemma one_add_one_is_two: "1 + 1 = (2::'a::number_ring)" |
|
89 by (simp del: numeral_1_eq_1 add: numeral_1_eq_1 [symmetric] add_number_of_eq) |
|
90 |
|
91 lemmas add_special = |
|
92 one_add_one_is_two |
|
93 binop_eq [of "op +", OF add_number_of_eq numeral_1_eq_1 refl, standard] |
|
94 binop_eq [of "op +", OF add_number_of_eq refl numeral_1_eq_1, standard] |
|
95 |
|
96 text{*Allow 1 on either or both sides (1-1 already simplifies to 0)*} |
|
97 lemmas diff_special = |
|
98 binop_eq [of "op -", OF diff_number_of_eq numeral_1_eq_1 refl, standard] |
|
99 binop_eq [of "op -", OF diff_number_of_eq refl numeral_1_eq_1, standard] |
|
100 |
|
101 text{*Allow 0 or 1 on either side with a binary numeral on the other*} |
|
102 lemmas eq_special = |
|
103 binop_eq [of "op =", OF eq_number_of_eq numeral_0_eq_0 refl, standard] |
|
104 binop_eq [of "op =", OF eq_number_of_eq numeral_1_eq_1 refl, standard] |
|
105 binop_eq [of "op =", OF eq_number_of_eq refl numeral_0_eq_0, standard] |
|
106 binop_eq [of "op =", OF eq_number_of_eq refl numeral_1_eq_1, standard] |
|
107 |
|
108 text{*Allow 0 or 1 on either side with a binary numeral on the other*} |
|
109 lemmas less_special = |
|
110 binop_eq [of "op <", OF less_number_of_eq_neg numeral_0_eq_0 refl, standard] |
|
111 binop_eq [of "op <", OF less_number_of_eq_neg numeral_1_eq_1 refl, standard] |
|
112 binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_0_eq_0, standard] |
|
113 binop_eq [of "op <", OF less_number_of_eq_neg refl numeral_1_eq_1, standard] |
|
114 |
|
115 text{*Allow 0 or 1 on either side with a binary numeral on the other*} |
|
116 lemmas le_special = |
|
117 binop_eq [of "op \<le>", OF le_number_of_eq numeral_0_eq_0 refl, standard] |
|
118 binop_eq [of "op \<le>", OF le_number_of_eq numeral_1_eq_1 refl, standard] |
|
119 binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_0_eq_0, standard] |
|
120 binop_eq [of "op \<le>", OF le_number_of_eq refl numeral_1_eq_1, standard] |
|
121 |
|
122 lemmas arith_special = |
|
123 add_special diff_special eq_special less_special le_special |
|
124 |
|
125 |
21 use "int_arith1.ML" |
126 use "int_arith1.ML" |
22 setup int_arith_setup |
127 setup int_arith_setup |
23 |
128 |
24 |
129 |
25 subsection{*More inequality reasoning*} |
130 subsection{*Lemmas About Small Numerals*} |
|
131 |
|
132 lemma of_int_m1 [simp]: "of_int -1 = (-1 :: 'a :: number_ring)" |
|
133 proof - |
|
134 have "(of_int -1 :: 'a) = of_int (- 1)" by simp |
|
135 also have "... = - of_int 1" by (simp only: of_int_minus) |
|
136 also have "... = -1" by simp |
|
137 finally show ?thesis . |
|
138 qed |
|
139 |
|
140 lemma abs_minus_one [simp]: "abs (-1) = (1::'a::{ordered_ring,number_ring})" |
|
141 by (simp add: abs_if) |
|
142 |
|
143 lemma of_int_number_of_eq: |
|
144 "of_int (number_of v) = (number_of v :: 'a :: number_ring)" |
|
145 apply (induct v) |
|
146 apply (simp_all only: number_of of_int_add, simp_all) |
|
147 done |
|
148 |
|
149 text{*Lemmas for specialist use, NOT as default simprules*} |
|
150 lemma mult_2: "2 * z = (z+z::'a::number_ring)" |
|
151 proof - |
|
152 have "2*z = (1 + 1)*z" by simp |
|
153 also have "... = z+z" by (simp add: left_distrib) |
|
154 finally show ?thesis . |
|
155 qed |
|
156 |
|
157 lemma mult_2_right: "z * 2 = (z+z::'a::number_ring)" |
|
158 by (subst mult_commute, rule mult_2) |
|
159 |
|
160 |
|
161 subsection{*More Inequality Reasoning*} |
26 |
162 |
27 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)" |
163 lemma zless_add1_eq: "(w < z + (1::int)) = (w<z | w=z)" |
28 by arith |
164 by arith |
29 |
165 |
30 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)" |
166 lemma add1_zle_eq: "(w + (1::int) \<le> z) = (w<z)" |
226 apply auto |
359 apply auto |
227 apply (subgoal_tac "m*1 = m*n") |
360 apply (subgoal_tac "m*1 = m*n") |
228 apply (drule mult_cancel_left [THEN iffD1], auto) |
361 apply (drule mult_cancel_left [THEN iffD1], auto) |
229 done |
362 done |
230 |
363 |
231 lemma zless_1_zmult: "[| 1 < m; 1 < n |] ==> 1 < m*(n::int)" |
364 text{*FIXME: tidy*} |
232 apply (rule_tac y = "1*n" in order_less_trans) |
|
233 apply (rule_tac [2] mult_strict_right_mono) |
|
234 apply (simp_all (no_asm_simp)) |
|
235 done |
|
236 |
|
237 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)" |
365 lemma pos_zmult_eq_1_iff: "0 < (m::int) ==> (m * n = 1) = (m = 1 & n = 1)" |
238 apply auto |
366 apply auto |
239 apply (case_tac "m=1") |
367 apply (case_tac "m=1") |
240 apply (case_tac [2] "n=1") |
368 apply (case_tac [2] "n=1") |
241 apply (case_tac [4] "m=1") |
369 apply (case_tac [4] "m=1") |
242 apply (case_tac [5] "n=1", auto) |
370 apply (case_tac [5] "n=1", auto) |
243 apply (tactic"distinct_subgoals_tac") |
371 apply (tactic"distinct_subgoals_tac") |
244 apply (subgoal_tac "1<m*n", simp) |
372 apply (subgoal_tac "1<m*n", simp) |
245 apply (rule zless_1_zmult, arith) |
373 apply (rule less_1_mult, arith) |
246 apply (subgoal_tac "0<n", arith) |
374 apply (subgoal_tac "0<n", arith) |
247 apply (subgoal_tac "0<m*n") |
375 apply (subgoal_tac "0<m*n") |
248 apply (drule zero_less_mult_iff [THEN iffD1], auto) |
376 apply (drule zero_less_mult_iff [THEN iffD1], auto) |
249 done |
377 done |
250 |
378 |