Theory Greatest_Common_Divisor

Up to index of Isabelle/HOL/Extraction

theory Greatest_Common_Divisor
imports QuotRem
begin

(*  Title:      HOL/Extraction/Greatest_Common_Divisor.thy
    ID:         $Id: Greatest_Common_Divisor.thy,v 1.1 2007/11/13 09:58:46 berghofe Exp $
    Author:     Stefan Berghofer, TU Muenchen
                Helmut Schwichtenberg, LMU Muenchen
*)

header {* Greatest common divisor *}

theory Greatest_Common_Divisor
imports QuotRem
begin

theorem greatest_common_divisor:
  "!!n::nat. Suc m < n ==> ∃k n1 m1. k * n1 = n ∧ k * m1 = Suc m ∧
     (∀l l1 l2. l * l1 = n --> l * l2 = Suc m --> l ≤ k)"
proof (induct m rule: nat_wf_ind)
  case (1 m n)
  from division obtain r q where h1: "n = Suc m * q + r" and h2: "r ≤ m"
    by iprover
  show ?case
  proof (cases r)
    case 0
    with h1 have "Suc m * q = n" by simp
    moreover have "Suc m * 1 = Suc m" by simp
    moreover {
      fix l2 have "!!l l1. l * l1 = n ==> l * l2 = Suc m ==> l ≤ Suc m"
        by (cases l2) simp_all }
    ultimately show ?thesis by iprover
  next
    case (Suc nat)
    with h2 have h: "nat < m" by simp
    moreover from h have "Suc nat < Suc m" by simp
    ultimately have "∃k m1 r1. k * m1 = Suc m ∧ k * r1 = Suc nat ∧
      (∀l l1 l2. l * l1 = Suc m --> l * l2 = Suc nat --> l ≤ k)"
      by (rule 1)
    then obtain k m1 r1 where
      h1': "k * m1 = Suc m"
      and h2': "k * r1 = Suc nat"
      and h3': "!!l l1 l2. l * l1 = Suc m ==> l * l2 = Suc nat ==> l ≤ k"
      by iprover
    have mn: "Suc m < n" by (rule 1)
    from h1 h1' h2' Suc have "k * (m1 * q + r1) = n" 
      by (simp add: add_mult_distrib2 nat_mult_assoc [symmetric])
    moreover have "!!l l1 l2. l * l1 = n ==> l * l2 = Suc m ==> l ≤ k"
    proof -
      fix l l1 l2
      assume ll1n: "l * l1 = n"
      assume ll2m: "l * l2 = Suc m"
      moreover have "l * (l1 - l2 * q) = Suc nat"
        by (simp add: diff_mult_distrib2 h1 Suc [symmetric] mn ll1n ll2m [symmetric])
      ultimately show "l ≤ k" by (rule h3')
    qed
    ultimately show ?thesis using h1' by iprover
  qed
qed

extract greatest_common_divisor

text {*
The extracted program for computing the greatest common divisor is
@{thm [display] greatest_common_divisor_def}
*}

consts_code
  arbitrary ("(error \"arbitrary\")")

code_module GCD
contains
  test = "greatest_common_divisor 7 12"

ML GCD.test

end

theorem greatest_common_divisor:

  Suc m < n
  ==> ∃k n1 m1.
         k * n1 = nk * m1 = Suc m ∧ (∀l l1 l2. l * l1 = n --> l * l2 = Suc m --> l  k)