|
76143
|
1 |
(* Author: Florian Haftmann, TU Muenchen
|
|
|
2 |
*)
|
|
|
3 |
|
|
77811
|
4 |
section \<open>Rounded division: modulus centered towards zero.\<close>
|
|
76143
|
5 |
|
|
|
6 |
theory Rounded_Division
|
|
|
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.
|
|
|
18 |
N.b.: This is not mentioned \cite{leijen01}.
|
|
|
19 |
\<close>
|
|
|
20 |
|
|
76143
|
21 |
definition rounded_divide :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close> (infixl \<open>rdiv\<close> 70)
|
|
76248
|
22 |
where \<open>k rdiv l = sgn l * ((k + \<bar>l\<bar> div 2) div \<bar>l\<bar>)\<close>
|
|
76143
|
23 |
|
|
|
24 |
definition rounded_modulo :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close> (infixl \<open>rmod\<close> 70)
|
|
76248
|
25 |
where \<open>k rmod l = (k + \<bar>l\<bar> div 2) mod \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
|
|
76143
|
26 |
|
|
77812
|
27 |
text \<open>
|
|
|
28 |
\noindent Example: @{lemma \<open>k rmod 5 \<in> {-2, -1, 0, 1, 2}\<close> by (auto simp add: rounded_modulo_def)}
|
|
|
29 |
\<close>
|
|
|
30 |
|
|
|
31 |
lemma signed_take_bit_eq_rmod:
|
|
|
32 |
\<open>signed_take_bit n k = k rmod (2 ^ Suc n)\<close>
|
|
|
33 |
by (simp only: rounded_modulo_def power_abs abs_numeral flip: take_bit_eq_mod)
|
|
|
34 |
(simp add: signed_take_bit_eq_take_bit_shift)
|
|
|
35 |
|
|
|
36 |
text \<open>
|
|
|
37 |
\noindent Property @{thm signed_take_bit_eq_rmod [no_vars]} is the key to generalize
|
|
|
38 |
rounded division to arbitrary structures satisfying \<^class>\<open>ring_bit_operations\<close>,
|
|
|
39 |
but so far it is not clear what practical relevance that would have.
|
|
|
40 |
\<close>
|
|
|
41 |
|
|
76143
|
42 |
lemma rdiv_mult_rmod_eq:
|
|
|
43 |
\<open>k rdiv l * l + k rmod 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
|
|
|
48 |
by (simp add: rounded_divide_def rounded_modulo_def algebra_simps *)
|
|
|
49 |
qed
|
|
76143
|
50 |
|
|
|
51 |
lemma mult_rdiv_rmod_eq:
|
|
|
52 |
\<open>l * (k rdiv l) + k rmod l = k\<close>
|
|
|
53 |
using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
|
|
|
54 |
|
|
|
55 |
lemma rmod_rdiv_mult_eq:
|
|
|
56 |
\<open>k rmod l + k rdiv l * l = k\<close>
|
|
|
57 |
using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
|
|
|
58 |
|
|
|
59 |
lemma rmod_mult_rdiv_eq:
|
|
|
60 |
\<open>k rmod l + l * (k rdiv l) = k\<close>
|
|
|
61 |
using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
|
|
|
62 |
|
|
|
63 |
lemma minus_rdiv_mult_eq_rmod:
|
|
|
64 |
\<open>k - k rdiv l * l = k rmod l\<close>
|
|
|
65 |
by (rule add_implies_diff [symmetric]) (fact rmod_rdiv_mult_eq)
|
|
|
66 |
|
|
|
67 |
lemma minus_mult_rdiv_eq_rmod:
|
|
|
68 |
\<open>k - l * (k rdiv l) = k rmod l\<close>
|
|
|
69 |
by (rule add_implies_diff [symmetric]) (fact rmod_mult_rdiv_eq)
|
|
|
70 |
|
|
|
71 |
lemma minus_rmod_eq_rdiv_mult:
|
|
|
72 |
\<open>k - k rmod l = k rdiv l * l\<close>
|
|
|
73 |
by (rule add_implies_diff [symmetric]) (fact rdiv_mult_rmod_eq)
|
|
|
74 |
|
|
|
75 |
lemma minus_rmod_eq_mult_rdiv:
|
|
|
76 |
\<open>k - k rmod l = l * (k rdiv l)\<close>
|
|
|
77 |
by (rule add_implies_diff [symmetric]) (fact mult_rdiv_rmod_eq)
|
|
|
78 |
|
|
|
79 |
lemma rdiv_0_eq [simp]:
|
|
|
80 |
\<open>k rdiv 0 = 0\<close>
|
|
|
81 |
by (simp add: rounded_divide_def)
|
|
|
82 |
|
|
|
83 |
lemma rmod_0_eq [simp]:
|
|
|
84 |
\<open>k rmod 0 = k\<close>
|
|
|
85 |
by (simp add: rounded_modulo_def)
|
|
|
86 |
|
|
|
87 |
lemma rdiv_1_eq [simp]:
|
|
|
88 |
\<open>k rdiv 1 = k\<close>
|
|
|
89 |
by (simp add: rounded_divide_def)
|
|
|
90 |
|
|
|
91 |
lemma rmod_1_eq [simp]:
|
|
|
92 |
\<open>k rmod 1 = 0\<close>
|
|
|
93 |
by (simp add: rounded_modulo_def)
|
|
|
94 |
|
|
|
95 |
lemma zero_rdiv_eq [simp]:
|
|
|
96 |
\<open>0 rdiv k = 0\<close>
|
|
|
97 |
by (auto simp add: rounded_divide_def not_less zdiv_eq_0_iff)
|
|
|
98 |
|
|
|
99 |
lemma zero_rmod_eq [simp]:
|
|
|
100 |
\<open>0 rmod k = 0\<close>
|
|
76248
|
101 |
by (auto simp add: rounded_modulo_def not_less zmod_trivial_iff)
|
|
|
102 |
|
|
|
103 |
lemma rdiv_minus_eq:
|
|
|
104 |
\<open>k rdiv - l = - (k rdiv l)\<close>
|
|
|
105 |
by (simp add: rounded_divide_def)
|
|
|
106 |
|
|
|
107 |
lemma rmod_minus_eq [simp]:
|
|
|
108 |
\<open>k rmod - l = k rmod l\<close>
|
|
|
109 |
by (simp add: rounded_modulo_def)
|
|
|
110 |
|
|
|
111 |
lemma rdiv_abs_eq:
|
|
|
112 |
\<open>k rdiv \<bar>l\<bar> = sgn l * (k rdiv l)\<close>
|
|
|
113 |
by (simp add: rounded_divide_def)
|
|
|
114 |
|
|
|
115 |
lemma rmod_abs_eq [simp]:
|
|
|
116 |
\<open>k rmod \<bar>l\<bar> = k rmod l\<close>
|
|
76143
|
117 |
by (simp add: rounded_modulo_def)
|
|
|
118 |
|
|
|
119 |
lemma nonzero_mult_rdiv_cancel_right:
|
|
|
120 |
\<open>k * l rdiv l = k\<close> if \<open>l \<noteq> 0\<close>
|
|
76248
|
121 |
proof -
|
|
|
122 |
have \<open>sgn l * k * \<bar>l\<bar> rdiv l = k\<close>
|
|
|
123 |
using that by (simp add: rounded_divide_def)
|
|
|
124 |
with that show ?thesis
|
|
|
125 |
by (simp add: ac_simps abs_sgn)
|
|
|
126 |
qed
|
|
76143
|
127 |
|
|
|
128 |
lemma rdiv_self_eq [simp]:
|
|
|
129 |
\<open>k rdiv k = 1\<close> if \<open>k \<noteq> 0\<close>
|
|
|
130 |
using that nonzero_mult_rdiv_cancel_right [of k 1] by simp
|
|
|
131 |
|
|
|
132 |
lemma rmod_self_eq [simp]:
|
|
|
133 |
\<open>k rmod 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
|
|
|
140 |
by (simp add: rounded_modulo_def algebra_simps)
|
|
|
141 |
qed
|
|
|
142 |
|
|
76251
|
143 |
lemma rmod_less_divisor:
|
|
|
144 |
\<open>k rmod 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: rounded_modulo_def)
|
|
|
146 |
|
|
|
147 |
lemma rmod_less_equal_divisor:
|
|
|
148 |
\<open>k rmod l \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
|
|
|
149 |
proof -
|
|
|
150 |
from that rmod_less_divisor [of l k]
|
|
|
151 |
have \<open>k rmod l < \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
|
|
|
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 |
|
|
|
159 |
lemma divisor_less_equal_rmod':
|
|
|
160 |
\<open>\<bar>l\<bar> div 2 - \<bar>l\<bar> \<le> k rmod l\<close> if \<open>l \<noteq> 0\<close>
|
|
|
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
|
|
|
165 |
by (simp_all add: rounded_modulo_def)
|
|
|
166 |
qed
|
|
|
167 |
|
|
|
168 |
lemma divisor_less_equal_rmod:
|
|
|
169 |
\<open>- (\<bar>l\<bar> div 2) \<le> k rmod l\<close> if \<open>l \<noteq> 0\<close>
|
|
|
170 |
using that divisor_less_equal_rmod' [of l k]
|
|
|
171 |
by (simp add: rounded_modulo_def)
|
|
|
172 |
|
|
|
173 |
lemma abs_rmod_less_equal:
|
|
|
174 |
\<open>\<bar>k rmod l\<bar> \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
|
|
|
175 |
using that divisor_less_equal_rmod [of l k]
|
|
|
176 |
by (simp add: abs_le_iff rmod_less_equal_divisor)
|
|
|
177 |
|
|
76143
|
178 |
end
|