| 76143 |      1 | (*  Author:  Florian Haftmann, TU Muenchen
 | 
|  |      2 | *)
 | 
|  |      3 | 
 | 
| 76247 |      4 | subsection \<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 | 
 | 
| 76143 |     14 | definition rounded_divide :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close>  (infixl \<open>rdiv\<close> 70)
 | 
| 76248 |     15 |   where \<open>k rdiv l = sgn l * ((k + \<bar>l\<bar> div 2) div \<bar>l\<bar>)\<close>
 | 
| 76143 |     16 | 
 | 
|  |     17 | definition rounded_modulo :: \<open>int \<Rightarrow> int \<Rightarrow> int\<close>  (infixl \<open>rmod\<close> 70)
 | 
| 76248 |     18 |   where \<open>k rmod l = (k + \<bar>l\<bar> div 2) mod \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
 | 
| 76143 |     19 | 
 | 
|  |     20 | lemma rdiv_mult_rmod_eq:
 | 
|  |     21 |   \<open>k rdiv l * l + k rmod l = k\<close>
 | 
| 76248 |     22 | proof -
 | 
|  |     23 |   have *: \<open>l * (sgn l * j) = \<bar>l\<bar> * j\<close> for j
 | 
|  |     24 |     by (simp add: ac_simps abs_sgn)
 | 
|  |     25 |   show ?thesis
 | 
|  |     26 |     by (simp add: rounded_divide_def rounded_modulo_def algebra_simps *)
 | 
|  |     27 | qed
 | 
| 76143 |     28 | 
 | 
|  |     29 | lemma mult_rdiv_rmod_eq:
 | 
|  |     30 |   \<open>l * (k rdiv l) + k rmod l = k\<close>
 | 
|  |     31 |   using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
 | 
|  |     32 | 
 | 
|  |     33 | lemma rmod_rdiv_mult_eq:
 | 
|  |     34 |   \<open>k rmod l + k rdiv l * l = k\<close>
 | 
|  |     35 |   using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
 | 
|  |     36 | 
 | 
|  |     37 | lemma rmod_mult_rdiv_eq:
 | 
|  |     38 |   \<open>k rmod l + l * (k rdiv l) = k\<close>
 | 
|  |     39 |   using rdiv_mult_rmod_eq [of k l] by (simp add: ac_simps)
 | 
|  |     40 | 
 | 
|  |     41 | lemma minus_rdiv_mult_eq_rmod:
 | 
|  |     42 |   \<open>k - k rdiv l * l = k rmod l\<close>
 | 
|  |     43 |   by (rule add_implies_diff [symmetric]) (fact rmod_rdiv_mult_eq)
 | 
|  |     44 | 
 | 
|  |     45 | lemma minus_mult_rdiv_eq_rmod:
 | 
|  |     46 |   \<open>k - l * (k rdiv l) = k rmod l\<close>
 | 
|  |     47 |   by (rule add_implies_diff [symmetric]) (fact rmod_mult_rdiv_eq)
 | 
|  |     48 | 
 | 
|  |     49 | lemma minus_rmod_eq_rdiv_mult:
 | 
|  |     50 |   \<open>k - k rmod l = k rdiv l * l\<close>
 | 
|  |     51 |   by (rule add_implies_diff [symmetric]) (fact rdiv_mult_rmod_eq)
 | 
|  |     52 | 
 | 
|  |     53 | lemma minus_rmod_eq_mult_rdiv:
 | 
|  |     54 |   \<open>k - k rmod l = l * (k rdiv l)\<close>
 | 
|  |     55 |   by (rule add_implies_diff [symmetric]) (fact mult_rdiv_rmod_eq)
 | 
|  |     56 | 
 | 
|  |     57 | lemma rdiv_0_eq [simp]:
 | 
|  |     58 |   \<open>k rdiv 0 = 0\<close>
 | 
|  |     59 |   by (simp add: rounded_divide_def)
 | 
|  |     60 | 
 | 
|  |     61 | lemma rmod_0_eq [simp]:
 | 
|  |     62 |   \<open>k rmod 0 = k\<close>
 | 
|  |     63 |   by (simp add: rounded_modulo_def)
 | 
|  |     64 | 
 | 
|  |     65 | lemma rdiv_1_eq [simp]:
 | 
|  |     66 |   \<open>k rdiv 1 = k\<close>
 | 
|  |     67 |   by (simp add: rounded_divide_def)
 | 
|  |     68 | 
 | 
|  |     69 | lemma rmod_1_eq [simp]:
 | 
|  |     70 |   \<open>k rmod 1 = 0\<close>
 | 
|  |     71 |   by (simp add: rounded_modulo_def)
 | 
|  |     72 | 
 | 
|  |     73 | lemma zero_rdiv_eq [simp]:
 | 
|  |     74 |   \<open>0 rdiv k = 0\<close>
 | 
|  |     75 |   by (auto simp add: rounded_divide_def not_less zdiv_eq_0_iff)
 | 
|  |     76 | 
 | 
|  |     77 | lemma zero_rmod_eq [simp]:
 | 
|  |     78 |   \<open>0 rmod k = 0\<close>
 | 
| 76248 |     79 |   by (auto simp add: rounded_modulo_def not_less zmod_trivial_iff)
 | 
|  |     80 | 
 | 
|  |     81 | lemma rdiv_minus_eq:
 | 
|  |     82 |   \<open>k rdiv - l = - (k rdiv l)\<close>
 | 
|  |     83 |   by (simp add: rounded_divide_def)
 | 
|  |     84 | 
 | 
|  |     85 | lemma rmod_minus_eq [simp]:
 | 
|  |     86 |   \<open>k rmod - l = k rmod l\<close>
 | 
|  |     87 |   by (simp add: rounded_modulo_def)
 | 
|  |     88 | 
 | 
|  |     89 | lemma rdiv_abs_eq:
 | 
|  |     90 |   \<open>k rdiv \<bar>l\<bar> = sgn l * (k rdiv l)\<close>
 | 
|  |     91 |   by (simp add: rounded_divide_def)
 | 
|  |     92 | 
 | 
|  |     93 | lemma rmod_abs_eq [simp]:
 | 
|  |     94 |   \<open>k rmod \<bar>l\<bar> = k rmod l\<close>
 | 
| 76143 |     95 |   by (simp add: rounded_modulo_def)
 | 
|  |     96 | 
 | 
|  |     97 | lemma nonzero_mult_rdiv_cancel_right:
 | 
|  |     98 |   \<open>k * l rdiv l = k\<close> if \<open>l \<noteq> 0\<close>
 | 
| 76248 |     99 | proof -
 | 
|  |    100 |   have \<open>sgn l * k * \<bar>l\<bar> rdiv l = k\<close>
 | 
|  |    101 |     using that by (simp add: rounded_divide_def)
 | 
|  |    102 |   with that show ?thesis
 | 
|  |    103 |     by (simp add: ac_simps abs_sgn)
 | 
|  |    104 | qed
 | 
| 76143 |    105 | 
 | 
|  |    106 | lemma rdiv_self_eq [simp]:
 | 
|  |    107 |   \<open>k rdiv k = 1\<close> if \<open>k \<noteq> 0\<close>
 | 
|  |    108 |   using that nonzero_mult_rdiv_cancel_right [of k 1] by simp
 | 
|  |    109 | 
 | 
|  |    110 | lemma rmod_self_eq [simp]:
 | 
|  |    111 |   \<open>k rmod k = 0\<close>
 | 
| 76248 |    112 | proof -
 | 
|  |    113 |   have \<open>(sgn k * \<bar>k\<bar> + \<bar>k\<bar> div 2) mod \<bar>k\<bar> = \<bar>k\<bar> div 2\<close>
 | 
|  |    114 |     by (auto simp add: zmod_trivial_iff)
 | 
|  |    115 |   also have \<open>sgn k * \<bar>k\<bar> = k\<close>
 | 
|  |    116 |     by (simp add: abs_sgn)
 | 
|  |    117 |   finally show ?thesis
 | 
|  |    118 |     by (simp add: rounded_modulo_def algebra_simps)
 | 
|  |    119 | qed
 | 
|  |    120 | 
 | 
|  |    121 | lemma signed_take_bit_eq_rmod:
 | 
|  |    122 |   \<open>signed_take_bit n k = k rmod (2 ^ Suc n)\<close>
 | 
|  |    123 |   by (simp only: rounded_modulo_def power_abs abs_numeral flip: take_bit_eq_mod)
 | 
|  |    124 |     (simp add: signed_take_bit_eq_take_bit_shift)
 | 
| 76143 |    125 | 
 | 
| 76251 |    126 | lemma rmod_less_divisor:
 | 
|  |    127 |   \<open>k rmod l < \<bar>l\<bar> - \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
 | 
|  |    128 |   using that pos_mod_bound [of \<open>\<bar>l\<bar>\<close>] by (simp add: rounded_modulo_def)
 | 
|  |    129 | 
 | 
|  |    130 | lemma rmod_less_equal_divisor:
 | 
|  |    131 |   \<open>k rmod l \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
 | 
|  |    132 | proof -
 | 
|  |    133 |   from that rmod_less_divisor [of l k]
 | 
|  |    134 |   have \<open>k rmod l < \<bar>l\<bar> - \<bar>l\<bar> div 2\<close>
 | 
|  |    135 |     by simp
 | 
|  |    136 |   also have \<open>\<bar>l\<bar> - \<bar>l\<bar> div 2 = \<bar>l\<bar> div 2 + of_bool (odd l)\<close>
 | 
|  |    137 |     by auto
 | 
|  |    138 |   finally show ?thesis
 | 
|  |    139 |     by (cases \<open>even l\<close>) simp_all
 | 
|  |    140 | qed
 | 
|  |    141 | 
 | 
|  |    142 | lemma divisor_less_equal_rmod':
 | 
|  |    143 |   \<open>\<bar>l\<bar> div 2 - \<bar>l\<bar> \<le> k rmod l\<close> if \<open>l \<noteq> 0\<close>
 | 
|  |    144 | proof -
 | 
|  |    145 |   have \<open>0 \<le> (k + \<bar>l\<bar> div 2) mod \<bar>l\<bar>\<close>
 | 
|  |    146 |     using that pos_mod_sign [of \<open>\<bar>l\<bar>\<close>] by simp
 | 
|  |    147 |   then show ?thesis
 | 
|  |    148 |     by (simp_all add: rounded_modulo_def)
 | 
|  |    149 | qed
 | 
|  |    150 | 
 | 
|  |    151 | lemma divisor_less_equal_rmod:
 | 
|  |    152 |   \<open>- (\<bar>l\<bar> div 2) \<le> k rmod l\<close> if \<open>l \<noteq> 0\<close>
 | 
|  |    153 |   using that divisor_less_equal_rmod' [of l k]
 | 
|  |    154 |   by (simp add: rounded_modulo_def)
 | 
|  |    155 | 
 | 
|  |    156 | lemma abs_rmod_less_equal:
 | 
|  |    157 |   \<open>\<bar>k rmod l\<bar> \<le> \<bar>l\<bar> div 2\<close> if \<open>l \<noteq> 0\<close>
 | 
|  |    158 |   using that divisor_less_equal_rmod [of l k]
 | 
|  |    159 |   by (simp add: abs_le_iff rmod_less_equal_divisor)
 | 
|  |    160 | 
 | 
| 76143 |    161 | end
 |