| 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
 |