src/HOL/Library/GCD.thy
changeset 21263 de65ce2bfb32
parent 21256 47195501ecf7
child 21404 eb85850d3eb7
equal deleted inserted replaced
21262:a2bd14226f9a 21263:de65ce2bfb32
    19   gcd  :: "nat \<times> nat => nat"  -- {* Euclid's algorithm *}
    19   gcd  :: "nat \<times> nat => nat"  -- {* Euclid's algorithm *}
    20 
    20 
    21 recdef gcd  "measure ((\<lambda>(m, n). n) :: nat \<times> nat => nat)"
    21 recdef gcd  "measure ((\<lambda>(m, n). n) :: nat \<times> nat => nat)"
    22   "gcd (m, n) = (if n = 0 then m else gcd (n, m mod n))"
    22   "gcd (m, n) = (if n = 0 then m else gcd (n, m mod n))"
    23 
    23 
    24 constdefs
    24 definition
    25   is_gcd :: "nat => nat => nat => bool"  -- {* @{term gcd} as a relation *}
    25   is_gcd :: "nat => nat => nat => bool"  -- {* @{term gcd} as a relation *}
    26   "is_gcd p m n == p dvd m \<and> p dvd n \<and>
    26   "is_gcd p m n = (p dvd m \<and> p dvd n \<and>
    27     (\<forall>d. d dvd m \<and> d dvd n --> d dvd p)"
    27     (\<forall>d. d dvd m \<and> d dvd n --> d dvd p))"
    28 
    28 
    29 
    29 
    30 lemma gcd_induct:
    30 lemma gcd_induct:
    31   "(!!m. P m 0) ==>
    31   "(!!m. P m 0) ==>
    32     (!!m n. 0 < n ==> P n (m mod n) ==> P m n)
    32     (!!m n. 0 < n ==> P n (m mod n) ==> P m n)
    36    apply simp_all
    36    apply simp_all
    37   done
    37   done
    38 
    38 
    39 
    39 
    40 lemma gcd_0 [simp]: "gcd (m, 0) = m"
    40 lemma gcd_0 [simp]: "gcd (m, 0) = m"
    41   apply simp
    41   by simp
    42   done
       
    43 
    42 
    44 lemma gcd_non_0: "0 < n ==> gcd (m, n) = gcd (n, m mod n)"
    43 lemma gcd_non_0: "0 < n ==> gcd (m, n) = gcd (n, m mod n)"
    45   apply simp
    44   by simp
    46   done
       
    47 
    45 
    48 declare gcd.simps [simp del]
    46 declare gcd.simps [simp del]
    49 
    47 
    50 lemma gcd_1 [simp]: "gcd (m, Suc 0) = 1"
    48 lemma gcd_1 [simp]: "gcd (m, Suc 0) = 1"
    51   apply (simp add: gcd_non_0)
    49   by (simp add: gcd_non_0)
    52   done
       
    53 
    50 
    54 text {*
    51 text {*
    55   \medskip @{term "gcd (m, n)"} divides @{text m} and @{text n}.  The
    52   \medskip @{term "gcd (m, n)"} divides @{text m} and @{text n}.  The
    56   conjunctions don't seem provable separately.
    53   conjunctions don't seem provable separately.
    57 *}
    54 *}
    58 
    55 
    59 lemma gcd_dvd1 [iff]: "gcd (m, n) dvd m"
    56 lemma gcd_dvd1 [iff]: "gcd (m, n) dvd m"
    60   and gcd_dvd2 [iff]: "gcd (m, n) dvd n"
    57   and gcd_dvd2 [iff]: "gcd (m, n) dvd n"
    61   apply (induct m n rule: gcd_induct)
    58   apply (induct m n rule: gcd_induct)
    62    apply (simp_all add: gcd_non_0)
    59      apply (simp_all add: gcd_non_0)
    63   apply (blast dest: dvd_mod_imp_dvd)
    60   apply (blast dest: dvd_mod_imp_dvd)
    64   done
    61   done
    65 
    62 
    66 text {*
    63 text {*
    67   \medskip Maximality: for all @{term m}, @{term n}, @{term k}
    64   \medskip Maximality: for all @{term m}, @{term n}, @{term k}
    68   naturals, if @{term k} divides @{term m} and @{term k} divides
    65   naturals, if @{term k} divides @{term m} and @{term k} divides
    69   @{term n} then @{term k} divides @{term "gcd (m, n)"}.
    66   @{term n} then @{term k} divides @{term "gcd (m, n)"}.
    70 *}
    67 *}
    71 
    68 
    72 lemma gcd_greatest: "k dvd m ==> k dvd n ==> k dvd gcd (m, n)"
    69 lemma gcd_greatest: "k dvd m ==> k dvd n ==> k dvd gcd (m, n)"
    73   apply (induct m n rule: gcd_induct)
    70   by (induct m n rule: gcd_induct) (simp_all add: gcd_non_0 dvd_mod)
    74    apply (simp_all add: gcd_non_0 dvd_mod)
       
    75   done
       
    76 
    71 
    77 lemma gcd_greatest_iff [iff]: "(k dvd gcd (m, n)) = (k dvd m \<and> k dvd n)"
    72 lemma gcd_greatest_iff [iff]: "(k dvd gcd (m, n)) = (k dvd m \<and> k dvd n)"
    78   apply (blast intro!: gcd_greatest intro: dvd_trans)
    73   by (blast intro!: gcd_greatest intro: dvd_trans)
    79   done
       
    80 
    74 
    81 lemma gcd_zero: "(gcd (m, n) = 0) = (m = 0 \<and> n = 0)"
    75 lemma gcd_zero: "(gcd (m, n) = 0) = (m = 0 \<and> n = 0)"
    82   by (simp only: dvd_0_left_iff [THEN sym] gcd_greatest_iff)
    76   by (simp only: dvd_0_left_iff [symmetric] gcd_greatest_iff)
    83 
    77 
    84 
    78 
    85 text {*
    79 text {*
    86   \medskip Function gcd yields the Greatest Common Divisor.
    80   \medskip Function gcd yields the Greatest Common Divisor.
    87 *}
    81 *}
   197   apply (subst add_commute)
   191   apply (subst add_commute)
   198   apply (rule gcd_add2)
   192   apply (rule gcd_add2)
   199   done
   193   done
   200 
   194 
   201 lemma gcd_add_mult: "gcd (m, k * m + n) = gcd (m, n)"
   195 lemma gcd_add_mult: "gcd (m, k * m + n) = gcd (m, n)"
   202   apply (induct k)
   196   by (induct k) (simp_all add: add_assoc)
   203    apply (simp_all add: add_assoc)
       
   204   done
       
   205 
   197 
   206 end
   198 end