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