src/HOL/Divides.thy
changeset 30240 5b25fee0362c
parent 29948 cdf12a1cb963
child 30242 aea5d7fa7ef5
equal deleted inserted replaced
30239:179ff9cb160b 30240:5b25fee0362c
    42 
    42 
    43 lemma div_mod_equality2: "(b * (a div b) + a mod b) + c = a + c"
    43 lemma div_mod_equality2: "(b * (a div b) + a mod b) + c = a + c"
    44 by (simp add: mod_div_equality2)
    44 by (simp add: mod_div_equality2)
    45 
    45 
    46 lemma mod_by_0 [simp]: "a mod 0 = a"
    46 lemma mod_by_0 [simp]: "a mod 0 = a"
    47   using mod_div_equality [of a zero] by simp
    47 using mod_div_equality [of a zero] by simp
    48 
    48 
    49 lemma mod_0 [simp]: "0 mod a = 0"
    49 lemma mod_0 [simp]: "0 mod a = 0"
    50   using mod_div_equality [of zero a] div_0 by simp 
    50 using mod_div_equality [of zero a] div_0 by simp
    51 
    51 
    52 lemma div_mult_self2 [simp]:
    52 lemma div_mult_self2 [simp]:
    53   assumes "b \<noteq> 0"
    53   assumes "b \<noteq> 0"
    54   shows "(a + b * c) div b = c + a div b"
    54   shows "(a + b * c) div b = c + a div b"
    55   using assms div_mult_self1 [of b a c] by (simp add: mult_commute)
    55   using assms div_mult_self1 [of b a c] by (simp add: mult_commute)
   176 by (rule dvd_eq_mod_eq_0[THEN iffD1])
   176 by (rule dvd_eq_mod_eq_0[THEN iffD1])
   177 
   177 
   178 lemma dvd_div_mult_self: "a dvd b \<Longrightarrow> (b div a) * a = b"
   178 lemma dvd_div_mult_self: "a dvd b \<Longrightarrow> (b div a) * a = b"
   179 by (subst (2) mod_div_equality [of b a, symmetric]) (simp add:dvd_imp_mod_0)
   179 by (subst (2) mod_div_equality [of b a, symmetric]) (simp add:dvd_imp_mod_0)
   180 
   180 
       
   181 lemma dvd_div_mult: "a dvd b \<Longrightarrow> (b div a) * c = b * c div a"
       
   182 apply (cases "a = 0")
       
   183  apply simp
       
   184 apply (auto simp: dvd_def mult_assoc)
       
   185 done
       
   186 
   181 lemma div_dvd_div[simp]:
   187 lemma div_dvd_div[simp]:
   182   "a dvd b \<Longrightarrow> a dvd c \<Longrightarrow> (b div a dvd c div a) = (b dvd c)"
   188   "a dvd b \<Longrightarrow> a dvd c \<Longrightarrow> (b div a dvd c div a) = (b dvd c)"
   183 apply (cases "a = 0")
   189 apply (cases "a = 0")
   184  apply simp
   190  apply simp
   185 apply (unfold dvd_def)
   191 apply (unfold dvd_def)
   186 apply auto
   192 apply auto
   187  apply(blast intro:mult_assoc[symmetric])
   193  apply(blast intro:mult_assoc[symmetric])
   188 apply(fastsimp simp add: mult_assoc)
   194 apply(fastsimp simp add: mult_assoc)
   189 done
   195 done
       
   196 
       
   197 lemma dvd_mod_imp_dvd: "[| k dvd m mod n;  k dvd n |] ==> k dvd m"
       
   198   apply (subgoal_tac "k dvd (m div n) *n + m mod n")
       
   199    apply (simp add: mod_div_equality)
       
   200   apply (simp only: dvd_add dvd_mult)
       
   201   done
   190 
   202 
   191 text {* Addition respects modular equivalence. *}
   203 text {* Addition respects modular equivalence. *}
   192 
   204 
   193 lemma mod_add_left_eq: "(a + b) mod c = (a mod c + b) mod c"
   205 lemma mod_add_left_eq: "(a + b) mod c = (a mod c + b) mod c"
   194 proof -
   206 proof -
   327   assumes "a mod c = a' mod c"
   339   assumes "a mod c = a' mod c"
   328   assumes "b mod c = b' mod c"
   340   assumes "b mod c = b' mod c"
   329   shows "(a - b) mod c = (a' - b') mod c"
   341   shows "(a - b) mod c = (a' - b') mod c"
   330   unfolding diff_minus using assms
   342   unfolding diff_minus using assms
   331   by (intro mod_add_cong mod_minus_cong)
   343   by (intro mod_add_cong mod_minus_cong)
       
   344 
       
   345 lemma dvd_neg_div: "y dvd x \<Longrightarrow> -x div y = - (x div y)"
       
   346 apply (case_tac "y = 0") apply simp
       
   347 apply (auto simp add: dvd_def)
       
   348 apply (subgoal_tac "-(y * k) = y * - k")
       
   349  apply (erule ssubst)
       
   350  apply (erule div_mult_self1_is_id)
       
   351 apply simp
       
   352 done
       
   353 
       
   354 lemma dvd_div_neg: "y dvd x \<Longrightarrow> x div -y = - (x div y)"
       
   355 apply (case_tac "y = 0") apply simp
       
   356 apply (auto simp add: dvd_def)
       
   357 apply (subgoal_tac "y * k = -y * -k")
       
   358  apply (erule ssubst)
       
   359  apply (rule div_mult_self1_is_id)
       
   360  apply simp
       
   361 apply simp
       
   362 done
   332 
   363 
   333 end
   364 end
   334 
   365 
   335 
   366 
   336 subsection {* Division on @{typ nat} *}
   367 subsection {* Division on @{typ nat} *}
   476   shows "divmod m n = (Suc ((m - n) div n), (m - n) mod n)"
   507   shows "divmod m n = (Suc ((m - n) div n), (m - n) mod n)"
   477 proof -
   508 proof -
   478   from divmod_rel have divmod_m_n: "divmod_rel m n (m div n) (m mod n)" .
   509   from divmod_rel have divmod_m_n: "divmod_rel m n (m div n) (m mod n)" .
   479   with assms have m_div_n: "m div n \<ge> 1"
   510   with assms have m_div_n: "m div n \<ge> 1"
   480     by (cases "m div n") (auto simp add: divmod_rel_def)
   511     by (cases "m div n") (auto simp add: divmod_rel_def)
   481   from assms divmod_m_n have "divmod_rel (m - n) n (m div n - 1) (m mod n)"
   512   from assms divmod_m_n have "divmod_rel (m - n) n (m div n - Suc 0) (m mod n)"
   482     by (cases "m div n") (auto simp add: divmod_rel_def)
   513     by (cases "m div n") (auto simp add: divmod_rel_def)
   483   with divmod_eq have "divmod (m - n) n = (m div n - 1, m mod n)" by simp
   514   with divmod_eq have "divmod (m - n) n = (m div n - Suc 0, m mod n)" by simp
   484   moreover from divmod_div_mod have "divmod (m - n) n = ((m - n) div n, (m - n) mod n)" .
   515   moreover from divmod_div_mod have "divmod (m - n) n = ((m - n) div n, (m - n) mod n)" .
   485   ultimately have "m div n = Suc ((m - n) div n)"
   516   ultimately have "m div n = Suc ((m - n) div n)"
   486     and "m mod n = (m - n) mod n" using m_div_n by simp_all
   517     and "m mod n = (m - n) mod n" using m_div_n by simp_all
   487   then show ?thesis using divmod_div_mod by simp
   518   then show ?thesis using divmod_div_mod by simp
   488 qed
   519 qed
   651 lemma div_mult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::nat)"
   682 lemma div_mult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::nat)"
   652 apply (cases "c = 0", simp)
   683 apply (cases "c = 0", simp)
   653 apply (blast intro: divmod_rel [THEN divmod_rel_mult1_eq, THEN div_eq])
   684 apply (blast intro: divmod_rel [THEN divmod_rel_mult1_eq, THEN div_eq])
   654 done
   685 done
   655 
   686 
   656 lemma mod_mult1_eq: "(a*b) mod c = a*(b mod c) mod (c::nat)"
       
   657 by (rule mod_mult_right_eq)
       
   658 
       
   659 lemma mod_mult1_eq': "(a*b) mod (c::nat) = ((a mod c) * b) mod c"
       
   660 by (rule mod_mult_left_eq)
       
   661 
       
   662 lemma mod_mult_distrib_mod:
       
   663   "(a*b) mod (c::nat) = ((a mod c) * (b mod c)) mod c"
       
   664 by (rule mod_mult_eq)
       
   665 
       
   666 lemma divmod_rel_add1_eq:
   687 lemma divmod_rel_add1_eq:
   667   "[| divmod_rel a c aq ar; divmod_rel b c bq br;  c > 0 |]
   688   "[| divmod_rel a c aq ar; divmod_rel b c bq br;  c > 0 |]
   668    ==> divmod_rel (a + b) c (aq + bq + (ar+br) div c) ((ar + br) mod c)"
   689    ==> divmod_rel (a + b) c (aq + bq + (ar+br) div c) ((ar + br) mod c)"
   669 by (auto simp add: split_ifs divmod_rel_def algebra_simps)
   690 by (auto simp add: split_ifs divmod_rel_def algebra_simps)
   670 
   691 
   672 lemma div_add1_eq:
   693 lemma div_add1_eq:
   673   "(a+b) div (c::nat) = a div c + b div c + ((a mod c + b mod c) div c)"
   694   "(a+b) div (c::nat) = a div c + b div c + ((a mod c + b mod c) div c)"
   674 apply (cases "c = 0", simp)
   695 apply (cases "c = 0", simp)
   675 apply (blast intro: divmod_rel_add1_eq [THEN div_eq] divmod_rel)
   696 apply (blast intro: divmod_rel_add1_eq [THEN div_eq] divmod_rel)
   676 done
   697 done
   677 
       
   678 lemma mod_add1_eq: "(a+b) mod (c::nat) = (a mod c + b mod c) mod c"
       
   679 by (rule mod_add_eq)
       
   680 
   698 
   681 lemma mod_lemma: "[| (0::nat) < c; r < b |] ==> b * (q mod c) + r < b * c"
   699 lemma mod_lemma: "[| (0::nat) < c; r < b |] ==> b * (q mod c) + r < b * c"
   682   apply (cut_tac m = q and n = c in mod_less_divisor)
   700   apply (cut_tac m = q and n = c in mod_less_divisor)
   683   apply (drule_tac [2] m = "q mod c" in less_imp_Suc_add, auto)
   701   apply (drule_tac [2] m = "q mod c" in less_imp_Suc_add, auto)
   684   apply (erule_tac P = "%x. ?lhs < ?rhs x" in ssubst)
   702   apply (erule_tac P = "%x. ?lhs < ?rhs x" in ssubst)
   793 (* case n \<le> Suc(na) *)
   811 (* case n \<le> Suc(na) *)
   794 apply (simp add: linorder_not_less le_Suc_eq mod_geq)
   812 apply (simp add: linorder_not_less le_Suc_eq mod_geq)
   795 apply (auto simp add: Suc_diff_le le_mod_geq)
   813 apply (auto simp add: Suc_diff_le le_mod_geq)
   796 done
   814 done
   797 
   815 
   798 lemma nat_mod_div_trivial: "m mod n div n = (0 :: nat)"
       
   799 by simp
       
   800 
       
   801 lemma nat_mod_mod_trivial: "m mod n mod n = (m mod n :: nat)"
       
   802 by simp
       
   803 
       
   804 
   816 
   805 subsubsection {* The Divides Relation *}
   817 subsubsection {* The Divides Relation *}
   806 
   818 
   807 lemma dvd_1_left [iff]: "Suc 0 dvd k"
   819 lemma dvd_1_left [iff]: "Suc 0 dvd k"
   808   unfolding dvd_def by simp
   820   unfolding dvd_def by simp
   809 
   821 
   810 lemma dvd_1_iff_1 [simp]: "(m dvd Suc 0) = (m = Suc 0)"
   822 lemma dvd_1_iff_1 [simp]: "(m dvd Suc 0) = (m = Suc 0)"
       
   823 by (simp add: dvd_def)
       
   824 
       
   825 lemma nat_dvd_1_iff_1 [simp]: "m dvd (1::nat) \<longleftrightarrow> m = 1"
   811 by (simp add: dvd_def)
   826 by (simp add: dvd_def)
   812 
   827 
   813 lemma dvd_anti_sym: "[| m dvd n; n dvd m |] ==> m = (n::nat)"
   828 lemma dvd_anti_sym: "[| m dvd n; n dvd m |] ==> m = (n::nat)"
   814   unfolding dvd_def
   829   unfolding dvd_def
   815   by (force dest: mult_eq_self_implies_10 simp add: mult_assoc mult_eq_1_iff)
   830   by (force dest: mult_eq_self_implies_10 simp add: mult_assoc mult_eq_1_iff)
   817 text {* @{term "op dvd"} is a partial order *}
   832 text {* @{term "op dvd"} is a partial order *}
   818 
   833 
   819 interpretation dvd!: order "op dvd" "\<lambda>n m \<Colon> nat. n dvd m \<and> \<not> m dvd n"
   834 interpretation dvd!: order "op dvd" "\<lambda>n m \<Colon> nat. n dvd m \<and> \<not> m dvd n"
   820   proof qed (auto intro: dvd_refl dvd_trans dvd_anti_sym)
   835   proof qed (auto intro: dvd_refl dvd_trans dvd_anti_sym)
   821 
   836 
   822 lemma dvd_diff: "[| k dvd m; k dvd n |] ==> k dvd (m-n :: nat)"
   837 lemma nat_dvd_diff[simp]: "[| k dvd m; k dvd n |] ==> k dvd (m-n :: nat)"
   823   unfolding dvd_def
   838 unfolding dvd_def
   824   by (blast intro: diff_mult_distrib2 [symmetric])
   839 by (blast intro: diff_mult_distrib2 [symmetric])
   825 
   840 
   826 lemma dvd_diffD: "[| k dvd m-n; k dvd n; n\<le>m |] ==> k dvd (m::nat)"
   841 lemma dvd_diffD: "[| k dvd m-n; k dvd n; n\<le>m |] ==> k dvd (m::nat)"
   827   apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst])
   842   apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst])
   828   apply (blast intro: dvd_add)
   843   apply (blast intro: dvd_add)
   829   done
   844   done
   830 
   845 
   831 lemma dvd_diffD1: "[| k dvd m-n; k dvd m; n\<le>m |] ==> k dvd (n::nat)"
   846 lemma dvd_diffD1: "[| k dvd m-n; k dvd m; n\<le>m |] ==> k dvd (n::nat)"
   832 by (drule_tac m = m in dvd_diff, auto)
   847 by (drule_tac m = m in nat_dvd_diff, auto)
   833 
   848 
   834 lemma dvd_reduce: "(k dvd n + k) = (k dvd (n::nat))"
   849 lemma dvd_reduce: "(k dvd n + k) = (k dvd (n::nat))"
   835   apply (rule iffI)
   850   apply (rule iffI)
   836    apply (erule_tac [2] dvd_add)
   851    apply (erule_tac [2] dvd_add)
   837    apply (rule_tac [2] dvd_refl)
   852    apply (rule_tac [2] dvd_refl)
   838   apply (subgoal_tac "n = (n+k) -k")
   853   apply (subgoal_tac "n = (n+k) -k")
   839    prefer 2 apply simp
   854    prefer 2 apply simp
   840   apply (erule ssubst)
   855   apply (erule ssubst)
   841   apply (erule dvd_diff)
   856   apply (erule nat_dvd_diff)
   842   apply (rule dvd_refl)
   857   apply (rule dvd_refl)
   843   done
   858   done
   844 
   859 
   845 lemma dvd_mod: "!!n::nat. [| f dvd m; f dvd n |] ==> f dvd m mod n"
   860 lemma dvd_mod: "!!n::nat. [| f dvd m; f dvd n |] ==> f dvd m mod n"
   846   unfolding dvd_def
   861   unfolding dvd_def
   847   apply (case_tac "n = 0", auto)
   862   apply (case_tac "n = 0", auto)
   848   apply (blast intro: mod_mult_distrib2 [symmetric])
   863   apply (blast intro: mod_mult_distrib2 [symmetric])
   849   done
       
   850 
       
   851 lemma dvd_mod_imp_dvd: "[| (k::nat) dvd m mod n;  k dvd n |] ==> k dvd m"
       
   852   apply (subgoal_tac "k dvd (m div n) *n + m mod n")
       
   853    apply (simp add: mod_div_equality)
       
   854   apply (simp only: dvd_add dvd_mult)
       
   855   done
   864   done
   856 
   865 
   857 lemma dvd_mod_iff: "k dvd n ==> ((k::nat) dvd m mod n) = (k dvd m)"
   866 lemma dvd_mod_iff: "k dvd n ==> ((k::nat) dvd m mod n) = (k dvd m)"
   858 by (blast intro: dvd_mod_imp_dvd dvd_mod)
   867 by (blast intro: dvd_mod_imp_dvd dvd_mod)
   859 
   868 
   887   apply (subgoal_tac "m mod n = 0")
   896   apply (subgoal_tac "m mod n = 0")
   888    apply (simp add: mult_div_cancel)
   897    apply (simp add: mult_div_cancel)
   889   apply (simp only: dvd_eq_mod_eq_0)
   898   apply (simp only: dvd_eq_mod_eq_0)
   890   done
   899   done
   891 
   900 
   892 lemma le_imp_power_dvd: "!!i::nat. m \<le> n ==> i^m dvd i^n"
       
   893   apply (unfold dvd_def)
       
   894   apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst])
       
   895   apply (simp add: power_add)
       
   896   done
       
   897 
       
   898 lemma nat_zero_less_power_iff [simp]: "(x^n > 0) = (x > (0::nat) | n=0)"
   901 lemma nat_zero_less_power_iff [simp]: "(x^n > 0) = (x > (0::nat) | n=0)"
   899   by (induct n) auto
   902   by (induct n) auto
   900 
       
   901 lemma power_le_dvd [rule_format]: "k^j dvd n --> i\<le>j --> k^i dvd (n::nat)"
       
   902   apply (induct j)
       
   903    apply (simp_all add: le_Suc_eq)
       
   904   apply (blast dest!: dvd_mult_right)
       
   905   done
       
   906 
   903 
   907 lemma power_dvd_imp_le: "[|i^m dvd i^n;  (1::nat) < i|] ==> m \<le> n"
   904 lemma power_dvd_imp_le: "[|i^m dvd i^n;  (1::nat) < i|] ==> m \<le> n"
   908   apply (rule power_le_imp_le_exp, assumption)
   905   apply (rule power_le_imp_le_exp, assumption)
   909   apply (erule dvd_imp_le, simp)
   906   apply (erule dvd_imp_le, simp)
   910   done
   907   done