Theory GCD_Impl
theory GCD_Impl
imports SepAuto
begin
text ‹A tutorial example for computation of GCD.›
text ‹Turn on auto2's trace›
declare [[print_trace]]
text ‹Property of gcd that justifies the recursive computation. Add as a
right-to-left rewrite rule.›
setup ‹add_rewrite_rule_back @{thm gcd_red_nat}›
text ‹Functional version of gcd.›
fun gcd_fun :: "nat ⇒ nat ⇒ nat" where
"gcd_fun a b = (if b = 0 then a else gcd_fun b (a mod b))"
text ‹The fun package automatically generates induction rule upon showing
termination. This adds the induction rule for the @fun\_induct command.›
setup ‹add_fun_induct_rule (@{term gcd_fun}, @{thm gcd_fun.induct})›
lemma gcd_fun_correct:
"gcd_fun a b = gcd a b"
@proof
@fun_induct "gcd_fun a b"
@unfold "gcd_fun a b"
@qed
text ‹Imperative version of gcd.›
partial_function (heap) gcd_impl :: "nat ⇒ nat ⇒ nat Heap" where
"gcd_impl a b = (
if b = 0 then return a
else do {
c ← return (a mod b);
r ← gcd_impl b c;
return r
})"
text ‹The program is sufficiently simple that we can prove the Hoare triple
directly (without going through the functional program).›
theorem gcd_impl_correct:
"<emp> gcd_impl a b <λr. ↑(r = gcd a b)>"
@proof
@fun_induct "gcd_fun a b"
@qed
text ‹Turn off trace.›
declare [[print_trace = false]]
end