17 and mod :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "mod" 70) |
17 and mod :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" (infixl "mod" 70) |
18 |
18 |
19 |
19 |
20 subsection {* Abstract division in commutative semirings. *} |
20 subsection {* Abstract division in commutative semirings. *} |
21 |
21 |
22 class semiring_div = comm_semiring_1_cancel + div + |
22 class semiring_div = comm_semiring_1_cancel + no_zero_divisors + div + |
23 assumes mod_div_equality: "a div b * b + a mod b = a" |
23 assumes mod_div_equality: "a div b * b + a mod b = a" |
24 and div_by_0 [simp]: "a div 0 = 0" |
24 and div_by_0 [simp]: "a div 0 = 0" |
25 and div_0 [simp]: "0 div a = 0" |
25 and div_0 [simp]: "0 div a = 0" |
26 and div_mult_self1 [simp]: "b \<noteq> 0 \<Longrightarrow> (a + c * b) div b = c + a div b" |
26 and div_mult_self1 [simp]: "b \<noteq> 0 \<Longrightarrow> (a + c * b) div b = c + a div b" |
|
27 and div_mult_mult1 [simp]: "c \<noteq> 0 \<Longrightarrow> (c * a) div (c * b) = a div b" |
27 begin |
28 begin |
28 |
29 |
29 text {* @{const div} and @{const mod} *} |
30 text {* @{const div} and @{const mod} *} |
30 |
31 |
31 lemma mod_div_equality2: "b * (a div b) + a mod b = a" |
32 lemma mod_div_equality2: "b * (a div b) + a mod b = a" |
294 also have "\<dots> = a mod c" |
295 also have "\<dots> = a mod c" |
295 by (simp only: mod_div_equality) |
296 by (simp only: mod_div_equality) |
296 finally show ?thesis . |
297 finally show ?thesis . |
297 qed |
298 qed |
298 |
299 |
299 end |
300 lemma div_mult_div_if_dvd: |
300 |
301 "y dvd x \<Longrightarrow> z dvd w \<Longrightarrow> (x div y) * (w div z) = (x * w) div (y * z)" |
301 lemma div_mult_div_if_dvd: "(y::'a::{semiring_div,no_zero_divisors}) dvd x \<Longrightarrow> |
302 apply (cases "y = 0", simp) |
302 z dvd w \<Longrightarrow> (x div y) * (w div z) = (x * w) div (y * z)" |
303 apply (cases "z = 0", simp) |
303 unfolding dvd_def |
304 apply (auto elim!: dvdE simp add: algebra_simps) |
304 apply clarify |
|
305 apply (case_tac "y = 0") |
|
306 apply simp |
|
307 apply (case_tac "z = 0") |
|
308 apply simp |
|
309 apply (simp add: algebra_simps) |
|
310 apply (subst mult_assoc [symmetric]) |
305 apply (subst mult_assoc [symmetric]) |
311 apply (simp add: no_zero_divisors) |
306 apply (simp add: no_zero_divisors) |
312 done |
307 done |
313 |
308 |
|
309 lemma div_mult_mult2 [simp]: |
|
310 "c \<noteq> 0 \<Longrightarrow> (a * c) div (b * c) = a div b" |
|
311 by (drule div_mult_mult1) (simp add: mult_commute) |
|
312 |
|
313 lemma div_mult_mult1_if [simp]: |
|
314 "(c * a) div (c * b) = (if c = 0 then 0 else a div b)" |
|
315 by simp_all |
|
316 |
|
317 lemma mod_mult_mult1: |
|
318 "(c * a) mod (c * b) = c * (a mod b)" |
|
319 proof (cases "c = 0") |
|
320 case True then show ?thesis by simp |
|
321 next |
|
322 case False |
|
323 from mod_div_equality |
|
324 have "((c * a) div (c * b)) * (c * b) + (c * a) mod (c * b) = c * a" . |
|
325 with False have "c * ((a div b) * b + a mod b) + (c * a) mod (c * b) |
|
326 = c * a + c * (a mod b)" by (simp add: algebra_simps) |
|
327 with mod_div_equality show ?thesis by simp |
|
328 qed |
|
329 |
|
330 lemma mod_mult_mult2: |
|
331 "(a * c) mod (b * c) = (a mod b) * c" |
|
332 using mod_mult_mult1 [of c a b] by (simp add: mult_commute) |
|
333 |
|
334 end |
314 |
335 |
315 lemma div_power: "(y::'a::{semiring_div,no_zero_divisors,recpower}) dvd x \<Longrightarrow> |
336 lemma div_power: "(y::'a::{semiring_div,no_zero_divisors,recpower}) dvd x \<Longrightarrow> |
316 (x div y)^n = x^n div y^n" |
337 (x div y)^n = x^n div y^n" |
317 apply (induct n) |
338 apply (induct n) |
318 apply simp |
339 apply simp |
564 fixes m n :: nat |
585 fixes m n :: nat |
565 assumes "n \<le> m" |
586 assumes "n \<le> m" |
566 shows "m mod n = (m - n) mod n" |
587 shows "m mod n = (m - n) mod n" |
567 using assms divmod_step divmod_div_mod by (cases "n = 0") simp_all |
588 using assms divmod_step divmod_div_mod by (cases "n = 0") simp_all |
568 |
589 |
569 instance proof |
590 instance proof - |
570 fix m n :: nat show "m div n * n + m mod n = m" |
591 have [simp]: "\<And>n::nat. n div 0 = 0" |
571 using divmod_rel [of m n] by (simp add: divmod_rel_def) |
592 by (simp add: div_nat_def divmod_zero) |
572 next |
593 have [simp]: "\<And>n::nat. 0 div n = 0" |
573 fix n :: nat show "n div 0 = 0" |
594 proof - |
574 using divmod_zero divmod_div_mod [of n 0] by simp |
595 fix n :: nat |
575 next |
596 show "0 div n = 0" |
576 fix n :: nat show "0 div n = 0" |
597 by (cases "n = 0") simp_all |
577 using divmod_rel [of 0 n] by (cases n) (simp_all add: divmod_rel_def) |
598 qed |
578 next |
599 show "OFCLASS(nat, semiring_div_class)" proof |
579 fix m n q :: nat assume "n \<noteq> 0" then show "(q + m * n) div n = m + q div n" |
600 fix m n :: nat |
580 by (induct m) (simp_all add: le_div_geq) |
601 show "m div n * n + m mod n = m" |
|
602 using divmod_rel [of m n] by (simp add: divmod_rel_def) |
|
603 next |
|
604 fix m n q :: nat |
|
605 assume "n \<noteq> 0" |
|
606 then show "(q + m * n) div n = m + q div n" |
|
607 by (induct m) (simp_all add: le_div_geq) |
|
608 next |
|
609 fix m n q :: nat |
|
610 assume "m \<noteq> 0" |
|
611 then show "(m * n) div (m * q) = n div q" |
|
612 proof (cases "n \<noteq> 0 \<and> q \<noteq> 0") |
|
613 case False then show ?thesis by auto |
|
614 next |
|
615 case True with `m \<noteq> 0` |
|
616 have "m > 0" and "n > 0" and "q > 0" by auto |
|
617 then have "\<And>a b. divmod_rel n q (a, b) \<Longrightarrow> divmod_rel (m * n) (m * q) (a, m * b)" |
|
618 by (auto simp add: divmod_rel_def) (simp_all add: algebra_simps) |
|
619 moreover from divmod_rel have "divmod_rel n q (n div q, n mod q)" . |
|
620 ultimately have "divmod_rel (m * n) (m * q) (n div q, m * (n mod q))" . |
|
621 then show ?thesis by (simp add: div_eq) |
|
622 qed |
|
623 qed simp_all |
581 qed |
624 qed |
582 |
625 |
583 end |
626 end |
584 |
627 |
585 text {* Simproc for cancelling @{const div} and @{const mod} *} |
628 text {* Simproc for cancelling @{const div} and @{const mod} *} |
739 |
782 |
740 lemma mod_mult2_eq: "a mod (b*c) = b*(a div b mod c) + a mod (b::nat)" |
783 lemma mod_mult2_eq: "a mod (b*c) = b*(a div b mod c) + a mod (b::nat)" |
741 apply (cases "b = 0", simp) |
784 apply (cases "b = 0", simp) |
742 apply (cases "c = 0", simp) |
785 apply (cases "c = 0", simp) |
743 apply (auto simp add: mult_commute divmod_rel [THEN divmod_rel_mult2_eq, THEN mod_eq]) |
786 apply (auto simp add: mult_commute divmod_rel [THEN divmod_rel_mult2_eq, THEN mod_eq]) |
744 done |
|
745 |
|
746 |
|
747 subsubsection{*Cancellation of Common Factors in Division*} |
|
748 |
|
749 lemma div_mult_mult_lemma: |
|
750 "[| (0::nat) < b; 0 < c |] ==> (c*a) div (c*b) = a div b" |
|
751 by (auto simp add: div_mult2_eq) |
|
752 |
|
753 lemma div_mult_mult1 [simp]: "(0::nat) < c ==> (c*a) div (c*b) = a div b" |
|
754 apply (cases "b = 0") |
|
755 apply (auto simp add: linorder_neq_iff [of b] div_mult_mult_lemma) |
|
756 done |
|
757 |
|
758 lemma div_mult_mult2 [simp]: "(0::nat) < c ==> (a*c) div (b*c) = a div b" |
|
759 apply (drule div_mult_mult1) |
|
760 apply (auto simp add: mult_commute) |
|
761 done |
787 done |
762 |
788 |
763 |
789 |
764 subsubsection{*Further Facts about Quotient and Remainder*} |
790 subsubsection{*Further Facts about Quotient and Remainder*} |
765 |
791 |