(* Author: David Cock - David.Cock@nicta.com.au *)
section‹Healthiness›
theory Healthiness imports Embedding begin
subsection‹The Healthiness of the Embedding›
text‹Healthiness is mostly derived by structural induction using
the simplifier. @{term Abort}, @{term Skip} and @{term Apply}
form base cases.›
lemma healthy_wp_Abort: "healthy (wp Abort)" proof(rule healthy_parts) fix b and P::"'a → real" assume nP: "nneg P"and bP: "bounded_by b P" thus"bounded_by b (wp Abort P)" unfolding wp_eval by(blast) show"nneg (wp Abort P)" unfolding wp_eval by(blast) next fix P Q::"'a expect" show"wp Abort P ⊨!!! wp Abort Q" unfolding wp_eval by(blast) next fix P and c and s::'a show"c * wp Abort P s = wp Abort (λs. c * P s) s" unfolding wp_eval by(auto) qed
lemma nearly_healthy_wlp_Abort: "nearly_healthy (wlp Abort)" proof(rule nearly_healthyI) fix P::"'s → real" show"unitary (wlp Abort P)" by(simp add:wp_eval) next fix P Q :: "'s expect" assume"P ⊨!!! Q"and"unitary P"and"unitary Q" thus"wlp Abort P ⊨!!! wlp Abort Q" unfolding wp_eval by(blast) qed
lemma healthy_wp_Seq: fixes t::"'s prog"and u assumes ht: "healthy (wp t)"and hu: "healthy (wp u)" shows"healthy (wp (t ;; u))" proof(rule healthy_parts, simp_all add:wp_eval) fix b and P::"'s → real" assume"bounded_by b P"and"nneg P" with hu have"bounded_by b (wp u P)"and"nneg (wp u P)"by(auto) with ht show"bounded_by b (wp t (wp u P))" and"nneg (wp t (wp u P))"by(auto) next fix P::"'s → real"and Q assume"sound P"and"sound Q"and"P ⊨!!! Q" with hu have"sound (wp u P)"and"sound (wp u Q)" and"wp u P ⊨!!! wp u Q"by(auto) with ht show"wp t (wp u P) ⊨!!! wp t (wp u Q)"by(auto) next fix P::"'s → real"and c::real and s assume pos: "0 ≤ c"and sP: "sound P" with ht and hu have"c * wp t (wp u P) s = wp t (λs. c * wp u P s) s" by(auto intro!:scalingD) alsowith hu and pos and sP have"... = wp t (wp u (λs. c * P s)) s" by(simp add:scalingD[OF healthy_scalingD]) finallyshow"c * wp t (wp u P) s = wp t (wp u (λs. c * P s)) s" . qed
lemma nearly_healthy_wlp_Seq: fixes t::"'s prog"and u assumes ht: "nearly_healthy (wlp t)"and hu: "nearly_healthy (wlp u)" shows"nearly_healthy (wlp (t ;; u))" proof(rule nearly_healthyI, simp_all add:wp_eval) fix b and P::"'s → real" assume"unitary P" with hu have"unitary (wlp u P)"by(auto) with ht show"unitary (wlp t (wlp u P))"by(auto) next fix P Q::"'s → real" assume"unitary P"and"unitary Q"and"P ⊨!!! Q" with hu have"unitary (wlp u P)"and"unitary (wlp u Q)" and"wlp u P ⊨!!! wlp u Q"by(auto) with ht show"wlp t (wlp u P) ⊨!!! wlp t (wlp u Q)"by(auto) qed
txt‹Non-negative:› from nQ and bQ and hf have"0 ≤ wp f Q s"by(auto) with uP have"0 ≤ P s * ..."by(auto intro:mult_nonneg_nonneg) moreover { from uP have"0 ≤ 1 - P s" by auto with nQ and bQ and hg have"0 ≤ ... * wp g Q s" by (metis healthy_nnegD2 mult_nonneg_nonneg nneg_def)
} ultimatelyshow"0 ≤ P s * wp f Q s + (1 - P s) * wp g Q s" by(auto intro:mult_nonneg_nonneg)
txt‹Bounded:› from nQ bQ hf have"wp f Q s ≤ b"by(auto) with uP nQ bQ hf have"P s * wp f Q s ≤ P s * b" by(blast intro!:mult_mono) moreover { from nQ bQ hg uP have"wp g Q s ≤ b"and"0 ≤ 1 - P s" by auto with nQ bQ hg have"(1 - P s) * wp g Q s ≤ (1 - P s) * b" by(blast intro!:mult_mono)
} ultimatelyhave"P s * wp f Q s + (1 - P s) * wp g Q s ≤ P s * b + (1 - P s) * b" by(blast intro:add_mono) alsohave"... = b"by(auto simp:algebra_simps) finallyshow"P s * wp f Q s + (1 - P s) * wp g Q s ≤ b" . next txt‹Monotonic:› fix Q R::"'s → real"and s assume sQ: "sound Q"and sR: "sound R"and le: "Q ⊨!!! R"
with hf have"wp f Q s ≤ wp f R s"by(blast dest:mono_transD) with uP have"P s * wp f Q s ≤ P s * wp f R s" by(auto intro:mult_left_mono) moreover { from sQ sR le hg have"wp g Q s ≤ wp g R s"by(blast dest:mono_transD) moreoverfrom uP have"0 ≤ 1 - P s" by auto ultimatelyhave"(1 - P s) * wp g Q s ≤ (1 - P s) * wp g R s" by(auto intro:mult_left_mono)
} ultimatelyshow"P s * wp f Q s + (1 - P s) * wp g Q s ≤ P s * wp f R s + (1 - P s) * wp g R s"by(auto) next txt‹Scaling:› fix Q::"'s → real"and c::real and s::'s assume sQ: "sound Q"and pos: "0 ≤ c" have"c * (P s * wp f Q s + (1 - P s) * wp g Q s) = P s * (c * wp f Q s) + (1 - P s) * (c * wp g Q s)" by(simp add:distrib_left) alsohave"... = P s * wp f (λs. c * Q s) s + (1 - P s) * wp g (λs. c * Q s) s" using hf hg sQ pos by(simp add:scalingD[OF healthy_scalingD]) finallyshow"c * (P s * wp f Q s + (1 - P s) * wp g Q s) = P s * wp f (λs. c * Q s) s + (1 - P s) * wp g (λs. c * Q s) s" . qed
lemma nearly_healthy_wlp_PC: fixes f::"'s prog" assumes hf: "nearly_healthy (wlp f)" and hg: "nearly_healthy (wlp g)" and uP: "unitary P" shows"nearly_healthy (wlp (f ⊕ g))" proof(intro nearly_healthyI unitaryI2 nnegI bounded_byI le_funI,
simp_all add:wp_eval) fix Q::"'s expect"and s::'s assume uQ: "unitary Q" from uQ hf hg have utQ: "unitary (wlp f Q)""unitary (wlp g Q)"by(auto) from uP have nnP: "0 ≤ P s""0 ≤ 1 - P s" by auto moreoverfrom utQ have"0 ≤ wlp f Q s""0 ≤ wlp g Q s"by(auto) ultimatelyshow"0 ≤ P s * wlp f Q s + (1 - P s) * wlp g Q s" by(auto intro:add_nonneg_nonneg mult_nonneg_nonneg)
from utQ have"wlp f Q s ≤ 1""wlp g Q s ≤ 1"by(auto) with nnP have"P s * wlp f Q s + (1 - P s) * wlp g Q s ≤ P s * 1 + (1 - P s) * 1" by(blast intro:add_mono mult_left_mono) thus"P s * wlp f Q s + (1 - P s) * wlp g Q s ≤ 1"by(simp)
fix R::"'s expect" assume uR: "unitary R"and le: "Q ⊨!!! R" with uQ have"wlp f Q s ≤ wlp f R s" by(auto intro:le_funD[OF nearly_healthy_monoD, OF hf]) with nnP have"P s * wlp f Q s ≤ P s * wlp f R s" by(auto intro:mult_left_mono) moreover { from uQ uR le have"wlp g Q s ≤ wlp g R s" by(auto intro:le_funD[OF nearly_healthy_monoD, OF hg]) with nnP have"(1 - P s) * wlp g Q s ≤ (1 - P s) * wlp g R s" by(auto intro:mult_left_mono)
} ultimatelyshow"P s * wlp f Q s + (1 - P s) * wlp g Q s ≤ P s * wlp f R s + (1 - P s) * wlp g R s" by(auto) qed
with hf have"bounded_by b (wp f P)"by(auto) hence"wp f P s ≤ b"by(blast) thus"min (wp f P s) (wp g P s) ≤ b"by(auto)
from nP bP assms show"0 ≤ min (wp f P s) (wp g P s)"by(auto) next fix P::"'s → real"and Q and s::'s from assms have mf: "mono_trans (wp f)"and mg: "mono_trans (wp g)"by(auto) assume sP: "sound P"and sQ: "sound Q"and le: "P ⊨!!! Q" hence"wp f P s ≤ wp f Q s"and"wp g P s ≤ wp g Q s" by(auto intro:le_funD[OF mono_transD[OF mf]] le_funD[OF mono_transD[OF mg]]) thus"min (wp f P s) (wp g P s) ≤ min (wp f Q s) (wp g Q s)"by(auto) next fix P::"'s → real"and c::real and s::'s assume sP: "sound P"and pos: "0 ≤ c" from assms have sf: "scaling (wp f)"and sg: "scaling (wp g)"by(auto) from pos have"c * min (wp f P s) (wp g P s) = min (c * wp f P s) (c * wp g P s)" by(simp add:min_distrib) alsofrom sP and pos have"... = min (wp f (λs. c * P s) s) (wp g (λs. c * P s) s)" by(simp add:scalingD[OF sf] scalingD[OF sg]) finallyshow"c * min (wp f P s) (wp g P s) = min (wp f (λs. c * P s) s) (wp g (λs. c * P s) s)" . qed
lemma nearly_healthy_wlp_DC: fixes f::"'s prog" assumes hf: "nearly_healthy (wlp f)" and hg: "nearly_healthy (wlp g)" shows"nearly_healthy (wlp (f ⊓ g))" proof(intro nearly_healthyI bounded_byI nnegI le_funI unitaryI2,
simp_all add:wp_eval, safe) fix P::"'s → real"and s::'s assume uP: "unitary P" with hf hg have utP: "unitary (wlp f P)""unitary (wlp g P)"by(auto) thus"0 ≤ wlp f P s""0 ≤ wlp g P s"by(auto)
have"min (wlp f P s) (wlp g P s) ≤ wlp f P s"by(auto) alsofrom utP have"... ≤ 1"by(auto) finallyshow"min (wlp f P s) (wlp g P s) ≤ 1" .
fix Q::"'s → real" assume uQ: "unitary Q"and le: "P ⊨!!! Q" have"min (wlp f P s) (wlp g P s) ≤ wlp f P s"by(auto) alsofrom uP uQ le have"... ≤ wlp f Q s" by(auto intro:le_funD[OF nearly_healthy_monoD, OF hf]) finallyshow"min (wlp f P s) (wlp g P s) ≤ wlp f Q s" .
have"min (wlp f P s) (wlp g P s) ≤ wlp g P s"by(auto) alsofrom uP uQ le have"... ≤ wlp g Q s" by(auto intro:le_funD[OF nearly_healthy_monoD, OF hg]) finallyshow"min (wlp f P s) (wlp g P s) ≤ wlp g Q s" . qed
with hf have"bounded_by b (wp f P)"by(auto) hence"wp f P s ≤ b"by(blast) moreover { from bP nP hg have"bounded_by b (wp g P)"by(auto) hence"wp g P s ≤ b"by(blast)
} ultimatelyshow"max (wp f P s) (wp g P s) ≤ b"by(auto)
from nP bP assms have"0 ≤ wp f P s"by(auto) thus"0 ≤ max (wp f P s) (wp g P s)"by(auto) next fix P::"'s → real"and Q and s::'s from assms have mf: "mono_trans (wp f)"and mg: "mono_trans (wp g)"by(auto) assume sP: "sound P"and sQ: "sound Q"and le: "P ⊨!!! Q" hence"wp f P s ≤ wp f Q s"and"wp g P s ≤ wp g Q s" by(auto intro:le_funD[OF mono_transD, OF mf] le_funD[OF mono_transD, OF mg]) thus"max (wp f P s) (wp g P s) ≤ max (wp f Q s) (wp g Q s)"by(auto) next fix P::"'s → real"and c::real and s::'s assume sP: "sound P"and pos: "0 ≤ c" from assms have sf: "scaling (wp f)"and sg: "scaling (wp g)"by(auto) from pos have"c * max (wp f P s) (wp g P s) = max (c * wp f P s) (c * wp g P s)" by(simp add:max_distrib) alsofrom sP and pos have"... = max (wp f (λs. c * P s) s) (wp g (λs. c * P s) s)" by(simp add:scalingD[OF sf] scalingD[OF sg]) finallyshow"c * max (wp f P s) (wp g P s) = max (wp f (λs. c * P s) s) (wp g (λs. c * P s) s)" . qed
with hf have"wlp f P s ≤ 1"by(auto) moreoverfrom uP hg have"unitary (wlp g P)"by(auto) hence"wlp g P s ≤ 1"by(auto) ultimatelyshow"max (wlp f P s) (wlp g P s) ≤ 1"by(auto)
from uP hf have"unitary (wlp f P)"by(auto) hence"0 ≤ wlp f P s"by(auto) thus"0 ≤ max (wlp f P s) (wlp g P s)"by(auto) next fix P::"'s → real"and Q and s::'s assume uP: "unitary P"and uQ: "unitary Q"and le: "P ⊨!!! Q" hence"wlp f P s ≤ wlp f Q s"and"wlp g P s ≤ wlp g Q s" by(auto intro:le_funD[OF nearly_healthy_monoD, OF hf]
le_funD[OF nearly_healthy_monoD, OF hg]) thus"max (wlp f P s) (wlp g P s) ≤ max (wlp f Q s) (wlp g Q s)"by(auto) qed
lemma healthy_wp_repeat: assumes h_a: "healthy (wp a)" shows"healthy (wp (repeat n a))" (is"?X n") proof(induct n) show"?X 0"by(auto simp:wp_eval) next fix n assume IH: "?X n" thus"?X (Suc n)"by(simp add:healthy_wp_Seq h_a) qed
lemma nearly_healthy_wlp_repeat: assumes h_a: "nearly_healthy (wlp a)" shows"nearly_healthy (wlp (repeat n a))" (is"?X n") proof(induct n) show"?X 0"by(simp add:wp_eval) next fix n assume IH: "?X n" thus"?X (Suc n)"by(simp add:nearly_healthy_wlp_Seq h_a) qed
lemma healthy_wp_SetDC: fixes prog::"'b → 'a prog"and S::"'a → 'b set" assumes healthy: "∧x s. x ∈ S s ==> healthy (wp (prog x))" and nonempty: "∧s. ∃x. x ∈ S s" shows"healthy (wp (SetDC prog S))" (is"healthy ?T") proof(intro healthy_parts bounded_byI nnegI le_funI, simp_all only:wp_eval) fix b and P::"'a → real"and s::'a assume bP: "bounded_by b P"and nP: "nneg P" hence sP: "sound P"by(auto)
from nonempty obtain x where xin: "x ∈ (λa. wp (prog a) P s) ` S s"by(blast) moreoverfrom sP and healthy have"∀x∈(λa. wp (prog a) P s) ` S s. 0 ≤ x"by(auto) ultimatelyhave"Inf ((λa. wp (prog a) P s) ` S s) ≤ x" by(intro cInf_lower bdd_belowI, auto) alsofrom xin and healthy and sP and bP have"x ≤ b"by(blast) finallyshow"Inf ((λa. wp (prog a) P s) ` S s) ≤ b" .
from xin and sP and healthy show"0 ≤ Inf ((λa. wp (prog a) P s) ` S s)"by(blast intro:cInf_greatest) next fix P::"'a → real"and Q and s::'a assume sP: "sound P"and sQ: "sound Q"and le: "P ⊨!!! Q"
from nonempty obtain x where xin: "x ∈ (λa. wp (prog a) P s) ` S s"by(blast) moreoverfrom sP and healthy have"∀x∈(λa. wp (prog a) P s) ` S s. 0 ≤ x"by(auto) moreover have"∀x∈(λa. wp (prog a) Q s) ` S s. ∃y∈(λa. wp (prog a) P s) ` S s. y ≤ x" proof(rule ballI, clarify, rule bexI) fix x and a assume ain: "a ∈ S s" with healthy and sP and sQ and le show"wp (prog a) P s ≤ wp (prog a) Q s" by(auto dest:mono_transD[OF healthy_monoD]) from ain show"wp (prog a) P s ∈ (λa. wp (prog a) P s) ` S s"by(simp) qed ultimately show"Inf ((λa. wp (prog a) P s) ` S s) ≤ Inf ((λa. wp (prog a) Q s) ` S s)" by(intro cInf_mono, blast+) next fix P::"'a → real"and c::real and s::'a assume sP: "sound P"and pos: "0 ≤ c" from nonempty obtain x where xin: "x ∈ (λa. wp (prog a) P s) ` S s"by(blast) have"c * Inf ((λa. wp (prog a) P s) ` S s) = Inf ((*) c ` ((λa. wp (prog a) P s) ` S s))" (is"?U = ?V") proof(rule antisym) show"?U ≤ ?V" proof(rule cInf_greatest) from nonempty show"(*) c ` (λa. wp (prog a) P s) ` S s ≠ {}"by(auto) fix x assume"x ∈ (*) c ` (λa. wp (prog a) P s) ` S s" thenobtain y where yin: "y ∈ (λa. wp (prog a) P s) ` S s"and rwx: "x = c * y"by(auto) have"Inf ((λa. wp (prog a) P s) ` S s) ≤ y" proof(intro cInf_lower[OF yin] bdd_belowI) fix z assume zin: "z ∈ (λa. wp (prog a) P s) ` S s" thenobtain a where "a ∈ S s"and"z = wp (prog a) P s"by(auto) with sP show"0 ≤ z"by(auto dest:healthy) qed with pos rwx show"c * Inf ((λa. wp (prog a) P s) ` S s) ≤ x"by(auto intro:mult_left_mono) qed show"?V ≤ ?U" proof(cases) assume cz: "c = 0" moreover { from nonempty obtain c where "c ∈ S s"by(auto) hence"∃x. ∃xa∈S s. x = wp (prog xa) P s"by(auto)
} ultimatelyshow ?thesis by(simp add:image_def) next assume"c ≠ 0" from nonempty have"S s ≠ {}"by blast thenhave"inverse c * (INF x∈S s. c * wp (prog x) P s) ≤ (INF a∈S s. wp (prog a) P s)" proof (rule cINF_greatest) fix x assume"x ∈ S s" have"bdd_below ((λx. c * wp (prog x) P s) ` S s)" proof (rule bdd_belowI [of _ 0]) fix z assume"z ∈ (λx. c * wp (prog x) P s) ` S s" thenobtain b where "b ∈ S s"and rwz: "z = c * wp (prog b) P s"by auto with sP have"0 ≤ wp (prog b) P s"by (auto dest: healthy) with pos show"0 ≤ z"by (auto simp: rwz intro: mult_nonneg_nonneg) qed thenhave"(INF x∈S s. c * wp (prog x) P s) ≤ c * wp (prog x) P s" using‹x ∈ S s›by (rule cINF_lower) with‹c ≠ 0›show"inverse c * (INF x∈S s. c * wp (prog x) P s) ≤ wp (prog x) P s" by (simp add: mult_div_mono_left pos) qed with‹c ≠ 0›have"inverse c * ?V ≤ inverse c * ?U" by (simp add: mult.assoc [symmetric] image_comp) with pos have"c * (inverse c * ?V) ≤ c * (inverse c * ?U)" by(auto intro:mult_left_mono) with‹c ≠ 0›show ?thesis by (simp add:mult.assoc [symmetric]) qed qed alsohave"... = Inf ((λa. c * wp (prog a) P s) ` S s)" by (simp add: image_comp) alsofrom sP and pos have"... = Inf ((λa. wp (prog a) (λs. c * P s) s) ` S s)" by(simp add:scalingD[OF healthy_scalingD, OF healthy] cong:image_cong) finallyshow"c * Inf ((λa. wp (prog a) P s) ` S s) = Inf ((λa. wp (prog a) (λs. c * P s) s) ` S s)" . qed
lemma nearly_healthy_wlp_SetDC: fixes prog::"'b → 'a prog"and S::"'a → 'b set" assumes healthy: "∧x s. x ∈ S s ==> nearly_healthy (wlp (prog x))" and nonempty: "∧s. ∃x. x ∈ S s" shows"nearly_healthy (wlp (SetDC prog S))" (is"nearly_healthy ?T") proof(intro nearly_healthyI unitaryI2 bounded_byI nnegI le_funI, simp_all only:wp_eval) fix b and P::"'a → real"and s::'a assume uP: "unitary P"
from nonempty obtain x where xin: "x ∈ (λa. wlp (prog a) P s) ` S s"by(blast) moreover { from uP healthy have"∀x∈(λa. wlp (prog a) P) ` S s. unitary x"by(auto) hence"∀x∈(λa. wlp (prog a) P) ` S s. 0 ≤ x s"by(auto) hence"∀y∈(λa. wlp (prog a) P s) ` S s. 0 ≤ y"by(auto)
} ultimatelyhave"Inf ((λa. wlp (prog a) P s) ` S s) ≤ x"by(intro cInf_lower bdd_belowI, auto) alsofrom xin healthy uP have"x ≤ 1"by(blast) finallyshow"Inf ((λa. wlp (prog a) P s) ` S s) ≤ 1" .
from xin uP healthy show"0 ≤ Inf ((λa. wlp (prog a) P s) ` S s)" by(blast dest!:unitary_sound[OF nearly_healthy_unitaryD[OF _ uP]]
intro:cInf_greatest) next fix P::"'a → real"and Q and s::'a assume uP: "unitary P"and uQ: "unitary Q"and le: "P ⊨!!! Q"
from nonempty obtain x where xin: "x ∈ (λa. wlp (prog a) P s) ` S s"by(blast) moreover { from uP healthy have"∀x∈(λa. wlp (prog a) P) ` S s. unitary x"by(auto) hence"∀x∈(λa. wlp (prog a) P) ` S s. 0 ≤ x s"by(auto) hence"∀y∈(λa. wlp (prog a) P s) ` S s. 0 ≤ y"by(auto)
} moreover have"∀x∈(λa. wlp (prog a) Q s) ` S s. ∃y∈(λa. wlp (prog a) P s) ` S s. y ≤ x" proof(rule ballI, clarify, rule bexI) fix x and a assume ain: "a ∈ S s" from uP uQ le show"wlp (prog a) P s ≤ wlp (prog a) Q s" by(auto intro:le_funD[OF nearly_healthy_monoD[OF healthy, OF ain]]) from ain show"wlp (prog a) P s ∈ (λa. wlp (prog a) P s) ` S s"by(simp) qed ultimately show"Inf ((λa. wlp (prog a) P s) ` S s) ≤ Inf ((λa. wlp (prog a) Q s) ` S s)" by(intro cInf_mono, blast+) qed
lemma healthy_wp_SetPC: fixes p::"'s → 'a → real" and f::"'a → 's prog" assumes healthy: "∧a s. a ∈ supp (p s) ==> healthy (wp (f a))" and sound: "∧s. sound (p s)" and sub_dist: "∧s. (∑a∈supp (p s). p s a) ≤ 1" shows"healthy (wp (SetPC f p))" (is"healthy ?X") proof(intro healthy_parts bounded_byI nnegI le_funI, simp_all add:wp_eval) fix b and P::"'s → real"and s::'s assume bP: "bounded_by b P"and nP: "nneg P" hence sP: "sound P"by(auto)
from sP and bP and healthy have"∧a s. a ∈ supp (p s) ==> wp (f a) P s ≤ b" by(blast dest:healthy_bounded_byD) with sound have"(∑a∈supp (p s). p s a * wp (f a) P s) ≤ (∑a∈supp (p s). p s a * b)" by(blast intro:sum_mono mult_left_mono) alsohave"... = (∑a∈supp (p s). p s a) * b" by(simp add:sum_distrib_right) also { from bP and nP have"0 ≤ b"by(blast) with sub_dist have"(∑a∈supp (p s). p s a) * b ≤ 1 * b" by(rule mult_right_mono)
} alsohave"1 * b = b"by(simp) finallyshow"(∑a∈supp (p s). p s a * wp (f a) P s) ≤ b" .
show"0 ≤ (∑a∈supp (p s). p s a * wp (f a) P s)" proof(rule sum_nonneg [OF mult_nonneg_nonneg]) fix x from sound show"0 ≤ p s x"by(blast) assume"x ∈ supp (p s)"with sP and healthy show"0 ≤ wp (f x) P s"by(blast) qed next fix P::"'s → real"and Q::"'s → real"and s assume s_P: "sound P"and s_Q: "sound Q"and ent: "P ⊨!!! Q" with healthy have"∧a. a ∈ supp (p s) ==> wp (f a) P s ≤ wp (f a) Q s" by(blast) with sound show"(∑a∈supp (p s). p s a * wp (f a) P s) ≤ (∑a∈supp (p s). p s a * wp (f a) Q s)" by(blast intro:sum_mono mult_left_mono) next fix P::"'s → real"and c::real and s::'s assume sound: "sound P"and pos: "0 ≤ c" have"c * (∑a∈supp (p s). p s a * wp (f a) P s) = (∑a∈supp (p s). p s a * (c * wp (f a) P s))"
(is"?A = ?B") by(simp add:sum_distrib_left ac_simps) alsofrom sound and pos and healthy have"... = (∑a∈supp (p s). p s a * wp (f a) (λs. c * P s) s)" by(auto simp:scalingD[OF healthy_scalingD]) finallyshow"?A = ..." . qed
lemma nearly_healthy_wlp_SetPC: fixes p::"'s → 'a → real" and f::"'a → 's prog" assumes healthy: "∧a s. a ∈ supp (p s) ==> nearly_healthy (wlp (f a))" and sound: "∧s. sound (p s)" and sub_dist: "∧s. (∑a∈supp (p s). p s a) ≤ 1" shows"nearly_healthy (wlp (SetPC f p))" (is"nearly_healthy ?X") proof(intro nearly_healthyI unitaryI2 bounded_byI nnegI le_funI, simp_all only:wp_eval) fix b and P::"'s → real"and s::'s assume uP: "unitary P"
from uP healthy have"∧a. a ∈ supp (p s) ==> unitary (wlp (f a) P)"by(auto) hence"∧a. a ∈ supp (p s) ==> wlp (f a) P s ≤ 1"by(auto) with sound have"(∑a∈supp (p s). p s a * wlp (f a) P s) ≤ (∑a∈supp (p s). p s a * 1)" by(blast intro:sum_mono mult_left_mono) alsohave"... = (∑a∈supp (p s). p s a)" by(simp add:sum_distrib_right) alsonote sub_dist finallyshow"(∑a∈supp (p s). p s a * wlp (f a) P s) ≤ 1" . show"0 ≤ (∑a∈supp (p s). p s a * wlp (f a) P s)" proof(rule sum_nonneg [OF mult_nonneg_nonneg]) fix x from sound show"0 ≤ p s x"by(blast) assume"x ∈ supp (p s)"with uP healthy show"0 ≤ wlp (f x) P s"by(blast) qed next fix P::"'s expect"and Q::"'s expect"and s assume uP: "unitary P"and uQ: "unitary Q"and le: "P ⊨!!! Q" hence"∧a. a ∈ supp (p s) ==> wlp (f a) P s ≤ wlp (f a) Q s" by(blast intro:le_funD[OF nearly_healthy_monoD, OF healthy]) with sound show"(∑a∈supp (p s). p s a * wlp (f a) P s) ≤ (∑a∈supp (p s). p s a * wlp (f a) Q s)" by(blast intro:sum_mono mult_left_mono) qed
fix Q::"'s expect" assume"unitary Q""P ⊨!!! Q" with uP show"wlp (p (f s)) P s ≤ wlp (p (f s)) Q s" by(blast intro:le_funD[OF nearly_healthy_monoD, OF hsub]) qed
subsection‹Healthiness for Loops›
lemma wp_loop_step_mono: fixes t u::"'s trans" assumes hb: "healthy (wp body)" and le: "le_trans t u" and ht: "∧P. sound P ==> sound (t P)" and hu: "∧P. sound P ==> sound (u P)" shows"le_trans (wp (body ;; Embed t <guillemotleft> G ¬⊕ Skip)) (wp (body ;; Embed u <guillemotleft> G ¬⊕ Skip))" proof(intro le_transI le_funI, simp add:wp_eval) fix P::"'s expect"and s::'s assume sP: "sound P" with le have"t P ⊨!!! u P"by(auto) moreoverfrom sP ht hu have"sound (t P)""sound (u P)"by(auto) ultimatelyhave"wp body (t P) s ≤ wp body (u P) s" by(auto intro:le_funD[OF mono_transD, OF healthy_monoD, OF hb]) thus"«G¬ s * wp body (t P) s ≤«G¬ s * wp body (u P) s " by(auto intro:mult_left_mono) qed
lemma wlp_loop_step_mono: fixes t u::"'s trans" assumes mb: "nearly_healthy (wlp body)" and le: "le_utrans t u" and ht: "∧P. unitary P ==> unitary (t P)" and hu: "∧P. unitary P ==> unitary (u P)" shows"le_utrans (wlp (body ;; Embed t <guillemotleft> G ¬⊕ Skip)) (wlp (body ;; Embed u <guillemotleft> G ¬⊕ Skip))" proof(intro le_utransI le_funI, simp add:wp_eval) fix P::"'s expect"and s::'s assume uP: "unitary P" with le have"t P ⊨!!! u P"by(auto) moreoverfrom uP ht hu have"unitary (t P)""unitary (u P)"by(auto) ultimatelyhave"wlp body (t P) s ≤ wlp body (u P) s" by(rule le_funD[OF nearly_healthy_monoD[OF mb]]) thus"«G¬ s * wlp body (t P) s ≤«G¬ s * wlp body (u P) s " by(auto intro:mult_left_mono) qed
text‹For each sound expectation, we have a pre fixed point of the loop body.
lets us use the relevant fixed-point lemmas.› lemma lfp_loop_fp: assumes hb: "healthy (wp body)" and sP: "sound P" shows"λs. «G¬ s * wp body (λs. bound_of P) s + «N G¬ s * P s ⊨!!! λs. bound_of P" proof(rule le_funI) fix s from sP have"sound (λs. bound_of P)"by(auto) moreoverhence"bounded_by (bound_of P) (λs. bound_of P)"by(auto) ultimatelyhave"bounded_by (bound_of P) (wp body (λs. bound_of P))" using hb by(auto) hence"wp body (λs. bound_of P) s ≤ bound_of P"by(auto) moreoverfrom sP have"P s ≤ bound_of P"by(auto) ultimatelyhave"«G¬ s * wp body (λa. bound_of P) s + (1 - «G¬ s) * P s ≤ «G¬ s * bound_of P + (1 - «G¬ s) * bound_of P" by(blast intro:add_mono mult_left_mono) thus"«G¬ s * wp body (λa. bound_of P) s + «N G¬ s * P s ≤ bound_of P" by(simp add:algebra_simps negate_embed) qed
lemma lfp_loop_greatest: fixes P::"'s expect" assumes lb: "∧R. λs. «G¬ s * wp body R s + «N G¬ s * P s ⊨!!! R ==> sound R ==> Q ⊨!!!R" and hb: "healthy (wp body)" and sP: "sound P" and sQ: "sound Q" shows"Q ⊨!!! lfp_exp (λQ s. «G¬ s * wp body Q s + «N G¬ s * P s)" using sP by(auto intro!:lfp_exp_greatest[OF lb sQ] sP lfp_loop_fp hb)
lemma lfp_loop_sound: fixes P::"'s expect" assumes hb: "healthy (wp body)" and sP: "sound P" shows"sound (lfp_exp (λQ s. «G¬ s * wp body Q s + «N G¬ s * P s))" using assms by(auto intro!:lfp_exp_sound lfp_loop_fp)
lemma wlp_loop_step_unitary: fixes t u::"'s trans" assumes hb: "nearly_healthy (wlp body)" and ht: "∧P. unitary P ==> unitary (t P)" and uP: "unitary P" shows"unitary (wlp (body ;; Embed t <guillemotleft> G ¬⊕ Skip) P)" proof(intro unitaryI2 nnegI bounded_byI, simp_all add:wp_eval) fix s::'s from ht uP have utP: "unitary (t P)"by(auto) with hb have"unitary (wlp body (t P))"by(auto) hence"0 ≤ wlp body (t P) s"by(auto) with uP show"0 ≤« G ¬ s * wlp body (t P) s + (1 - « G ¬ s) * P s" by(auto intro!:add_nonneg_nonneg mult_nonneg_nonneg) from ht uP have"bounded_by 1 (t P)"by(auto) with utP hb have"bounded_by 1 (wlp body (t P))"by(auto) hence"wlp body (t P) s ≤ 1"by(auto) with uP have"«G¬ s * wlp body (t P) s + (1 - «G¬ s) * P s ≤«G¬ s * 1 + (1 - «G¬ s) * 1" by(blast intro:add_mono mult_left_mono) alsohave"... = 1"by(simp) finallyshow"«G¬ s * wlp body (t P) s + (1 - «G¬ s) * P s ≤ 1" . qed
lemma wp_loop_step_sound: fixes t u::"'s trans" assumes hb: "healthy (wp body)" and ht: "∧P. sound P ==> sound (t P)" and sP: "sound P" shows"sound (wp (body ;; Embed t <guillemotleft> G ¬⊕ Skip) P)" proof(intro soundI2 nnegI bounded_byI, simp_all add:wp_eval) fix s::'s from ht sP have stP: "sound (t P)"by(auto) with hb have"0 ≤ wp body (t P) s"by(auto) with sP show"0 ≤« G ¬ s * wp body (t P) s + (1 - « G ¬ s) * P s" by(auto intro!:add_nonneg_nonneg mult_nonneg_nonneg)
from ht sP have"sound (t P)"by(auto) moreoverhence"bounded_by (bound_of (t P)) (t P)"by(auto) ultimatelyhave"wp body (t P) s ≤ bound_of (t P)"using hb by(auto) hence"wp body (t P) s ≤ max (bound_of P) (bound_of (t P))"by(auto) moreover { from sP have"P s ≤ bound_of P"by(auto) hence"P s ≤ max (bound_of P) (bound_of (t P))"by(auto)
} ultimately have"«G¬ s * wp body (t P) s + (1 - «G¬ s) * P s ≤ «G¬ s * max (bound_of P) (bound_of (t P)) + (1 - «G¬ s) * max (bound_of P) (bound_of (t P))" by(blast intro:add_mono mult_left_mono) alsohave"... = max (bound_of P) (bound_of (t P))"by(simp add:algebra_simps) finallyshow"«G¬ s * wp body (t P) s + (1 - «G¬ s) * P s ≤ max (bound_of P) (bound_of (t P))" . qed
text‹This gives the equivalence with the alternative definition for
loops🚫‹‹\S7, p.~198, footnote 23› in "McIver_M_04"›.›
lemma wlp_Loop1: fixes body :: "'s prog" assumes unitary: "unitary P" and healthy: "nearly_healthy (wlp body)" shows"wlp (do G ⟶ body od) P = gfp_exp (λQ s. «G¬ s * wlp body Q s + «N G¬ s * P s)"
(is"?X = gfp_exp (?Y P)") proof - let"?Z u" = "(body ;; Embed u <guillemotleft> G ¬⊕ Skip)" show ?thesis proof(simp only: wp_eval, intro gfp_pulldown assms le_funI) fix u P show"wlp (?Z u) P = ?Y P (u P)"by(simp add:wp_eval negate_embed) next fix t::"'s trans"and P::"'s expect" assume ut: "∧Q. unitary Q ==> unitary (t Q)"and uP: "unitary P" thus"unitary (wlp (?Z t) P)" by(rule wlp_loop_step_unitary[OF healthy]) next fix P Q::"'s expect" assume uP: "unitary P"and uQ: "unitary Q" show"unitary (λa. « G ¬ a * wlp body Q a + «N G ¬ a * P a)" proof(intro unitaryI2 nnegI bounded_byI) fix s::'s from healthy uQ have"unitary (wlp body Q)"by(auto) hence"0 ≤ wlp body Q s"by(auto) with uP show"0 ≤«G¬ s * wlp body Q s + «N G¬ s * P s" by(auto intro!:add_nonneg_nonneg mult_nonneg_nonneg)
from healthy uQ have"bounded_by 1 (wlp body Q)"by(auto) with uP have"«G¬ s * wlp body Q s + (1 - «G¬ s) * P s ≤«G¬ s * 1 + (1 - «G¬ s) * 1" by(blast intro:add_mono mult_left_mono) alsohave"... = 1"by(simp) finallyshow"«G¬ s * wlp body Q s + «N G¬ s * P s ≤ 1" by(simp add:negate_embed) qed next fix P Q R::"'s expect"and s::'s assume uP: "unitary P"and uQ: "unitary Q"and uR: "unitary R" and le: "Q ⊨!!! R" hence"wlp body Q s ≤ wlp body R s" by(blast intro:le_funD[OF nearly_healthy_monoD, OF healthy]) thus"«G¬ s * wlp body Q s + «N G¬ s * P s ≤ «G¬ s * wlp body R s + «N G¬ s * P s" by(auto intro:mult_left_mono) next fix t u::"'s trans" assume"le_utrans t u" "∧P. unitary P ==> unitary (t P)" "∧P. unitary P ==> unitary (u P)" thus"le_utrans (wlp (?Z t)) (wlp (?Z u))" by(blast intro!:wlp_loop_step_mono[OF healthy]) qed qed
lemma wp_loop_sound: assumes sP: "sound P" and hb: "healthy (wp body)" shows"sound (wp do G ⟶ body od P)" proof(simp only: wp_eval, intro lfp_trans_sound sP) let ?v = "λP s. bound_of P" show"le_trans (wp (body ;; Embed ?v <guillemotleft> G ¬⊕ Skip)) ?v" by(intro le_transI, simp add:wp_eval lfp_loop_fp[unfolded negate_embed] hb) show"∧P. sound P ==> sound (?v P)"by(auto) qed
text‹Likewise, we can rewrite strict loops.› lemma wp_Loop1: fixes body :: "'s prog" assumes sP: "sound P" and healthy: "healthy (wp body)" shows"wp (do G ⟶ body od) P = lfp_exp (λQ s. «G¬ s * wp body Q s + «N G¬ s * P s)"
(is"?X = lfp_exp (?Y P)") proof - let"?Z u" = "(body ;; Embed u <guillemotleft> G ¬⊕ Skip)" show ?thesis proof(simp only: wp_eval, intro lfp_pulldown assms le_funI sP mono_transI) fix u P show"wp (?Z u) P = ?Y P (u P)"by(simp add:wp_eval negate_embed) next fix t::"'s trans"and P::"'s expect" assume ut: "∧Q. sound Q ==> sound (t Q)"and uP: "sound P" with healthy show"sound (wp (?Z t) P)"by(rule wp_loop_step_sound) next fix P Q::"'s expect" assume sP: "sound P"and sQ: "sound Q" show"sound (λa. « G ¬ a * wp body Q a + «N G ¬ a * P a)" proof(intro soundI2 nnegI bounded_byI) fix s::'s from sQ have"nneg Q""bounded_by (bound_of Q) Q"by(auto) with healthy have"bounded_by (bound_of Q) (wp body Q)"by(auto) hence"wp body Q s ≤ bound_of Q"by(auto) hence"wp body Q s ≤ max (bound_of P) (bound_of Q)"by(auto) moreover { from sP have"P s ≤ bound_of P"by(auto) hence"P s ≤ max (bound_of P) (bound_of Q)"by(auto)
} ultimatelyhave"«G¬ s * wp body Q s + «N G¬ s * P s ≤ «G¬ s * max (bound_of P) (bound_of Q) + «N G¬ s * max (bound_of P) (bound_of Q)" by(auto intro!:add_mono mult_left_mono) alsohave"... = max (bound_of P) (bound_of Q)"by(simp add:algebra_simps negate_embed) finallyshow"«G¬ s * wp body Q s + «N G¬ s * P s ≤ max (bound_of P) (bound_of Q)" .
from sP have"0 ≤ P s"by(auto) moreoverfrom sQ healthy have"0 ≤ wp body Q s"by(auto) ultimatelyshow"0 ≤«G¬ s * wp body Q s + «N G¬ s * P s" by(auto intro:add_nonneg_nonneg mult_nonneg_nonneg) qed next fix P Q R::"'s expect"and s::'s assume sQ: "sound Q"and sR: "sound R" and le: "Q ⊨!!! R" hence"wp body Q s ≤ wp body R s" by(blast intro:le_funD[OF mono_transD, OF healthy_monoD, OF healthy]) thus"«G¬ s * wp body Q s + «N G¬ s * P s ≤ «G¬ s * wp body R s + «N G¬ s * P s" by(auto intro:mult_left_mono) next fix t u::"'s trans" assume le: "le_trans t u" and st: "∧P. sound P ==> sound (t P)" and su: "∧P. sound P ==> sound (u P)" with healthy show"le_trans (wp (?Z t)) (wp (?Z u))" by(rule wp_loop_step_mono) next from healthy show"le_trans (wp (?Z (λP s. bound_of P))) (λP s. bound_of P)" by(intro le_transI, simp add:wp_eval lfp_loop_fp[unfolded negate_embed]) next fix P::"'s expect"and s::'s assume"sound P" thus"sound (λs. bound_of P)"by(auto) qed qed
lemma nearly_healthy_wlp_loop: fixes body::"'s prog" assumes hb: "nearly_healthy (wlp body)" shows"nearly_healthy (wlp (do G ⟶ body od))" proof(intro nearly_healthyI unitaryI2 nnegI2 bounded_byI2, simp_all add:wlp_Loop1 hb) fix P::"'s expect" assume uP: "unitary P" let"?X R" = "λQ s. « G ¬ s * wlp body Q s + «N G ¬ s * R s"
show"λs. 0 ⊨!!! gfp_exp (?X P)" proof(rule gfp_exp_upperbound) show"unitary (λs. 0::real)"by(auto) with hb have"unitary (wlp body (λs. 0))"by(auto) with uP show"λs. 0 ⊨!!! (?X P (λs. 0))" by(blast intro!:le_funI add_nonneg_nonneg mult_nonneg_nonneg) qed
fix Q::"'s expect" assume uQ: "unitary Q"and le: "P ⊨!!! Q" show"gfp_exp (?X P) ⊨!!! gfp_exp (?X Q)" proof(rule gfp_exp_least) fix R::"'s expect"assume uR: "unitary R" assume fp: "R ⊨!!! ?X P R" alsofrom le have"... ⊨!!! ?X Q R" by(blast intro:add_mono mult_left_mono le_funI) finallyshow"R ⊨!!! gfp_exp (?X Q)" using uR by(auto intro:gfp_exp_upperbound) next show"unitary (gfp_exp (?X Q))" proof(rule gfp_exp_unitary, intro unitaryI2 nnegI bounded_byI) fix R::"'s expect"and s::'s assume uR: "unitary R" with hb have ubP: "unitary (wlp body R)"by(auto) with uQ show"0 ≤« G ¬ s * wlp body R s + «N G ¬ s * Q s" by(blast intro:add_nonneg_nonneg mult_nonneg_nonneg)
from ubP uQ have"wlp body R s ≤ 1""Q s ≤ 1"by(auto) hence"« G ¬ s * wlp body R s + «N G ¬ s * Q s ≤«G¬ s * 1 + «N G¬ s * 1" by(blast intro:add_mono mult_left_mono) thus"« G ¬ s * wlp body R s + «N G ¬ s * Q s ≤ 1" by(simp add:negate_embed) qed qed qed
text‹We show healthiness by appealing to the properties of expectation fixed points, applied
the alternative loop definition.› lemma healthy_wp_loop: fixes body::"'s prog" assumes hb: "healthy (wp body)" shows"healthy (wp (do G ⟶ body od))" proof - let"?X P" = "(λQ s. «G¬ s * wp body Q s + «N G¬ s * P s)" show ?thesis proof(intro healthy_parts bounded_byI2 nnegI2, simp_all add:wp_Loop1 hb soundI2 sound_intros) fix P::"'s expect"and c::real and s::'s assume sP: "sound P"and nnc: "0 ≤ c" show"c * (lfp_exp (?X P)) s = lfp_exp (?X (λs. c * P s)) s" proof(cases) assume"c = 0"thus ?thesis proof(simp, intro antisym) from hb have fp: "λs. «G¬ s * wp body (λ_. 0) s ⊨!!! λs. 0"by(simp) hence"lfp_exp (λP s. «G¬ s * wp body P s) ⊨!!! λs. 0" by(auto intro:lfp_exp_lowerbound) thus"lfp_exp (λP s. «G¬ s * wp body P s) s ≤ 0"by(auto) have"λs. 0 ⊨!!! lfp_exp (λP s. «G¬ s * wp body P s)" by(auto intro:lfp_exp_greatest fp) thus"0 ≤ lfp_exp (λP s. «G¬ s * wp body P s) s"by(auto) qed next have onesided: "∧P c. c ≠ 0 ==> 0 ≤ c ==> sound P ==> λa. c * lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) a ⊨!!! lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * (c * P b))" proof - fix P::"'s expect"and c::real assume cnz: "c ≠ 0"and nnc: "0 ≤ c"and sP: "sound P" with nnc have cpos: "0 < c"by(auto) hence nnic: "0 ≤ inverse c"by(auto) show"λa. c * lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) a ⊨!!! lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * (c * P b))" proof(rule lfp_exp_greatest) fix Q::"'s expect" assume sQ: "sound Q" and fp: "λb. «G¬ b * wp body Q b + «N G¬ b * (c * P b) ⊨!!! Q" hence"∧s. «G¬ s * wp body Q s + «N G¬ s * (c * P s) ≤ Q s"by(auto) with nnic have"∧s. inverse c * («G¬ s * wp body Q s + «N G¬ s * (c * P s)) ≤ inverse c * Q s" by(auto intro:mult_left_mono) hence"∧s. «G¬ s * (inverse c * wp body Q s) + (inverse c * c) * «N G¬ s * P s ≤ inverse c * Q s" by(simp add:algebra_simps) hence"∧s. «G¬ s * wp body (λs. inverse c * Q s) s + «N G¬ s * P s ≤ inverse c * Q s" by(simp add:cnz scalingD[OF healthy_scalingD, OF hb sQ nnic]) hence"λs. «G¬ s * wp body (λs. inverse c * Q s) s + «N G¬ s * P s ⊨!!! λs. inverse c * Q s"by(rule le_funI) moreoverfrom nnic sQ have"sound (λs. inverse c * Q s)" by(iprover intro:sound_intros) ultimatelyhave"lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) ⊨!!! λs. inverse c * Q s" by(rule lfp_exp_lowerbound) hence"∧s. lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) s ≤ inverse c * Q s" by(rule le_funD) with nnc have"∧s. c * lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) s ≤ c * (inverse c * Q s)" by(auto intro:mult_left_mono) alsofrom cnz have"∧s. ... s = Q s"by(simp) finallyshow"λa. c * lfp_exp (λa b. «G¬ b * wp body a b + «N G¬ b * P b) a ⊨!!! Q" by(rule le_funI) next from sP have"sound (λs. bound_of P)"by(auto) with hb sP have"sound (lfp_exp (?X P))" by(blast intro:lfp_exp_sound lfp_loop_fp) with nnc show"sound (λs. c * lfp_exp (?X P) s)" by(auto intro!:sound_intros)
from hb sP nnc show"λs. «G¬ s * wp body (λs. bound_of (λs. c * P s)) s + «N G¬ s * (c * P s) ⊨!!! λs. bound_of (λs. c * P s)" by(iprover intro:lfp_loop_fp sound_intros)
from sP nnc show"sound (λs. bound_of (λs. c * P s))" by(auto intro!:sound_intros) qed qed
assume nzc: "c ≠ 0" show ?thesis (is"?X P c s = ?Y P c s") proof(rule fun_cong[where x=s], rule antisym) from nzc nnc sP show"?X P c ⊨!!! ?Y P c"by(rule onesided)
from nzc have nzic: "inverse c ≠ 0"by(auto) moreoverwith nnc have nnic: "0 ≤ inverse c"by(auto) moreoverfrom nnc sP have scP: "sound (λs. c * P s)"by(auto intro!:sound_intros) ultimatelyhave"?X (λs. c * P s) (inverse c) ⊨!!! ?Y (λs. c * P s) (inverse c)" by(rule onesided) with nnc have"λs. c * ?X (λs. c * P s) (inverse c) s ⊨!!! λs. c * ?Y (λs. c * P s) (inverse c) s" by(blast intro:mult_left_mono) with nzc show"?Y P c ⊨!!! ?X P c"by(simp add:mult.assoc[symmetric]) qed qed next fix P::"'s expect"and b::real assume bP: "bounded_by b P"and nP: "nneg P" show"lfp_exp (λQ s. «G¬ s * wp body Q s + «N G¬ s * P s) ⊨!!! λs. b" proof(intro lfp_exp_lowerbound le_funI) fix s::'s from bP nP hb have"bounded_by b (wp body (λs. b))"by(auto) hence"wp body (λs. b) s ≤ b"by(auto) moreoverfrom bP have"P s ≤ b"by(auto) ultimatelyhave"«G¬ s * wp body (λs. b) s + «N G¬ s * P s ≤«G¬ s * b + «N G¬ s * b" by(auto intro!:add_mono mult_left_mono) alsohave"... = b"by(simp add:negate_embed field_simps) finallyshow"«G¬ s * wp body (λs. b) s + «N G¬ s * P s ≤ b" . from bP nP have"0 ≤ b"by(auto) thus"sound (λs. b)"by(auto) qed from hb bP nP show"λs. 0 ⊨!!! lfp_exp (λQ s. «G¬ s * wp body Q s + «N G¬ s * P s)" by(auto dest!:sound_nneg intro!:lfp_loop_greatest) next fix P Q::"'s expect" assume sP: "sound P"and sQ: "sound Q"and le: "P ⊨!!! Q" show"lfp_exp (?X P) ⊨!!! lfp_exp (?X Q)" proof(rule lfp_exp_greatest) fix R::"'s expect" assume sR: "sound R" and fp: "λs. «G¬ s * wp body R s + «N G¬ s * Q s ⊨!!! R" from le have"λs. «G¬ s * wp body R s + «N G¬ s * P s ⊨!!! λs. «G¬ s * wp body R s + «N G¬ s * Q s" by(auto intro:le_funI add_left_mono mult_left_mono) alsonote fp finallyshow"lfp_exp (λR s. «G¬ s * wp body R s + «N G¬ s * P s) ⊨!!! R" using sR by(auto intro:lfp_exp_lowerbound) next from hb sP show"sound (lfp_exp (λR s. «G¬ s * wp body R s + «N G¬ s * P s))" by(rule lfp_loop_sound) from hb sQ show"λs. «G¬ s * wp body (λs. bound_of Q) s + «N G¬ s * Q s ⊨!!! λs. bound_of Q" by(rule lfp_loop_fp) from sQ show"sound (λs. bound_of Q)"by(auto) qed qed qed
¤ 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.0.36Bemerkung:
(vorverarbeitet am 2026-09-09)
¤
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.