src/HOL/Divides.thy
changeset 21408 fff1731da03b
parent 21191 c00161fbf990
child 21911 e29bcab0c81c
equal deleted inserted replaced
21407:af60523da908 21408:fff1731da03b
     5 *)
     5 *)
     6 
     6 
     7 header {* The division operators div, mod and the divides relation "dvd" *}
     7 header {* The division operators div, mod and the divides relation "dvd" *}
     8 
     8 
     9 theory Divides
     9 theory Divides
    10 imports Datatype
    10 imports Datatype Power
    11 begin
    11 begin
    12 
    12 
    13 (*We use the same class for div and mod;
    13 (*We use the same class for div and mod;
    14   moreover, dvd is defined whenever multiplication is*)
    14   moreover, dvd is defined whenever multiplication is*)
    15 axclass
    15 class div =
    16   div < type
    16   fixes div :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
    17 
    17   fixes mod :: "'a \<Rightarrow> 'a \<Rightarrow> 'a"
    18 instance  nat :: div ..
    18 begin
       
    19 
       
    20 notation
       
    21   div (infixl "\<^loc>div" 70)
       
    22 
       
    23 notation
       
    24   mod (infixl "\<^loc>mod" 70)
       
    25 
       
    26 end
       
    27 
       
    28 notation
       
    29   div (infixl "div" 70)
       
    30 
       
    31 notation
       
    32   mod (infixl "mod" 70)
       
    33 
       
    34 instance nat :: "Divides.div"
       
    35   mod_def: "m mod n == wfrec (trancl pred_nat)
       
    36                           (%f j. if j<n | n=0 then j else f (j-n)) m"
       
    37   div_def:   "m div n == wfrec (trancl pred_nat) 
       
    38                           (%f j. if j<n | n=0 then 0 else Suc (f (j-n))) m" ..
       
    39 
       
    40 definition
       
    41   (*The definition of dvd is polymorphic!*)
       
    42   dvd  :: "'a::times \<Rightarrow> 'a \<Rightarrow> bool" (infixl "dvd" 50) where
       
    43   dvd_def: "m dvd n \<longleftrightarrow> (\<exists>k. n = m*k)"
    19 
    44 
    20 consts
    45 consts
    21   div  :: "'a::div \<Rightarrow> 'a \<Rightarrow> 'a"          (infixl 70)
    46   quorem :: "(nat*nat) * (nat*nat) => bool"
    22   mod  :: "'a::div \<Rightarrow> 'a \<Rightarrow> 'a"          (infixl 70)
       
    23   dvd  :: "'a::times \<Rightarrow> 'a \<Rightarrow> bool"      (infixl 50)
       
    24 
       
    25 
    47 
    26 defs
    48 defs
    27 
    49   (*This definition helps prove the harder properties of div and mod.
    28   mod_def:   "m mod n == wfrec (trancl pred_nat)
    50     It is copied from IntDiv.thy; should it be overloaded?*)
    29                           (%f j. if j<n | n=0 then j else f (j-n)) m"
    51   quorem_def: "quorem \<equiv> (%((a,b), (q,r)).
    30 
    52                     a = b*q + r &
    31   div_def:   "m div n == wfrec (trancl pred_nat) 
    53                     (if 0<b then 0\<le>r & r<b else b<r & r \<le>0))"
    32                           (%f j. if j<n | n=0 then 0 else Suc (f (j-n))) m"
       
    33 
       
    34 (*The definition of dvd is polymorphic!*)
       
    35   dvd_def:   "m dvd n == \<exists>k. n = m*k"
       
    36 
       
    37 (*This definition helps prove the harder properties of div and mod.
       
    38   It is copied from IntDiv.thy; should it be overloaded?*)
       
    39 constdefs
       
    40   quorem :: "(nat*nat) * (nat*nat) => bool"
       
    41     "quorem == %((a,b), (q,r)).
       
    42                       a = b*q + r &
       
    43                       (if 0<b then 0\<le>r & r<b else b<r & r \<le>0)"
       
    44 
    54 
    45 
    55 
    46 
    56 
    47 subsection{*Initial Lemmas*}
    57 subsection{*Initial Lemmas*}
    48 
    58 
   185 
   195 
   186 
   196 
   187 structure CancelDivModData =
   197 structure CancelDivModData =
   188 struct
   198 struct
   189 
   199 
   190 val div_name = "Divides.op div";
   200 val div_name = "Divides.div";
   191 val mod_name = "Divides.op mod";
   201 val mod_name = "Divides.mod";
   192 val mk_binop = HOLogic.mk_binop;
   202 val mk_binop = HOLogic.mk_binop;
   193 val mk_sum = NatArithUtils.mk_sum;
   203 val mk_sum = NatArithUtils.mk_sum;
   194 val dest_sum = NatArithUtils.dest_sum;
   204 val dest_sum = NatArithUtils.dest_sum;
   195 
   205 
   196 (*logic*)
   206 (*logic*)
   264 prefer 2 apply (blast intro: unique_quotient)
   274 prefer 2 apply (blast intro: unique_quotient)
   265 apply (simp add: quorem_def)
   275 apply (simp add: quorem_def)
   266 done
   276 done
   267 
   277 
   268 lemma quorem_div_mod: "0 < b ==> quorem ((a, b), (a div b, a mod b))"
   278 lemma quorem_div_mod: "0 < b ==> quorem ((a, b), (a div b, a mod b))"
   269 by (auto simp add: quorem_def)
   279   unfolding quorem_def by simp 
   270 
   280 
   271 lemma quorem_div: "[| quorem((a,b),(q,r));  0 < b |] ==> a div b = q"
   281 lemma quorem_div: "[| quorem((a,b),(q,r));  0 < b |] ==> a div b = q"
   272 by (simp add: quorem_div_mod [THEN unique_quotient])
   282 by (simp add: quorem_div_mod [THEN unique_quotient])
   273 
   283 
   274 lemma quorem_mod: "[| quorem((a,b),(q,r));  0 < b |] ==> a mod b = r"
   284 lemma quorem_mod: "[| quorem((a,b),(q,r));  0 < b |] ==> a mod b = r"
   647 
   657 
   648 lemma dvd_mult_div_cancel: "n dvd m ==> n * (m div n) = (m::nat)"
   658 lemma dvd_mult_div_cancel: "n dvd m ==> n * (m div n) = (m::nat)"
   649 apply (subgoal_tac "m mod n = 0")
   659 apply (subgoal_tac "m mod n = 0")
   650  apply (simp add: mult_div_cancel)
   660  apply (simp add: mult_div_cancel)
   651 apply (simp only: dvd_eq_mod_eq_0)
   661 apply (simp only: dvd_eq_mod_eq_0)
       
   662 done
       
   663 
       
   664 lemma le_imp_power_dvd: "!!i::nat. m \<le> n ==> i^m dvd i^n"
       
   665 apply (unfold dvd_def)
       
   666 apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst])
       
   667 apply (simp add: power_add)
       
   668 done
       
   669 
       
   670 lemma nat_zero_less_power_iff [simp]: "(0 < x^n) = (x \<noteq> (0::nat) | n=0)"
       
   671 by (induct "n", auto)
       
   672 
       
   673 lemma power_le_dvd [rule_format]: "k^j dvd n --> i\<le>j --> k^i dvd (n::nat)"
       
   674 apply (induct "j")
       
   675 apply (simp_all add: le_Suc_eq)
       
   676 apply (blast dest!: dvd_mult_right)
       
   677 done
       
   678 
       
   679 lemma power_dvd_imp_le: "[|i^m dvd i^n;  (1::nat) < i|] ==> m \<le> n"
       
   680 apply (rule power_le_imp_le_exp, assumption)
       
   681 apply (erule dvd_imp_le, simp)
   652 done
   682 done
   653 
   683 
   654 lemma mod_eq_0_iff: "(m mod d = 0) = (\<exists>q::nat. m = d*q)"
   684 lemma mod_eq_0_iff: "(m mod d = 0) = (\<exists>q::nat. m = d*q)"
   655 by (auto simp add: dvd_eq_mod_eq_0 [symmetric] dvd_def)
   685 by (auto simp add: dvd_eq_mod_eq_0 [symmetric] dvd_def)
   656 
   686