theory week09B_demo_gcd_sol imports WhileLoopRule GCD begin definition gcd' :: "nat \ nat \ ('s,nat) nondet_monad" where "gcd' a b \ do { (a, b) \ whileLoop (\(a, b) b. 0 < a) (\(a, b). return (b mod a, a)) (a, b); return b }" lemma prod_case_valid: assumes "\P\ f (fst x) (snd x) \Q\" shows "\P\ case x of (a,b) \ f a b \Q\" using assms apply(auto simp: valid_def split: prod.splits) done lemma gcd'_correct: "\\_. True\ gcd' a b \\r s. r = gcd a b\" apply(unfold gcd'_def) apply(rule hoare_weaken_pre) apply(rule bind_wp) apply(rule prod_case_valid) apply(rule return_wp) apply(rule_tac I="\(x,y) s. gcd a b = gcd x y" in whileLoop_wp) apply(rule hoare_weaken_pre) apply(rule prod_case_valid) apply(rule return_wp) apply clarsimp apply (metis gcd.commute gcd_red_nat) apply clarsimp apply clarsimp done end