src/HOL/Divides.thy
changeset 30930 11010e5f18f0
parent 30923 2697a1d1d34a
child 30934 ed5377c2b0a3
equal deleted inserted replaced
30929:d9343c0aac11 30930:11010e5f18f0
    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