(* This is a slightly modified and specialized version of the partial correctness logic presented in ABSTRACT HOARE LOGICS by Tobias Nipkow Modifications are done for educational reasons by Arnd Poetzsch-Heffter to show the relation to other theories discussed in the lecture. *) theory MyHoare imports Main begin datatype var = V nat (".v_" 90) type_synonym state = "var \ int" type_synonym bexp = "state \ bool" datatype com = Do "(state \ state set)" | Semi com com ("_; _" [60, 60] 10) | Cond bexp com com ("IF _ THEN _ ELSE _" 60) | While bexp com ("WHILE _ DO _" 60) | Local "(state \ state)" com "(state \ state \ state)" ("LOCAL _; _; _" [0,0,60] 60) inductive exec :: "state \ com \ state \ bool" ("_/ -_\/ _" [50,0,50] 50) where Do: "t \ f s \ s -Do f\ t" | Semi: "\ s0 -c1\ s1; s1 -c2\ s2 \ \ s0 -c1;c2\ s2" | IfT: "\ b s; s -c1\ t \ \ s -IF b THEN c1 ELSE c2\ t" | IfF: "\ \b s; s -c2\ t \ \ s -IF b THEN c1 ELSE c2\ t" | WhileF: "\b s \ s -WHILE b DO c\ s" | WhileT: "\ b s; s -c\ t; t -WHILE b DO c\ u \ \ s -WHILE b DO c\ u" | Local: "f s -c\ t \ s -LOCAL f; c; g\ g s t" lemma exec_Do_iff[iff]: "(s -Do f\ t) = (t \ f s)" by(auto elim: exec.cases intro:exec.intros) lemma [iff]: "(s -c;d\ u) = (\t. s -c\ t \ t -d\ u)" by(best elim: exec.cases intro:exec.intros) lemma [iff]: "(s -IF b THEN c ELSE d\ t) = (s -if b s then c else d\ t)" apply auto apply(blast elim: exec.cases intro:exec.intros)+ done lemma [iff]: "(s -LOCAL f; c; g\ u) = (\t. f s -c\ t \ u = g s t)" by(fastsimp elim: exec.cases intro:exec.intros) lemma unfold_while: "(s -WHILE b DO c\ u) = (s -IF b THEN c;WHILE b DO c ELSE Do(\s. {s})\ u)" by(auto elim: exec.cases intro:exec.intros split:split_if_asm) lemma while_lemma[rule_format]: "s -w\ t \ \b c. w = WHILE b DO c \ P s \ (\s s'. P s \ b s \ s -c\ s' \ P s') \ P t \ \b t" apply(erule exec.induct) apply clarify+ defer apply clarify+ apply(subgoal_tac "P t") apply blast apply blast done lemma while_rule: "\s -WHILE b DO c\ t; P s; \s s'. P s \ b s \ s -c\ s' \ P s'\ \ P t \ \b t" apply(drule while_lemma) prefer 2 apply assumption apply blast done type_synonym assn = "state \ bool" abbreviation hoare_valid :: "assn \ com \ assn \ bool" ("\ {(1_)}/ (_)/ {(1_)}" 50) where "\ {P}c{Q} \ \s t. s -c\ t \ P s \ Q t" inductive hoare :: "assn \ com \ assn \ bool" ("\ ({(1_)}/ (_)/ {(1_)})" 50) where Do: "\ {\s. \t \ f s. P t} Do f {P}" | Semi: "\ \ {P}c1{Q}; \ {Q}c2{R} \ \ \ {P} c1;c2 {R}" | If: "\ \ {\s. P s \ b s} c1 {Q}; \ {\s. P s \ \b s} c2 {Q} \ \ \ {P} IF b THEN c1 ELSE c2 {Q}" | While: "\ {\s. P s \ b s} c {P} \ \ {P} WHILE b DO c {\s. P s \ \b s}" | Conseq: "\ \s. P' s \ P s; \ {P}c{Q}; \s. Q s \ Q' s \ \ \ {P'}c{Q'}" | Local: "\ \s. P s \ P' s (f s); \s. \ {P' s} c {Q \ (g s)} \ \ \ {P} LOCAL f;c;g {Q}" lemma strengthen_pre: "\ \s. P' s \ P s; \ {P}c{Q} \ \ \ {P'}c{Q}" by(erule hoare.Conseq, assumption, blast) lemma weaken_post: "\ \ {P}c{Q}; \s. Q s \ Q' s \ \ \ {P}c{Q'}" apply(rule hoare.Conseq) apply(fast, assumption, assumption) done (* { x >= 0 } c := 0; sq := 1; while sq<=x ( c := c+1; sq := sq + (2*c+1) *) definition x :: "var" where "x \ .v0" definition c :: "var" where "c == .v1" definition sq :: "var" where "sq == .v2" definition a1 :: "com" where "a1 == (Do (\s.{s(c := (0::int))}))" definition a2 :: "com" where "a2 == (Do (\s.{s(sq := (1::int))}))" definition a3 :: "com" where "a3 == (Do (\s.{s(c := (s c) + (1::int))}))" definition a4 :: "com" where "a4 == (Do (\s.{s(sq := (s sq) + (2*(s c)+(1::int)))}))" definition wb :: "com" where "wb == (a3 ; a4)" definition w :: "com" where "w == (WHILE ( \s. (s sq) \ (s x) ) DO wb)" definition c1 :: "com" where "c1 == (a2 ; w)" definition c0 :: "com" where "c0 == (a1 ; c1)" lemmas var_def = x_def c_def sq_def lemma a1Prop: "\ { \s. (0 \ (s x))} a1 {\s.(s c)*(s c) \ (s x) \ 1 = ((s c)+1)*((s c)+1)}" apply (simp add: a1_def var_def) thm hoare.Do apply(rule strengthen_pre) prefer 2 apply (rule hoare.Do) apply simp done lemma a2Prop: "\ {\s.(s c)*(s c) \ (s x) \ 1 = ((s c)+1)*((s c)+1)} a2 {\s.(s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1)}" apply (simp add: a2_def var_def) thm hoare.Do apply(rule strengthen_pre) prefer 2 apply (rule hoare.Do) apply simp done lemma a3Prop: "\ {\s. (s sq) \ (s x) \ (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) } a3 {\s. (s c)*(s c) \ (s x) \ (s sq) = (s c)*(s c)}" apply (simp add: a3_def var_def) thm hoare.Do apply(rule strengthen_pre) prefer 2 apply (rule hoare.Do) apply simp done lemma a4Prop [rule_format]: "\ { \s. (s c)*(s c) \ (s x) \ (s sq)+(2*(s c)+1) = ((s c)+1)*((s c)+1) } a4 { \s. (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) }" apply (simp add: a4_def var_def) thm hoare.Do apply(rule strengthen_pre) prefer 2 apply (rule hoare.Do) apply simp done lemma binom1: "((i::int)+1)*(i+1) = i*i + 2*i + 1" apply (simp add: add mult ring_distribs) done lemma a4StrengthProp: "\ { \s. (s c)*(s c) \ (s x) \ (s sq) = (s c)*(s c) } a4 { \s. (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) }" apply (rule strengthen_pre) prefer 2 apply (rule a4Prop) apply (insert binom1) apply simp done lemma wbProp [rule_format]: "\ {\s. (s sq) \ (s x) \ (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) } wb { \s. (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) }" apply (simp (no_asm) add: wb_def ) thm hoare.Semi apply (rule Semi) apply (rule a3Prop) apply (rule a4StrengthProp) done lemma wProp: "\ {\s. (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) } w {\s. \((s sq) \ (s x)) \ (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) }" apply (unfold w_def ) thm While apply (rule weaken_post) apply (rule While) prefer 2 apply blast apply (rule strengthen_pre) prefer 2 apply (rule wbProp) apply simp done lemma wWeakProp: "\ {\s. (s c)*(s c) \ (s x) \ (s sq) = ((s c)+1)*((s c)+1) } w {\s. (s c)*(s c) \ (s x) \ (s x) < ((s c)+1)*((s c)+1) }" apply (rule weaken_post) thm wProp apply (rule wProp) apply simp done lemma c1Prop: "\ {\s.(s c)*(s c) \ (s x) \ 1 = ((s c)+1)*((s c)+1)} c1 {\s. (s c)*(s c) \ (s x) \ (s x) < ((s c)+1)*((s c)+1) }" apply (unfold c1_def ) thm hoare.Semi apply (rule Semi) apply (rule a2Prop) apply (rule wWeakProp) done lemma c0Prop: "\ {\s.(0 \ (s x))} c0 {\s. (s c)*(s c) \ (s x) \ (s x) < ((s c)+1)*((s c)+1) }" apply (unfold c0_def ) apply (rule Semi) apply (rule a1Prop) apply (rule c1Prop) done end