| 64785 |      1 | (*  Title:      HOL/Euclidean_Division.thy
 | 
|  |      2 |     Author:     Manuel Eberl, TU Muenchen
 | 
|  |      3 |     Author:     Florian Haftmann, TU Muenchen
 | 
|  |      4 | *)
 | 
|  |      5 | 
 | 
|  |      6 | section \<open>Uniquely determined division in euclidean (semi)rings\<close>
 | 
|  |      7 | 
 | 
|  |      8 | theory Euclidean_Division
 | 
|  |      9 |   imports Nat_Transfer
 | 
|  |     10 | begin
 | 
|  |     11 | 
 | 
|  |     12 | subsection \<open>Quotient and remainder in integral domains\<close>
 | 
|  |     13 | 
 | 
|  |     14 | class semidom_modulo = algebraic_semidom + semiring_modulo
 | 
|  |     15 | begin
 | 
|  |     16 | 
 | 
|  |     17 | lemma mod_0 [simp]: "0 mod a = 0"
 | 
|  |     18 |   using div_mult_mod_eq [of 0 a] by simp
 | 
|  |     19 | 
 | 
|  |     20 | lemma mod_by_0 [simp]: "a mod 0 = a"
 | 
|  |     21 |   using div_mult_mod_eq [of a 0] by simp
 | 
|  |     22 | 
 | 
|  |     23 | lemma mod_by_1 [simp]:
 | 
|  |     24 |   "a mod 1 = 0"
 | 
|  |     25 | proof -
 | 
|  |     26 |   from div_mult_mod_eq [of a one] div_by_1 have "a + a mod 1 = a" by simp
 | 
|  |     27 |   then have "a + a mod 1 = a + 0" by simp
 | 
|  |     28 |   then show ?thesis by (rule add_left_imp_eq)
 | 
|  |     29 | qed
 | 
|  |     30 | 
 | 
|  |     31 | lemma mod_self [simp]:
 | 
|  |     32 |   "a mod a = 0"
 | 
|  |     33 |   using div_mult_mod_eq [of a a] by simp
 | 
|  |     34 | 
 | 
|  |     35 | lemma dvd_imp_mod_0 [simp]:
 | 
|  |     36 |   assumes "a dvd b"
 | 
|  |     37 |   shows "b mod a = 0"
 | 
|  |     38 |   using assms minus_div_mult_eq_mod [of b a] by simp
 | 
|  |     39 | 
 | 
|  |     40 | lemma mod_0_imp_dvd: 
 | 
|  |     41 |   assumes "a mod b = 0"
 | 
|  |     42 |   shows   "b dvd a"
 | 
|  |     43 | proof -
 | 
|  |     44 |   have "b dvd ((a div b) * b)" by simp
 | 
|  |     45 |   also have "(a div b) * b = a"
 | 
|  |     46 |     using div_mult_mod_eq [of a b] by (simp add: assms)
 | 
|  |     47 |   finally show ?thesis .
 | 
|  |     48 | qed
 | 
|  |     49 | 
 | 
|  |     50 | lemma mod_eq_0_iff_dvd:
 | 
|  |     51 |   "a mod b = 0 \<longleftrightarrow> b dvd a"
 | 
|  |     52 |   by (auto intro: mod_0_imp_dvd)
 | 
|  |     53 | 
 | 
|  |     54 | lemma dvd_eq_mod_eq_0 [nitpick_unfold, code]:
 | 
|  |     55 |   "a dvd b \<longleftrightarrow> b mod a = 0"
 | 
|  |     56 |   by (simp add: mod_eq_0_iff_dvd)
 | 
|  |     57 | 
 | 
|  |     58 | lemma dvd_mod_iff: 
 | 
|  |     59 |   assumes "c dvd b"
 | 
|  |     60 |   shows "c dvd a mod b \<longleftrightarrow> c dvd a"
 | 
|  |     61 | proof -
 | 
|  |     62 |   from assms have "(c dvd a mod b) \<longleftrightarrow> (c dvd ((a div b) * b + a mod b))" 
 | 
|  |     63 |     by (simp add: dvd_add_right_iff)
 | 
|  |     64 |   also have "(a div b) * b + a mod b = a"
 | 
|  |     65 |     using div_mult_mod_eq [of a b] by simp
 | 
|  |     66 |   finally show ?thesis .
 | 
|  |     67 | qed
 | 
|  |     68 | 
 | 
|  |     69 | lemma dvd_mod_imp_dvd:
 | 
|  |     70 |   assumes "c dvd a mod b" and "c dvd b"
 | 
|  |     71 |   shows "c dvd a"
 | 
|  |     72 |   using assms dvd_mod_iff [of c b a] by simp
 | 
|  |     73 | 
 | 
|  |     74 | end
 | 
|  |     75 | 
 | 
|  |     76 | class idom_modulo = idom + semidom_modulo
 | 
|  |     77 | begin
 | 
|  |     78 | 
 | 
|  |     79 | subclass idom_divide ..
 | 
|  |     80 | 
 | 
|  |     81 | lemma div_diff [simp]:
 | 
|  |     82 |   "c dvd a \<Longrightarrow> c dvd b \<Longrightarrow> (a - b) div c = a div c - b div c"
 | 
|  |     83 |   using div_add [of _  _ "- b"] by (simp add: dvd_neg_div)
 | 
|  |     84 | 
 | 
|  |     85 | end
 | 
|  |     86 | 
 | 
|  |     87 |   
 | 
|  |     88 | subsection \<open>Euclidean (semi)rings with explicit division and remainder\<close>
 | 
|  |     89 |   
 | 
|  |     90 | class euclidean_semiring = semidom_modulo + normalization_semidom + 
 | 
|  |     91 |   fixes euclidean_size :: "'a \<Rightarrow> nat"
 | 
|  |     92 |   assumes size_0 [simp]: "euclidean_size 0 = 0"
 | 
|  |     93 |   assumes mod_size_less: 
 | 
|  |     94 |     "b \<noteq> 0 \<Longrightarrow> euclidean_size (a mod b) < euclidean_size b"
 | 
|  |     95 |   assumes size_mult_mono:
 | 
|  |     96 |     "b \<noteq> 0 \<Longrightarrow> euclidean_size a \<le> euclidean_size (a * b)"
 | 
|  |     97 | begin
 | 
|  |     98 | 
 | 
|  |     99 | lemma size_mult_mono': "b \<noteq> 0 \<Longrightarrow> euclidean_size a \<le> euclidean_size (b * a)"
 | 
|  |    100 |   by (subst mult.commute) (rule size_mult_mono)
 | 
|  |    101 | 
 | 
|  |    102 | lemma euclidean_size_normalize [simp]:
 | 
|  |    103 |   "euclidean_size (normalize a) = euclidean_size a"
 | 
|  |    104 | proof (cases "a = 0")
 | 
|  |    105 |   case True
 | 
|  |    106 |   then show ?thesis
 | 
|  |    107 |     by simp
 | 
|  |    108 | next
 | 
|  |    109 |   case [simp]: False
 | 
|  |    110 |   have "euclidean_size (normalize a) \<le> euclidean_size (normalize a * unit_factor a)"
 | 
|  |    111 |     by (rule size_mult_mono) simp
 | 
|  |    112 |   moreover have "euclidean_size a \<le> euclidean_size (a * (1 div unit_factor a))"
 | 
|  |    113 |     by (rule size_mult_mono) simp
 | 
|  |    114 |   ultimately show ?thesis
 | 
|  |    115 |     by simp
 | 
|  |    116 | qed
 | 
|  |    117 | 
 | 
|  |    118 | lemma dvd_euclidean_size_eq_imp_dvd:
 | 
|  |    119 |   assumes "a \<noteq> 0" and "euclidean_size a = euclidean_size b"
 | 
|  |    120 |     and "b dvd a" 
 | 
|  |    121 |   shows "a dvd b"
 | 
|  |    122 | proof (rule ccontr)
 | 
|  |    123 |   assume "\<not> a dvd b"
 | 
|  |    124 |   hence "b mod a \<noteq> 0" using mod_0_imp_dvd [of b a] by blast
 | 
|  |    125 |   then have "b mod a \<noteq> 0" by (simp add: mod_eq_0_iff_dvd)
 | 
|  |    126 |   from \<open>b dvd a\<close> have "b dvd b mod a" by (simp add: dvd_mod_iff)
 | 
|  |    127 |   then obtain c where "b mod a = b * c" unfolding dvd_def by blast
 | 
|  |    128 |     with \<open>b mod a \<noteq> 0\<close> have "c \<noteq> 0" by auto
 | 
|  |    129 |   with \<open>b mod a = b * c\<close> have "euclidean_size (b mod a) \<ge> euclidean_size b"
 | 
|  |    130 |     using size_mult_mono by force
 | 
|  |    131 |   moreover from \<open>\<not> a dvd b\<close> and \<open>a \<noteq> 0\<close>
 | 
|  |    132 |   have "euclidean_size (b mod a) < euclidean_size a"
 | 
|  |    133 |     using mod_size_less by blast
 | 
|  |    134 |   ultimately show False using \<open>euclidean_size a = euclidean_size b\<close>
 | 
|  |    135 |     by simp
 | 
|  |    136 | qed
 | 
|  |    137 | 
 | 
|  |    138 | lemma euclidean_size_times_unit:
 | 
|  |    139 |   assumes "is_unit a"
 | 
|  |    140 |   shows   "euclidean_size (a * b) = euclidean_size b"
 | 
|  |    141 | proof (rule antisym)
 | 
|  |    142 |   from assms have [simp]: "a \<noteq> 0" by auto
 | 
|  |    143 |   thus "euclidean_size (a * b) \<ge> euclidean_size b" by (rule size_mult_mono')
 | 
|  |    144 |   from assms have "is_unit (1 div a)" by simp
 | 
|  |    145 |   hence "1 div a \<noteq> 0" by (intro notI) simp_all
 | 
|  |    146 |   hence "euclidean_size (a * b) \<le> euclidean_size ((1 div a) * (a * b))"
 | 
|  |    147 |     by (rule size_mult_mono')
 | 
|  |    148 |   also from assms have "(1 div a) * (a * b) = b"
 | 
|  |    149 |     by (simp add: algebra_simps unit_div_mult_swap)
 | 
|  |    150 |   finally show "euclidean_size (a * b) \<le> euclidean_size b" .
 | 
|  |    151 | qed
 | 
|  |    152 | 
 | 
|  |    153 | lemma euclidean_size_unit:
 | 
|  |    154 |   "is_unit a \<Longrightarrow> euclidean_size a = euclidean_size 1"
 | 
|  |    155 |   using euclidean_size_times_unit [of a 1] by simp
 | 
|  |    156 | 
 | 
|  |    157 | lemma unit_iff_euclidean_size: 
 | 
|  |    158 |   "is_unit a \<longleftrightarrow> euclidean_size a = euclidean_size 1 \<and> a \<noteq> 0"
 | 
|  |    159 | proof safe
 | 
|  |    160 |   assume A: "a \<noteq> 0" and B: "euclidean_size a = euclidean_size 1"
 | 
|  |    161 |   show "is_unit a"
 | 
|  |    162 |     by (rule dvd_euclidean_size_eq_imp_dvd [OF A B]) simp_all
 | 
|  |    163 | qed (auto intro: euclidean_size_unit)
 | 
|  |    164 | 
 | 
|  |    165 | lemma euclidean_size_times_nonunit:
 | 
|  |    166 |   assumes "a \<noteq> 0" "b \<noteq> 0" "\<not> is_unit a"
 | 
|  |    167 |   shows   "euclidean_size b < euclidean_size (a * b)"
 | 
|  |    168 | proof (rule ccontr)
 | 
|  |    169 |   assume "\<not>euclidean_size b < euclidean_size (a * b)"
 | 
|  |    170 |   with size_mult_mono'[OF assms(1), of b] 
 | 
|  |    171 |     have eq: "euclidean_size (a * b) = euclidean_size b" by simp
 | 
|  |    172 |   have "a * b dvd b"
 | 
|  |    173 |     by (rule dvd_euclidean_size_eq_imp_dvd [OF _ eq]) (insert assms, simp_all)
 | 
|  |    174 |   hence "a * b dvd 1 * b" by simp
 | 
|  |    175 |   with \<open>b \<noteq> 0\<close> have "is_unit a" by (subst (asm) dvd_times_right_cancel_iff)
 | 
|  |    176 |   with assms(3) show False by contradiction
 | 
|  |    177 | qed
 | 
|  |    178 | 
 | 
|  |    179 | lemma dvd_imp_size_le:
 | 
|  |    180 |   assumes "a dvd b" "b \<noteq> 0" 
 | 
|  |    181 |   shows   "euclidean_size a \<le> euclidean_size b"
 | 
|  |    182 |   using assms by (auto elim!: dvdE simp: size_mult_mono)
 | 
|  |    183 | 
 | 
|  |    184 | lemma dvd_proper_imp_size_less:
 | 
|  |    185 |   assumes "a dvd b" "\<not> b dvd a" "b \<noteq> 0" 
 | 
|  |    186 |   shows   "euclidean_size a < euclidean_size b"
 | 
|  |    187 | proof -
 | 
|  |    188 |   from assms(1) obtain c where "b = a * c" by (erule dvdE)
 | 
|  |    189 |   hence z: "b = c * a" by (simp add: mult.commute)
 | 
|  |    190 |   from z assms have "\<not>is_unit c" by (auto simp: mult.commute mult_unit_dvd_iff)
 | 
|  |    191 |   with z assms show ?thesis
 | 
|  |    192 |     by (auto intro!: euclidean_size_times_nonunit)
 | 
|  |    193 | qed
 | 
|  |    194 | 
 | 
|  |    195 | end
 | 
|  |    196 | 
 | 
|  |    197 | class euclidean_ring = idom_modulo + euclidean_semiring
 | 
|  |    198 | 
 | 
|  |    199 |   
 | 
|  |    200 | subsection \<open>Uniquely determined division\<close>
 | 
|  |    201 |   
 | 
|  |    202 | class unique_euclidean_semiring = euclidean_semiring + 
 | 
|  |    203 |   fixes uniqueness_constraint :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
 | 
|  |    204 |   assumes size_mono_mult:
 | 
|  |    205 |     "b \<noteq> 0 \<Longrightarrow> euclidean_size a < euclidean_size c
 | 
|  |    206 |       \<Longrightarrow> euclidean_size (a * b) < euclidean_size (c * b)"
 | 
|  |    207 |     -- \<open>FIXME justify\<close>
 | 
|  |    208 |   assumes uniqueness_constraint_mono_mult:
 | 
|  |    209 |     "uniqueness_constraint a b \<Longrightarrow> uniqueness_constraint (a * c) (b * c)"
 | 
|  |    210 |   assumes uniqueness_constraint_mod:
 | 
|  |    211 |     "b \<noteq> 0 \<Longrightarrow> \<not> b dvd a \<Longrightarrow> uniqueness_constraint (a mod b) b"
 | 
|  |    212 |   assumes div_bounded:
 | 
|  |    213 |     "b \<noteq> 0 \<Longrightarrow> uniqueness_constraint r b
 | 
|  |    214 |     \<Longrightarrow> euclidean_size r < euclidean_size b
 | 
|  |    215 |     \<Longrightarrow> (q * b + r) div b = q"
 | 
|  |    216 | begin
 | 
|  |    217 | 
 | 
|  |    218 | lemma divmod_cases [case_names divides remainder by0]:
 | 
|  |    219 |   obtains 
 | 
|  |    220 |     (divides) q where "b \<noteq> 0"
 | 
|  |    221 |       and "a div b = q"
 | 
|  |    222 |       and "a mod b = 0"
 | 
|  |    223 |       and "a = q * b"
 | 
|  |    224 |   | (remainder) q r where "b \<noteq> 0" and "r \<noteq> 0"
 | 
|  |    225 |       and "uniqueness_constraint r b"
 | 
|  |    226 |       and "euclidean_size r < euclidean_size b"
 | 
|  |    227 |       and "a div b = q"
 | 
|  |    228 |       and "a mod b = r"
 | 
|  |    229 |       and "a = q * b + r"
 | 
|  |    230 |   | (by0) "b = 0"
 | 
|  |    231 | proof (cases "b = 0")
 | 
|  |    232 |   case True
 | 
|  |    233 |   then show thesis
 | 
|  |    234 |   by (rule by0)
 | 
|  |    235 | next
 | 
|  |    236 |   case False
 | 
|  |    237 |   show thesis
 | 
|  |    238 |   proof (cases "b dvd a")
 | 
|  |    239 |     case True
 | 
|  |    240 |     then obtain q where "a = b * q" ..
 | 
|  |    241 |     with \<open>b \<noteq> 0\<close> divides
 | 
|  |    242 |     show thesis
 | 
|  |    243 |       by (simp add: ac_simps)
 | 
|  |    244 |   next
 | 
|  |    245 |     case False
 | 
|  |    246 |     then have "a mod b \<noteq> 0"
 | 
|  |    247 |       by (simp add: mod_eq_0_iff_dvd)
 | 
|  |    248 |     moreover from \<open>b \<noteq> 0\<close> \<open>\<not> b dvd a\<close> have "uniqueness_constraint (a mod b) b"
 | 
|  |    249 |       by (rule uniqueness_constraint_mod)
 | 
|  |    250 |     moreover have "euclidean_size (a mod b) < euclidean_size b"
 | 
|  |    251 |       using \<open>b \<noteq> 0\<close> by (rule mod_size_less)
 | 
|  |    252 |     moreover have "a = a div b * b + a mod b"
 | 
|  |    253 |       by (simp add: div_mult_mod_eq)
 | 
|  |    254 |     ultimately show thesis
 | 
|  |    255 |       using \<open>b \<noteq> 0\<close> by (blast intro: remainder)
 | 
|  |    256 |   qed
 | 
|  |    257 | qed
 | 
|  |    258 | 
 | 
|  |    259 | lemma div_eqI:
 | 
|  |    260 |   "a div b = q" if "b \<noteq> 0" "uniqueness_constraint r b"
 | 
|  |    261 |     "euclidean_size r < euclidean_size b" "q * b + r = a"
 | 
|  |    262 | proof -
 | 
|  |    263 |   from that have "(q * b + r) div b = q"
 | 
|  |    264 |     by (auto intro: div_bounded)
 | 
|  |    265 |   with that show ?thesis
 | 
|  |    266 |     by simp
 | 
|  |    267 | qed
 | 
|  |    268 | 
 | 
|  |    269 | lemma mod_eqI:
 | 
|  |    270 |   "a mod b = r" if "b \<noteq> 0" "uniqueness_constraint r b"
 | 
|  |    271 |     "euclidean_size r < euclidean_size b" "q * b + r = a" 
 | 
|  |    272 | proof -
 | 
|  |    273 |   from that have "a div b = q"
 | 
|  |    274 |     by (rule div_eqI)
 | 
|  |    275 |   moreover have "a div b * b + a mod b = a"
 | 
|  |    276 |     by (fact div_mult_mod_eq)
 | 
|  |    277 |   ultimately have "a div b * b + a mod b = a div b * b + r"
 | 
|  |    278 |     using \<open>q * b + r = a\<close> by simp
 | 
|  |    279 |   then show ?thesis
 | 
|  |    280 |     by simp
 | 
|  |    281 | qed
 | 
|  |    282 | 
 | 
|  |    283 | end
 | 
|  |    284 | 
 | 
|  |    285 | class unique_euclidean_ring = euclidean_ring + unique_euclidean_semiring
 | 
|  |    286 | 
 | 
|  |    287 | end
 |