theory GCDInClass imports Main begin fun gcd :: "nat \ nat \ nat" where "gcd m 0 = m" | "gcd 0 n = n" | "gcd m n = (if m < n then gcd m (n - m) else gcd (m - n) n)" thm gcd.induct definition divisible_by :: "nat \ nat \ bool" ("_ | _" [80,80] 79) where "divisible_by m n \ (\ k. m = n * k)" declare divisible_by_def[simp] definition isGCD :: "nat \ nat \ nat \ bool" where "isGCD k m n \ m|k \ n|k \ (\ k'. m|k' \ n|k' \ k|k')" declare isGCD_def[simp] lemma gcd_diff: assumes MN: "m \ n" and G:"isGCD k m (n - m)" shows "isGCD k m n" proof - from G have mk: "m|k" and nmk: "(n-m)|k" and gk: "\ k'. m|k' \ (n-m)|k' \ k|k'" by auto from mk obtain k1 where mkk1: "m = k * k1" by auto from nmk obtain k2 where nmkk2: "n-m = k * k2" by auto from nmkk2 MN have "n = m + k * k2" by simp with mkk1 have "n = (k1 * k) + (k2 * k)" by simp hence "n = (k1 + k2) * k" using add_mult_distrib by simp hence nk: "n|k" by simp have kg_mn: "\ k'. m|k' \ n|k' \ k|k'" proof clarify fix k' assume mkp: "m|k'" and nkp: "n|k'" from nkp obtain k3 where nkpk3: "n = k' * k3" by auto from mkp obtain k4 where mkpk3: "m = k' * k4" by auto from nkpk3 mkpk3 have "n - m = (k' * k3) - (k' * k4)" by auto hence "n - m = (k3 * k') - (k4 * k')" using nat_mult_commute[of k' k3] nat_mult_commute[of k' k4] by simp hence "n - m = (k3 - k4) * k'" using diff_mult_distrib by simp hence "(n - m)|k'" by simp with mkp gk show "k|k'" by simp qed from mk nk kg_mn show "isGCD k m n" by simp qed theorem "isGCD (gcd m n) m n" proof (induct rule: gcd.induct) fix m show "isGCD (gcd m 0) m 0" by simp next fix v have "Suc v = (Suc v) * 1" by simp hence "\ k. Suc v = (Suc v) * k" by (rule exI) hence "Suc v | gcd 0 (Suc v)" by simp thus "isGCD (gcd 0 (Suc v)) 0 (Suc v)" by simp next fix va v let ?m = "Suc va" and ?n = "Suc v" assume IH1: "?m < ?n \ isGCD (gcd ?m (?n - ?m)) ?m (?n - ?m)" and IH2: "\ ?m < ?n \ isGCD (gcd (?m - ?n) ?n) (?m - ?n) ?n" show "isGCD (gcd ?m ?n) ?m ?n" proof (cases "?m < ?n") assume MN: "?m < ?n" from MN IH1 have 1: "isGCD (gcd ?m (?n - ?m)) ?m (?n - ?m)" by blast from 1 MN have 3: "isGCD (gcd ?m ?n) ?m (?n - ?m)" by simp from MN have 4: "?m \ ?n" by simp from 4 3 show "isGCD (gcd ?m ?n) ?m ?n" by (rule gcd_diff) next assume notMN: "\ (?m < ?n)" from notMN IH2 have 1: "isGCD (gcd (?m - ?n) ?n) (?m - ?n) ?n" by blast from 1 notMN have 2: "isGCD (gcd ?m ?n) ?n (?m - ?n)" by simp from notMN have 3: "?n \ ?m" by simp from 3 2 have "isGCD (gcd ?m ?n) ?n ?m" by (rule gcd_diff) from this show "isGCD (gcd ?m ?n) ?m ?n" by simp qed qed end