76143
|
1 |
(* Author: Florian Haftmann, TU Muenchen
|
|
2 |
*)
|
|
3 |
|
77884
|
4 |
section \<open>Division with modulus centered towards zero.\<close>
|
76143
|
5 |
|
77884
|
6 |
theory Centered_Division
|
76143
|
7 |
imports Main
|
|
8 |
begin
|
|
9 |
|
76251
|
10 |
lemma off_iff_abs_mod_2_eq_one:
|
|
11 |
\<open>odd l \<longleftrightarrow> \<bar>l\<bar> mod 2 = 1\<close> for l :: int
|
|
12 |
by (simp flip: odd_iff_mod_2_eq_one)
|
|
13 |
|
77812
|
14 |
text \<open>
|
|
15 |
\noindent The following specification of division on integers centers
|
|
16 |
the modulus around zero. This is useful e.g.~to define division
|
|
17 |
on Gauss numbers.
|
79950
|
18 |
N.b.: This is not mentioned \<^cite>\<open>"leijen01"\<close>.
|
77812
|
19 |
\<close>
|
|
20 |
|
77884
|
21 |
definition centered_divide :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close> (infixl \<open>cdiv\<close> 70)
|
|
22 |
where \<open>k cdiv l = sgn l * ((k + \<bar>l\<bar> div 2) div \<bar>l\<bar>)\<close>
|
76143
|
23 |
|
77884
|
24 |
definition centered_modulo :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close> (infixl \<open>cmod\<close> 70)
|
|
25 |
where \<open>k cmod l = (k + \<bar>l\<bar> div 2) mod \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
|
76143
|
26 |
|
77812
|
27 |
text \<open>
|
77884
|
28 |
\noindent Example: @{lemma \<open>k cmod 5 \<in> {-2, -1, 0, 1, 2}\<close> by (auto simp add: centered_modulo_def)}
|
77812
|
29 |
\<close>
|
|
30 |
|
77884
|
31 |
lemma signed_take_bit_eq_cmod:
|
|
32 |
\<open>signed_take_bit n k = k cmod (2 ^ Suc n)\<close>
|
|
33 |
by (simp only: centered_modulo_def power_abs abs_numeral flip: take_bit_eq_mod)
|
77812
|
34 |
(simp add: signed_take_bit_eq_take_bit_shift)
|
|
35 |
|
|
36 |
text \<open>
|
77884
|
37 |
\noindent Property @{thm signed_take_bit_eq_cmod [no_vars]} is the key to generalize
|
|
38 |
centered division to arbitrary structures satisfying \<^class>\<open>ring_bit_operations\<close>,
|
77812
|
39 |
but so far it is not clear what practical relevance that would have.
|
|
40 |
\<close>
|
|
41 |
|
77884
|
42 |
lemma cdiv_mult_cmod_eq:
|
|
43 |
\<open>k cdiv l * l + k cmod l = k\<close>
|
76248
|
44 |
proof -
|
|
45 |
have *: \<open>l * (sgn l * j) = \<bar>l\<bar> * j\<close> for j
|
|
46 |
by (simp add: ac_simps abs_sgn)
|
|
47 |
show ?thesis
|
77884
|
48 |
by (simp add: centered_divide_def centered_modulo_def algebra_simps *)
|
76248
|
49 |
qed
|
76143
|
50 |
|
77884
|
51 |
lemma mult_cdiv_cmod_eq:
|
|
52 |
\<open>l * (k cdiv l) + k cmod l = k\<close>
|
|
53 |
using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps)
|
76143
|
54 |
|
77884
|
55 |
lemma cmod_cdiv_mult_eq:
|
|
56 |
\<open>k cmod l + k cdiv l * l = k\<close>
|
|
57 |
using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps)
|
76143
|
58 |
|
77884
|
59 |
lemma cmod_mult_cdiv_eq:
|
|
60 |
\<open>k cmod l + l * (k cdiv l) = k\<close>
|
|
61 |
using cdiv_mult_cmod_eq [of k l] by (simp add: ac_simps)
|
76143
|
62 |
|
77884
|
63 |
lemma minus_cdiv_mult_eq_cmod:
|
|
64 |
\<open>k - k cdiv l * l = k cmod l\<close>
|
|
65 |
by (rule add_implies_diff [symmetric]) (fact cmod_cdiv_mult_eq)
|
76143
|
66 |
|
77884
|
67 |
lemma minus_mult_cdiv_eq_cmod:
|
|
68 |
\<open>k - l * (k cdiv l) = k cmod l\<close>
|
|
69 |
by (rule add_implies_diff [symmetric]) (fact cmod_mult_cdiv_eq)
|
76143
|
70 |
|
77884
|
71 |
lemma minus_cmod_eq_cdiv_mult:
|
|
72 |
\<open>k - k cmod l = k cdiv l * l\<close>
|
|
73 |
by (rule add_implies_diff [symmetric]) (fact cdiv_mult_cmod_eq)
|
76143
|
74 |
|
77884
|
75 |
lemma minus_cmod_eq_mult_cdiv:
|
|
76 |
\<open>k - k cmod l = l * (k cdiv l)\<close>
|
|
77 |
by (rule add_implies_diff [symmetric]) (fact mult_cdiv_cmod_eq)
|
76143
|
78 |
|
77884
|
79 |
lemma cdiv_0_eq [simp]:
|
|
80 |
\<open>k cdiv 0 = 0\<close>
|
|
81 |
by (simp add: centered_divide_def)
|
76143
|
82 |
|
77884
|
83 |
lemma cmod_0_eq [simp]:
|
|
84 |
\<open>k cmod 0 = k\<close>
|
|
85 |
by (simp add: centered_modulo_def)
|
76143
|
86 |
|
77884
|
87 |
lemma cdiv_1_eq [simp]:
|
|
88 |
\<open>k cdiv 1 = k\<close>
|
|
89 |
by (simp add: centered_divide_def)
|
76143
|
90 |
|
77884
|
91 |
lemma cmod_1_eq [simp]:
|
|
92 |
\<open>k cmod 1 = 0\<close>
|
|
93 |
by (simp add: centered_modulo_def)
|
76143
|
94 |
|
77884
|
95 |
lemma zero_cdiv_eq [simp]:
|
|
96 |
\<open>0 cdiv k = 0\<close>
|
|
97 |
by (auto simp add: centered_divide_def not_less zdiv_eq_0_iff)
|
76143
|
98 |
|
77884
|
99 |
lemma zero_cmod_eq [simp]:
|
|
100 |
\<open>0 cmod k = 0\<close>
|
|
101 |
by (auto simp add: centered_modulo_def not_less zmod_trivial_iff)
|
76248
|
102 |
|
77884
|
103 |
lemma cdiv_minus_eq:
|
|
104 |
\<open>k cdiv - l = - (k cdiv l)\<close>
|
|
105 |
by (simp add: centered_divide_def)
|
76248
|
106 |
|
77884
|
107 |
lemma cmod_minus_eq [simp]:
|
|
108 |
\<open>k cmod - l = k cmod l\<close>
|
|
109 |
by (simp add: centered_modulo_def)
|
76248
|
110 |
|
77884
|
111 |
lemma cdiv_abs_eq:
|
|
112 |
\<open>k cdiv \<bar>l\<bar> = sgn l * (k cdiv l)\<close>
|
|
113 |
by (simp add: centered_divide_def)
|
76248
|
114 |
|
77884
|
115 |
lemma cmod_abs_eq [simp]:
|
|
116 |
\<open>k cmod \<bar>l\<bar> = k cmod l\<close>
|
|
117 |
by (simp add: centered_modulo_def)
|
76143
|
118 |
|
77884
|
119 |
lemma nonzero_mult_cdiv_cancel_right:
|
|
120 |
\<open>k * l cdiv l = k\<close> if \<open>l \<noteq> 0\<close>
|
76248
|
121 |
proof -
|
77884
|
122 |
have \<open>sgn l * k * \<bar>l\<bar> cdiv l = k\<close>
|
|
123 |
using that by (simp add: centered_divide_def)
|
76248
|
124 |
with that show ?thesis
|
|
125 |
by (simp add: ac_simps abs_sgn)
|
|
126 |
qed
|
76143
|
127 |
|
77884
|
128 |
lemma cdiv_self_eq [simp]:
|
|
129 |
\<open>k cdiv k = 1\<close> if \<open>k \<noteq> 0\<close>
|
|
130 |
using that nonzero_mult_cdiv_cancel_right [of k 1] by simp
|
76143
|
131 |
|
77884
|
132 |
lemma cmod_self_eq [simp]:
|
|
133 |
\<open>k cmod k = 0\<close>
|
76248
|
134 |
proof -
|
|
135 |
have \<open>(sgn k * \<bar>k\<bar> + \<bar>k\<bar> div 2) mod \<bar>k\<bar> = \<bar>k\<bar> div 2\<close>
|
|
136 |
by (auto simp add: zmod_trivial_iff)
|
|
137 |
also have \<open>sgn k * \<bar>k\<bar> = k\<close>
|
|
138 |
by (simp add: abs_sgn)
|
|
139 |
finally show ?thesis
|
77884
|
140 |
by (simp add: centered_modulo_def algebra_simps)
|
76248
|
141 |
qed
|
|
142 |
|
77884
|
143 |
lemma cmod_less_divisor:
|
|
144 |
\<open>k cmod l < \<bar>l\<bar> - \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
|
|
145 |
using that pos_mod_bound [of \<open>\<bar>l\<bar>\<close>] by (simp add: centered_modulo_def)
|
76251
|
146 |
|
77884
|
147 |
lemma cmod_less_equal_divisor:
|
|
148 |
\<open>k cmod l \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
|
76251
|
149 |
proof -
|
77884
|
150 |
from that cmod_less_divisor [of l k]
|
|
151 |
have \<open>k cmod l < \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
|
76251
|
152 |
by simp
|
|
153 |
also have \<open>\<bar>l\<bar> - \<bar>l\<bar> div 2 = \<bar>l\<bar> div 2 + of_bool (odd l)\<close>
|
|
154 |
by auto
|
|
155 |
finally show ?thesis
|
|
156 |
by (cases \<open>even l\<close>) simp_all
|
|
157 |
qed
|
|
158 |
|
77884
|
159 |
lemma divisor_less_equal_cmod':
|
|
160 |
\<open>\<bar>l\<bar> div 2 - \<bar>l\<bar> \<le> k cmod l\<close> if \<open>l \<noteq> 0\<close>
|
76251
|
161 |
proof -
|
|
162 |
have \<open>0 \<le> (k + \<bar>l\<bar> div 2) mod \<bar>l\<bar>\<close>
|
|
163 |
using that pos_mod_sign [of \<open>\<bar>l\<bar>\<close>] by simp
|
|
164 |
then show ?thesis
|
77884
|
165 |
by (simp_all add: centered_modulo_def)
|
76251
|
166 |
qed
|
|
167 |
|
77884
|
168 |
lemma divisor_less_equal_cmod:
|
|
169 |
\<open>- (\<bar>l\<bar> div 2) \<le> k cmod l\<close> if \<open>l \<noteq> 0\<close>
|
|
170 |
using that divisor_less_equal_cmod' [of l k]
|
|
171 |
by (simp add: centered_modulo_def)
|
76251
|
172 |
|
77884
|
173 |
lemma abs_cmod_less_equal:
|
|
174 |
\<open>\<bar>k cmod l\<bar> \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
|
|
175 |
using that divisor_less_equal_cmod [of l k]
|
|
176 |
by (simp add: abs_le_iff cmod_less_equal_divisor)
|
76251
|
177 |
|
76143
|
178 |
end
|