theory week08B_demo imports "~~/src/HOL/Hoare/HeapSyntax" begin primrec fac :: "nat \ nat" where "fac 0 = 1" | "fac (Suc n) = (Suc n) * fac n" lemma "VARS B { True } B := 2 { B = 2 }" apply vcg done lemma " VARS (x::nat) y r {True} IF x>y THEN r:=x ELSE r:=y FI {r\x \ r \y \ (r=x \ r=y)}" apply vcg apply simp done lemma "VARS (A::int) B { A = 0 \ B = 0 } WHILE A \ a INV { B = A * b } DO B := B + b; A := A + 1 OD {B = a * b }" apply vcg thm distrib_left mult.commute apply (auto simp: distrib_left mult.commute) done lemma factorial_sound: "VARS A B { A = n} B := 1; WHILE A \ 0 INV { fac n = B * fac A } DO B := B * A; A := A - 1 OD { B = fac n }" apply vcg apply clarsimp+ apply(case_tac A) apply clarsimp+ done -- ---------------------------------------------------------------------------------- -- "Arrays" (* define a program that looks for a key in an array *) (*think about the loop invariant *) lemma "VARS I L { True } I := 0; WHILE I < length L \ L!I \ key INV { \i key } DO I := I+1 OD { (I < length L \ L!I = key) \ (I=length L \ key \ set L)}" apply vcg apply simp apply(rule allI) apply(rule impI) apply(subgoal_tac "i < I \ i = I") apply blast find_theorems "_ X \ set Ps } WHILE p \ Null \ p \ Ref X INV { TODO } DO p := p^.nxt OD { p = Ref X }" *) lemma "VARS nxt p { List nxt p Ps \ X \ set Ps } WHILE p \ Null \ p \ Ref X INV { \Ps. List nxt p Ps \ X \ set Ps } DO p := p^.nxt OD { p = Ref X }" apply vcg apply auto done (* define a function that "zips" 2 disjoint linked lists *) (* think about its loop invariant *) (* {List tl p Ps \ List tl q Qs \ set Ps \ set Qs = {} \ size Qs \ size Ps} pp := p; WHILE q \ Null INV { TODO } DO qq := q^.tl; q^.tl := pp^.tl; pp^.tl := q; pp := q^.tl; q := qq OD {List tl p (splice Ps Qs)}" *) lemma "VARS tl p q pp qq {List tl p Ps \ List tl q Qs \ set Ps \ set Qs = {} \ size Qs \ size Ps} pp := p; WHILE q \ Null INV {\as bs qs. distinct as \ Path tl p as pp \ List tl pp bs \ List tl q qs \ set bs \ set qs = {} \ set as \ (set bs \ set qs) = {} \ size qs \ size bs \ splice Ps Qs = as @ splice bs qs} DO qq := q^.tl; q^.tl := pp^.tl; pp^.tl := q; pp := q^.tl; q := qq OD {List tl p (splice Ps Qs)}" thm splice.simps thm Path.simps apply vcg_simp apply(rule_tac x = "[]" in exI) apply fastforce apply clarsimp apply(rename_tac y bs qqs) apply(case_tac bs) apply simp apply clarsimp apply(rename_tac x bbs) apply(rule_tac x = "as @ [x,y]" in exI) apply simp apply(rule_tac x = "bbs" in exI) apply simp apply(rule_tac x = "qqs" in exI) apply simp apply (fastforce simp:List_app) done end