subsection"Verification Condition Generator" theory QuantK_VCG imports QuantK_Hoare begin
subsubsection"Ceiling integer division on extended natural numbers"
definition"mydiv (a::nat) (k::nat) = (if k dvd a then a div k else (a div k) + 1)"
lemma mydivcode: "k>0 ==> D≥k ==> mydiv D k = Suc (mydiv (D-k) k)" unfolding mydiv_def apply (auto simp add: le_div_geq) using dvd_minus_self by auto
lemma mydivcode1: "mydiv 0 k = 0" unfolding mydiv_def by auto
lemma mydivcode2: "k>0 ==> 0<D ==> D<k ==> mydiv D k = Suc 0" unfolding mydiv_def by auto
lemma mydiv_mono: "a≤b ==> mydiv a k ≤ mydiv b k"unfolding mydiv_def apply(cases "k dvd a")
subgoal apply(cases "k dvd b") apply auto apply (auto simp add: div_le_mono) using div_le_mono le_Suc_eq by blast
subgoal apply(cases "k dvd b") apply auto apply (auto simp add: div_le_mono) by (metis Suc_leI add.right_neutral div_le_mono div_mult_mod_eq dvd_imp_mod_0 le_add1 le_antisym less_le) done
lemma mydiv_cancel: "0 < k ==> mydiv (k * i) k = i" unfolding mydiv_def by auto
lemmaassumes k: "k>0"and B: "B ≤ k*A" shows mydiv_le_E: "mydiv B k ≤ A" proof - from mydiv_mono[OF B] and k mydiv_cancel show ?thesis by metis qed lemma mydiv_mult_leq: "0 < k ==> l≤k ==> mydiv (l*A) k ≤ A" by(simp add: mydiv_le_E)
lemma mydiv_cancel3: "0 < k ==> i ≤ k * mydiv i k" by (auto simp add: mydiv_def dividend_less_times_div le_eq_less_or_eq)
definition"ediv a k = (if a=∞ then ∞ else enat (mydiv (THE i. a=enat i) k))"
lemma ediv_enat[simp]: "ediv (enat a) k = enat (mydiv a k)" unfolding ediv_def by auto lemma ediv_mydiv[simp]: "ediv (enat a) k ≤ enat f ⟷ mydiv a k ≤ f" unfolding ediv_def by auto
lemma ediv_mono: "a≤b ==> ediv a k ≤ ediv b k" unfolding ediv_def by (auto simp add: mydiv_mono)
lemma ediv_cancel2: "k>0 ==> ediv (enat k * x) k = x" unfolding ediv_def apply(cases "x=∞") using mydiv_cancel by auto
lemma ediv_cancel3: "k>0 ==> A ≤ enat k * ediv A k" unfolding ediv_def apply(cases "A=∞") using mydiv_cancel3 by auto
fun strip :: "acom ==> com"where "strip SKIP = SKIP" | "strip (x ::= a) = (x ::= a)" | "strip (C1;; C2) = (strip C1;; strip C2)" | "strip (IF b THEN C1 ELSE C2) = (IF b THEN strip C1 ELSE strip C2)" | "strip ({_} WHILE b DO C) = (WHILE b DO strip C)" | "strip ({_} Ab C) = strip C"
funpre :: "acom ==> qassn ==> qassn"where "pre SKIP Q = (λs. eSuc (Q s))" | "pre (x ::= a) Q = (λs. eSuc (Q (s[a/x])))" | "pre (C1;; C2) Q = pre C1 (pre C2 Q)" | "pre (IF b THEN C1 ELSE C2) Q = (λs. eSuc (if bval b s then pre C1 Q s else pre C2 Q s ))" | "pre ({P} WHILE b DO C) Q = (%s. P s + 1)" | "pre ({k} Ab C) Q = (λs. ediv (pre C (λs. k*Q s) s) k)"
text‹In contrast to @{term pre}, @{term vc} produces a formula that is independent of the state:›
fun vc :: "acom ==> qassn ==> bool"where "vc SKIP Q = True" | "vc (x ::= a) Q = True" | "vc (C1 ;; C2) Q = ((vc C1 (pre C2 Q)) ∧ (vc C2 Q) )" | "vc (IF b THEN C1 ELSE C2) Q = (vc C1 Q ∧ vc C2 Q)" | "vc ({I} WHILE b DO C) Q = ( (∀s. (pre C (λs. I s + 1) s ≤ I s + ↑(bval b s)) ∧( Q s ≤ I s + ↑ (¬ bval b s))) ∧ vc C (%s. I s + 1))" | "vc ({k} Ab C) Q = (vc C (λs. enat k* Q s) ∧ k>0 🍋‹∧ (∀s. pre C (λs. enat k * Q s) s ≤ enat k * ediv (pre C (λs. enat k * Q s) s) k)›)"
subsubsection"Soundness of VCG"
lemma vc_sound: "vc C Q ==>⊨2' {pre C Q} strip C { Q }" proof (induct C arbitrary: Q) case (Aif b C1 C2) thenhave Aif1: "⊨2' {pre C1 Q} strip C1 {Q}"and Aif2: "⊨2' {pre C2 Q} strip C2 {Q}"by auto show ?caseapply auto apply(rule hoareQ.conseq[where k=1]) apply(rule hoareQ.If[where P="%s. if bval b s then pre C1 Q s else pre C2 Q s"and Q="Q"])
subgoal apply(rule hoareQ.conseq[where k=1]) apply (fact Aif1)
subgoal for s apply(cases "bval b s") by auto apply auto done
subgoal apply(rule hoareQ.conseq[where k=1]) apply (fact Aif2)
subgoal for s apply(cases "bval b s") by auto apply auto done apply auto done next case (Awhile I b C) thenhave i: "(∧Q. vc C Q ==>⊨2' {pre C Q} strip C {Q})" and ii': " ∀s. pre C (λs. I s + 1) s ≤ I s + ↑ (bval b s)" and ii'': "∧s. Q s ≤ I s + ↑ (¬ bval b s)" and iii: "vc C (λs. I s + 1)" by auto
from i iii have A: "⊨2' {pre C (λs. I s + 1)} strip C {(λs. I s + 1)}"by auto
show ?case apply simp apply(rule conseq[where k=1]) apply(rule While[where I=I]) apply(rule weakenpre) apply(rule A) apply(rule ii') apply simp using ii'' apply auto done next case (Abst k C) thenhave vc: "vc C (λs. k* Q s)"and k: "k>0"by auto from Abst(1) vc have C: "⊨2' {pre C (%s. k*Q s)} strip C {(%s. k*Q s)}"by auto show ?caseapply(simp) apply(rule conseq) apply(rule C) using k apply auto using ediv_cancel3 by auto qed (auto intro: hoareQ.Skip hoareQ.Assign hoareQ.Seq )
lemma vc_sound': "[vc C Q ; (∀s. pre C Q s ≤ P s) ]==>⊨2' {P} strip C { Q }" apply(rule hoareQ.conseq[where k=1]) apply(rule vc_sound) by auto
lemma vc_sound'': "[vc C Q' ; (∀s. pre C Q' s ≤ k * P s) ; (∧s. enat k * Q s ≤ Q' s); k>0 ]==>⊨2' {P} strip C { Q }" apply(rule hoareQ.conseq ) apply(rule vc_sound) by auto
subsubsection"Completeness"
lemma pre_mono: assumes"∧s. P' s ≤ P s" shows"∧s. pre C P' s ≤ pre C P s" using assms by (induct C arbitrary: P P', auto simp: ediv_mono mult_left_mono )
lemma vc_mono: assumes"∧s. P' s ≤ P s" shows"vc C P ==> vc C P'" using assms proof (induct C arbitrary: P P') case (Awhile I b C Q) thus ?case apply (auto simp: pre_mono) using order.trans by blast next case (Abst x1 C) thenshow ?caseby (auto simp: mult_left_mono) qed (auto simp: pre_mono)
lemma"⊨2' { P } c { Q } ==>∃C. strip C = c ∧ vc C Q ∧ (∀s. pre C Q s ≤ P s)"
(is"_ ==>∃C. ?G P c Q C") proof (induction rule: hoareQ.induct) case (conseq P c Q k P' Q') thenobtain C where strip: "strip C = c"and vc: "vc C Q"andpre: "∧s. pre C Q s ≤ P s" by blast
{ fix s have"pre C (λs. enat k * Q' s) s ≤ pre C Q s"using pre_mono conseq(3) by simp also frompre conseq(2) have"…≤ enat k * P' s"using order.trans by blast finallyhave"pre C (λs. enat k * Q' s) s ≤ enat k * P' s"by auto thenhave"ediv (pre C (λs. enat k * Q' s) s) k ≤ ediv (enat k * P' s) k"using ediv_mono by auto moreovernote ediv_cancel2[OF conseq(4)] ultimatelyhave"ediv (pre C (λs. enat k * Q' s) s) k ≤ P' s" by simp
} note compensate=this
show ?case apply(rule exI[where x="{k} Ab C"]) apply(safe)
subgoal using strip by simp
subgoal apply simp apply safe
subgoal using vc vc_mono conseq(3) by force
subgoal by fact done
subgoal apply simp using compensate by auto done next case (Skip P) show ?case (is"∃C. ?C C") proofshow"?C Askip"by auto qed next case (Assign P a x) show ?case (is"∃C. ?C C") proofshow"?C(Aassign x a)"by auto qed next case (If P b c1 Q c2) fromIf(3) obtain C1 where strip1: "strip C1 = c1"and vc1: "vc C1 Q" and pre1: "(∧s. pre C1 Q s ≤ (P s + ↑(bval b s)))" by blast fromIf(4) obtain C2 where strip2: "strip C2 = c2"and vc2: "vc C2 Q" and pre2: "(∧s. pre C2 (λs. Q s) s ≤ (P s + ↑(¬ bval b s)))" by blast
show ?case apply(rule exI[where x="IF b THEN C1 ELSE C2"], safe)
subgoal using strip1 strip2 by auto
subgoal using vc1 vc2 by auto
subgoal for s using pre1[of s] pre2[of s] by auto done next case (Seq P1 c1 P2 c2 P3) from Seq(3) obtain C1 where strip1: "strip C1 = c1"and vc1: "vc C1 P2" and pre1: "(∀s. pre C1 P2 s ≤ P1 s)"by blast from Seq(4) obtain C2 where strip2: "strip C2 = c2"and vc2: "vc C2 P3" and pre2: "∧s. pre C2 P3 s ≤ P2 s"by blast
{ fix s have"pre C1 (pre C2 P3) s ≤ P1 s" apply(rule order.trans[where b="pre C1 P2 s"]) apply(rule pre_mono) using pre2 apply simp using pre1 by simp
} notepre = this show ?case apply(rule exI[where x="C1 ;; C2"], safe)
subgoal using strip1 strip2 by simp
subgoal apply simp apply safe using vc1 vc2 vc_mono pre2 by auto
subgoal apply simp usingpreby auto done next case (While I b c) from While(2) obtain C where strip: "strip C = c"and vc: "vc C (λa. I a + 1)" andpre: "∧s. pre C (λa. I a + 1) s ≤ I s + ↑ (bval b s)"by blast show ?case apply(rule exI[where x="{I} WHILE b DO C"], safe)
subgoal using strip by simp
subgoal apply simp usingpre vc by auto
subgoal by simp done qed
lemma"⊨Z { P } c { Q } ==>∃C. strip C = c ∧ vc C Q ∧ (∀s. pre C Q s ≤ P s)"
(is"_ ==>∃C. ?G P c Q C") proof (induction rule: hoareQ'.induct) case (ZSkip P) show ?case (is"∃C. ?C C") proofshow"?C Askip"by auto qed next case (ZAssign P a x) show ?case (is"∃C. ?C C") proofshow"?C(Aassign x a)"by simp qed next case (ZIf P b c1 Q c2) from ZIf(3) obtain C1 where strip1: "strip C1 = c1"and vc1: "vc C1 Q"and pre1: "(∧s. pre C1 Q s ≤ P s + ↑ (bval b s))"by blast from ZIf(4) obtain C2 where strip2: "strip C2 = c2"and vc2: "vc C2 Q"and pre2: "(∧s. pre C2 Q s ≤ P s + ↑ (¬ bval b s))"by blast
show ?caseapply(rule exI[where x="IF b THEN C1 ELSE C2"]) apply(safe)
subgoal using strip1 strip2 by auto
subgoal using vc1 vc2 by auto
subgoal for s apply auto
subgoal using pre1[of s] by auto
subgoal using pre2[of s] by auto done done next case (ZSeq P1 c1 P2 c2 P3) from ZSeq(3) obtain C1 where strip1: "strip C1 = c1"and vc1: "vc C1 P2"and pre1: "(∀s. pre C1 P2 s ≤ P1 s)"by blast from ZSeq(4) obtain C2 where strip2: "strip C2 = c2"and vc2: "vc C2 P3"and pre2: "(∀s. pre C2 P3 s ≤ P2 s)"by blast
{ fix s have"pre C1 (pre C2 P3) s ≤ P1 s" apply(rule order.trans[where b="pre C1 P2 s"]) apply(rule pre_mono) using pre2 apply simp using pre1 by simp
} notepre = this show ?caseapply(rule exI[where x="C1 ;; C2"]) apply safe
subgoal using strip1 strip2 by simp
subgoal using vc1 vc2 vc_mono pre2 by auto
subgoal usingpreby auto done next case (ZWhile I b c) from ZWhile(2) obtain C where strip: "strip C = c"and vc: "vc C (λa. I a + 1)" andpre: "∧s. pre C (λa. I a + 1) s ≤ I s + ↑ (bval b s)"by blast show ?caseapply(rule exI[where x="{I} WHILE b DO C"]) apply safe
subgoal using strip by simp
subgoal usingpre vc by auto
subgoal by simp done next case (Zconseq' P c Q P' Q') thenobtain C where"strip C = c"and vc: "vc C Q"andpre: "∧s. pre C Q s ≤ P s"by blast
from pre_mono[OF Zconseq'(3)] have1: "∧s. pre C Q' s ≤ pre C Q s"by auto
show ?case apply(rule exI[where x=C]) apply safe apply fact
subgoal using vc Zconseq'(3) vc_mono by auto
subgoal usingpre Zconseq'(2) 1using order.trans by metis done next case (Zconst k P c Q) thenobtain C where strip: "strip C = c"and vc: "vc C (λa. enat k * Q a)" and k: "k>0"andpre: "∧s. pre C (λa. enat k * Q a) s ≤ enat k * P s"by blast show ?case apply(rule exI[where x="{k} Ab C"]) apply safe
subgoal using strip by auto
subgoal using vc k by auto
subgoal apply auto using ediv_mono[OF pre] ediv_cancel2[OF k] by metis done qed
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.