(* 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 ` (\<lambda>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.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.