equal
deleted
inserted
replaced
218 then show ?thesis by (simp add: mod_div_equality) |
218 then show ?thesis by (simp add: mod_div_equality) |
219 qed |
219 qed |
220 |
220 |
221 text \<open>Addition respects modular equivalence.\<close> |
221 text \<open>Addition respects modular equivalence.\<close> |
222 |
222 |
223 lemma mod_add_left_eq: -- \<open>FIXME reorient\<close> |
223 lemma mod_add_left_eq: \<comment> \<open>FIXME reorient\<close> |
224 "(a + b) mod c = (a mod c + b) mod c" |
224 "(a + b) mod c = (a mod c + b) mod c" |
225 proof - |
225 proof - |
226 have "(a + b) mod c = (a div c * c + a mod c + b) mod c" |
226 have "(a + b) mod c = (a div c * c + a mod c + b) mod c" |
227 by (simp only: mod_div_equality) |
227 by (simp only: mod_div_equality) |
228 also have "\<dots> = (a mod c + b + a div c * c) mod c" |
228 also have "\<dots> = (a mod c + b + a div c * c) mod c" |
230 also have "\<dots> = (a mod c + b) mod c" |
230 also have "\<dots> = (a mod c + b) mod c" |
231 by (rule mod_mult_self1) |
231 by (rule mod_mult_self1) |
232 finally show ?thesis . |
232 finally show ?thesis . |
233 qed |
233 qed |
234 |
234 |
235 lemma mod_add_right_eq: -- \<open>FIXME reorient\<close> |
235 lemma mod_add_right_eq: \<comment> \<open>FIXME reorient\<close> |
236 "(a + b) mod c = (a + b mod c) mod c" |
236 "(a + b) mod c = (a + b mod c) mod c" |
237 proof - |
237 proof - |
238 have "(a + b) mod c = (a + (b div c * c + b mod c)) mod c" |
238 have "(a + b) mod c = (a + (b div c * c + b mod c)) mod c" |
239 by (simp only: mod_div_equality) |
239 by (simp only: mod_div_equality) |
240 also have "\<dots> = (a + b mod c + b div c * c) mod c" |
240 also have "\<dots> = (a + b mod c + b div c * c) mod c" |
242 also have "\<dots> = (a + b mod c) mod c" |
242 also have "\<dots> = (a + b mod c) mod c" |
243 by (rule mod_mult_self1) |
243 by (rule mod_mult_self1) |
244 finally show ?thesis . |
244 finally show ?thesis . |
245 qed |
245 qed |
246 |
246 |
247 lemma mod_add_eq: -- \<open>FIXME reorient\<close> |
247 lemma mod_add_eq: \<comment> \<open>FIXME reorient\<close> |
248 "(a + b) mod c = (a mod c + b mod c) mod c" |
248 "(a + b) mod c = (a mod c + b mod c) mod c" |
249 by (rule trans [OF mod_add_left_eq mod_add_right_eq]) |
249 by (rule trans [OF mod_add_left_eq mod_add_right_eq]) |
250 |
250 |
251 lemma mod_add_cong: |
251 lemma mod_add_cong: |
252 assumes "a mod c = a' mod c" |
252 assumes "a mod c = a' mod c" |
259 by (simp only: mod_add_eq [symmetric]) |
259 by (simp only: mod_add_eq [symmetric]) |
260 qed |
260 qed |
261 |
261 |
262 text \<open>Multiplication respects modular equivalence.\<close> |
262 text \<open>Multiplication respects modular equivalence.\<close> |
263 |
263 |
264 lemma mod_mult_left_eq: -- \<open>FIXME reorient\<close> |
264 lemma mod_mult_left_eq: \<comment> \<open>FIXME reorient\<close> |
265 "(a * b) mod c = ((a mod c) * b) mod c" |
265 "(a * b) mod c = ((a mod c) * b) mod c" |
266 proof - |
266 proof - |
267 have "(a * b) mod c = ((a div c * c + a mod c) * b) mod c" |
267 have "(a * b) mod c = ((a div c * c + a mod c) * b) mod c" |
268 by (simp only: mod_div_equality) |
268 by (simp only: mod_div_equality) |
269 also have "\<dots> = (a mod c * b + a div c * b * c) mod c" |
269 also have "\<dots> = (a mod c * b + a div c * b * c) mod c" |
271 also have "\<dots> = (a mod c * b) mod c" |
271 also have "\<dots> = (a mod c * b) mod c" |
272 by (rule mod_mult_self1) |
272 by (rule mod_mult_self1) |
273 finally show ?thesis . |
273 finally show ?thesis . |
274 qed |
274 qed |
275 |
275 |
276 lemma mod_mult_right_eq: -- \<open>FIXME reorient\<close> |
276 lemma mod_mult_right_eq: \<comment> \<open>FIXME reorient\<close> |
277 "(a * b) mod c = (a * (b mod c)) mod c" |
277 "(a * b) mod c = (a * (b mod c)) mod c" |
278 proof - |
278 proof - |
279 have "(a * b) mod c = (a * (b div c * c + b mod c)) mod c" |
279 have "(a * b) mod c = (a * (b div c * c + b mod c)) mod c" |
280 by (simp only: mod_div_equality) |
280 by (simp only: mod_div_equality) |
281 also have "\<dots> = (a * (b mod c) + a * (b div c) * c) mod c" |
281 also have "\<dots> = (a * (b mod c) + a * (b div c) * c) mod c" |
283 also have "\<dots> = (a * (b mod c)) mod c" |
283 also have "\<dots> = (a * (b mod c)) mod c" |
284 by (rule mod_mult_self1) |
284 by (rule mod_mult_self1) |
285 finally show ?thesis . |
285 finally show ?thesis . |
286 qed |
286 qed |
287 |
287 |
288 lemma mod_mult_eq: -- \<open>FIXME reorient\<close> |
288 lemma mod_mult_eq: \<comment> \<open>FIXME reorient\<close> |
289 "(a * b) mod c = ((a mod c) * (b mod c)) mod c" |
289 "(a * b) mod c = ((a mod c) * (b mod c)) mod c" |
290 by (rule trans [OF mod_mult_left_eq mod_mult_right_eq]) |
290 by (rule trans [OF mod_mult_left_eq mod_mult_right_eq]) |
291 |
291 |
292 lemma mod_mult_cong: |
292 lemma mod_mult_cong: |
293 assumes "a mod c = a' mod c" |
293 assumes "a mod c = a' mod c" |
571 and divmod_step :: "num \<Rightarrow> 'a \<times> 'a \<Rightarrow> 'a \<times> 'a" |
571 and divmod_step :: "num \<Rightarrow> 'a \<times> 'a \<Rightarrow> 'a \<times> 'a" |
572 assumes divmod_def: "divmod m n = (numeral m div numeral n, numeral m mod numeral n)" |
572 assumes divmod_def: "divmod m n = (numeral m div numeral n, numeral m mod numeral n)" |
573 and divmod_step_def: "divmod_step l qr = (let (q, r) = qr |
573 and divmod_step_def: "divmod_step l qr = (let (q, r) = qr |
574 in if r \<ge> numeral l then (2 * q + 1, r - numeral l) |
574 in if r \<ge> numeral l then (2 * q + 1, r - numeral l) |
575 else (2 * q, r))" |
575 else (2 * q, r))" |
576 -- \<open>These are conceptually definitions but force generated code |
576 \<comment> \<open>These are conceptually definitions but force generated code |
577 to be monomorphic wrt. particular instances of this class which |
577 to be monomorphic wrt. particular instances of this class which |
578 yields a significant speedup.\<close> |
578 yields a significant speedup.\<close> |
579 |
579 |
580 begin |
580 begin |
581 |
581 |
731 then have "divmod m n = divmod_step n (divmod m (Num.Bit0 n))" |
731 then have "divmod m n = divmod_step n (divmod m (Num.Bit0 n))" |
732 by (simp add: divmod_def) |
732 by (simp add: divmod_def) |
733 with False show ?thesis by simp |
733 with False show ?thesis by simp |
734 qed |
734 qed |
735 |
735 |
736 text \<open>The division rewrite proper -- first, trivial results involving @{text 1}\<close> |
736 text \<open>The division rewrite proper -- first, trivial results involving \<open>1\<close>\<close> |
737 |
737 |
738 lemma divmod_trivial [simp]: |
738 lemma divmod_trivial [simp]: |
739 "divmod Num.One Num.One = (numeral Num.One, 0)" |
739 "divmod Num.One Num.One = (numeral Num.One, 0)" |
740 "divmod (Num.Bit0 m) Num.One = (numeral (Num.Bit0 m), 0)" |
740 "divmod (Num.Bit0 m) Num.One = (numeral (Num.Bit0 m), 0)" |
741 "divmod (Num.Bit1 m) Num.One = (numeral (Num.Bit1 m), 0)" |
741 "divmod (Num.Bit1 m) Num.One = (numeral (Num.Bit1 m), 0)" |
1426 have "\<forall>k. 0<k \<longrightarrow> \<not> P (p-k)" (is "\<forall>k. ?A k") |
1426 have "\<forall>k. 0<k \<longrightarrow> \<not> P (p-k)" (is "\<forall>k. ?A k") |
1427 proof |
1427 proof |
1428 fix k |
1428 fix k |
1429 show "?A k" |
1429 show "?A k" |
1430 proof (induct k) |
1430 proof (induct k) |
1431 show "?A 0" by simp -- "by contradiction" |
1431 show "?A 0" by simp \<comment> "by contradiction" |
1432 next |
1432 next |
1433 fix n |
1433 fix n |
1434 assume ih: "?A n" |
1434 assume ih: "?A n" |
1435 show "?A (Suc n)" |
1435 show "?A (Suc n)" |
1436 proof (clarsimp) |
1436 proof (clarsimp) |
1636 by (simp_all add: snd_divmod) |
1636 by (simp_all add: snd_divmod) |
1637 |
1637 |
1638 |
1638 |
1639 subsection \<open>Division on @{typ int}\<close> |
1639 subsection \<open>Division on @{typ int}\<close> |
1640 |
1640 |
1641 definition divmod_int_rel :: "int \<Rightarrow> int \<Rightarrow> int \<times> int \<Rightarrow> bool" -- \<open>definition of quotient and remainder\<close> |
1641 definition divmod_int_rel :: "int \<Rightarrow> int \<Rightarrow> int \<times> int \<Rightarrow> bool" \<comment> \<open>definition of quotient and remainder\<close> |
1642 where "divmod_int_rel a b = (\<lambda>(q, r). a = b * q + r \<and> |
1642 where "divmod_int_rel a b = (\<lambda>(q, r). a = b * q + r \<and> |
1643 (if 0 < b then 0 \<le> r \<and> r < b else if b < 0 then b < r \<and> r \<le> 0 else q = 0))" |
1643 (if 0 < b then 0 \<le> r \<and> r < b else if b < 0 then b < r \<and> r \<le> 0 else q = 0))" |
1644 |
1644 |
1645 lemma unique_quotient_lemma: |
1645 lemma unique_quotient_lemma: |
1646 "b * q' + r' \<le> b * q + r \<Longrightarrow> 0 \<le> r' \<Longrightarrow> r' < b \<Longrightarrow> r < b \<Longrightarrow> q' \<le> (q::int)" |
1646 "b * q' + r' \<le> b * q + r \<Longrightarrow> 0 \<le> r' \<Longrightarrow> r' < b \<Longrightarrow> r < b \<Longrightarrow> q' \<le> (q::int)" |
1858 lemma mod_pos_neg_trivial: "[| (0::int) < a; a+b \<le> 0 |] ==> a mod b = a+b" |
1858 lemma mod_pos_neg_trivial: "[| (0::int) < a; a+b \<le> 0 |] ==> a mod b = a+b" |
1859 apply (rule_tac q = "-1" in mod_int_unique) |
1859 apply (rule_tac q = "-1" in mod_int_unique) |
1860 apply (auto simp add: divmod_int_rel_def) |
1860 apply (auto simp add: divmod_int_rel_def) |
1861 done |
1861 done |
1862 |
1862 |
1863 text\<open>There is no @{text mod_neg_pos_trivial}.\<close> |
1863 text\<open>There is no \<open>mod_neg_pos_trivial\<close>.\<close> |
1864 |
1864 |
1865 |
1865 |
1866 subsubsection \<open>Laws for div and mod with Unary Minus\<close> |
1866 subsubsection \<open>Laws for div and mod with Unary Minus\<close> |
1867 |
1867 |
1868 lemma zminus1_lemma: |
1868 lemma zminus1_lemma: |
2168 @{term "numeral k"}:\<close> |
2168 @{term "numeral k"}:\<close> |
2169 declare split_zdiv [of _ _ "numeral k", arith_split] for k |
2169 declare split_zdiv [of _ _ "numeral k", arith_split] for k |
2170 declare split_zmod [of _ _ "numeral k", arith_split] for k |
2170 declare split_zmod [of _ _ "numeral k", arith_split] for k |
2171 |
2171 |
2172 |
2172 |
2173 subsubsection \<open>Computing @{text "div"} and @{text "mod"} with shifting\<close> |
2173 subsubsection \<open>Computing \<open>div\<close> and \<open>mod\<close> with shifting\<close> |
2174 |
2174 |
2175 lemma pos_divmod_int_rel_mult_2: |
2175 lemma pos_divmod_int_rel_mult_2: |
2176 assumes "0 \<le> b" |
2176 assumes "0 \<le> b" |
2177 assumes "divmod_int_rel a b (q, r)" |
2177 assumes "divmod_int_rel a b (q, r)" |
2178 shows "divmod_int_rel (1 + 2*a) (2*b) (q, 1 + 2*r)" |
2178 shows "divmod_int_rel (1 + 2*a) (2*b) (q, 1 + 2*r)" |
2270 by (drule zdiv_mono1_neg, auto) |
2270 by (drule zdiv_mono1_neg, auto) |
2271 |
2271 |
2272 lemma div_nonpos_pos_le0: "[| (a::int) \<le> 0; b > 0 |] ==> a div b \<le> 0" |
2272 lemma div_nonpos_pos_le0: "[| (a::int) \<le> 0; b > 0 |] ==> a div b \<le> 0" |
2273 by (drule zdiv_mono1, auto) |
2273 by (drule zdiv_mono1, auto) |
2274 |
2274 |
2275 text\<open>Now for some equivalences of the form @{text"a div b >=< 0 \<longleftrightarrow> \<dots>"} |
2275 text\<open>Now for some equivalences of the form \<open>a div b >=< 0 \<longleftrightarrow> \<dots>\<close> |
2276 conditional upon the sign of @{text a} or @{text b}. There are many more. |
2276 conditional upon the sign of \<open>a\<close> or \<open>b\<close>. There are many more. |
2277 They should all be simp rules unless that causes too much search.\<close> |
2277 They should all be simp rules unless that causes too much search.\<close> |
2278 |
2278 |
2279 lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)" |
2279 lemma pos_imp_zdiv_nonneg_iff: "(0::int) < b ==> (0 \<le> a div b) = (0 \<le> a)" |
2280 apply auto |
2280 apply auto |
2281 apply (drule_tac [2] zdiv_mono1) |
2281 apply (drule_tac [2] zdiv_mono1) |
2464 mod_mult_right_eq[symmetric] |
2464 mod_mult_right_eq[symmetric] |
2465 mod_mult_left_eq [symmetric] |
2465 mod_mult_left_eq [symmetric] |
2466 power_mod |
2466 power_mod |
2467 zminus_zmod zdiff_zmod_left zdiff_zmod_right |
2467 zminus_zmod zdiff_zmod_left zdiff_zmod_right |
2468 |
2468 |
2469 text \<open>Distributive laws for function @{text nat}.\<close> |
2469 text \<open>Distributive laws for function \<open>nat\<close>.\<close> |
2470 |
2470 |
2471 lemma nat_div_distrib: "0 \<le> x \<Longrightarrow> nat (x div y) = nat x div nat y" |
2471 lemma nat_div_distrib: "0 \<le> x \<Longrightarrow> nat (x div y) = nat x div nat y" |
2472 apply (rule linorder_cases [of y 0]) |
2472 apply (rule linorder_cases [of y 0]) |
2473 apply (simp add: div_nonneg_neg_le0) |
2473 apply (simp add: div_nonneg_neg_le0) |
2474 apply simp |
2474 apply simp |