Theory DiscussionO
subsection ‹Relation between the Hoare logics in big-O style›
theory DiscussionO
imports SepLogK_Hoare QuantK_Hoare Nielson_Hoare
begin
subsubsection ‹Relation Nielson to quantHoare›
definition emN :: "qassn ⇒ Nielson_Hoare.assn2" where "emN P = (λl s. P s < ∞)"
lemma assumes s: "⊨⇩1 { emN P'} c { %s. (THE e. enat e = P' s - Q' (THE t. (∃n. (c, s) ⇒ n ⇓ t ) )) ⇓ emN Q' }" (is "⊨⇩1 { ?P } c { ?e ⇓ ?Q }")
shows quantNielson: "⊨⇩2⇩' { P' } c { Q' }"
proof -
from s obtain k where k: "k>0" and qd: "⋀l s. emN P' l s ⟹ (∃t p. (c, s) ⇒ p ⇓ t ∧ p ≤ k * ?e s ∧ emN Q' l t)"
unfolding hoare1_valid_def by blast
show ?thesis unfolding QuantK_Hoare.hoare2o_valid_def
apply(rule exI[where x=k])
apply safe apply fact
proof -
fix s
assume P': "P' s < ∞"
then have "(emN P') (λ_. 0) s" unfolding emN_def by auto
with qd obtain p t where i: "(c, s) ⇒ p ⇓ t" and p: "p ≤ k * ?e s" and e: "emN Q' (λ_. 0) t"
by blast
have t: "↓⇩s (c, s) = t" using bigstepT_the_state[OF i] by auto
from P' obtain pre where pre: "P' s = enat pre" by fastforce
from e have "Q' t < ∞" unfolding emN_def by auto
then obtain post where post: "Q' t = enat post" by fastforce
have "p > 0" using i bigstep_progress by auto
thm enat.inject idiff_enat_enat the_equality
have k: "(THE e. enat e = P' s - Q' (THE t. ∃n. (c, s) ⇒ n ⇓ t)) = pre - post"
unfolding t pre post apply(rule the_equality)
using idiff_enat_enat by auto
with p have ieq: "p ≤ k * (pre - post)" by auto
then have "p + k * post ≤ k * pre" using ‹p>0›
using diff_mult_distrib2 by auto
then
have ii: "enat p + k * Q' t ≤ k * P' s" unfolding post pre by simp
from i ii show "(∃t p. (c, s) ⇒ p ⇓ t ∧ enat p + k * Q' t ≤ k * P' s)" by auto
qed
qed
lemma assumes s: "⊨⇩2⇩' { %s . emb (∀l. P l s) + enat (e s) } c { %s. emb (∀l. Q l s) }" (is "⊨⇩2⇩' { ?P } c { ?Q }")
and sP: "⋀l t. P l t ⟹ ∀l. P l t"
and sQ: "⋀l t. Q l t ⟹ ∀l. Q l t"
shows NielsonQuant: "⊨⇩1 { P } c { e ⇓ Q }"
proof -
from s obtain k where k: "k>0" and qd: "⋀s. ?P s < ∞ ⟶ (∃t p. (c, s) ⇒ p ⇓ t ∧ enat p + enat k * ?Q t ≤ enat k * ?P s)"
unfolding QuantK_Hoare.hoare2o_valid_def by blast
show ?thesis unfolding hoare1_valid_def
apply(rule exI[where x=k])
apply safe apply fact
proof -
fix l s
assume P': "P l s"
then have aP: "∀l. P l s" using sP by auto
then have P: "?P s < ∞" by auto
with qd obtain p t where i: "(c, s) ⇒ p ⇓ t" and p: "enat p + enat k * ?Q t ≤ enat k * ?P s"
by blast
have t: "↓⇩s (c, s) = t" using bigstepT_the_state[OF i] by auto
from P have Q: "Q l t" using p k
apply auto
by (metis (full_types) emb.simps(1) enat_ord_simps(2) imult_is_infinity infinity_ileE not_less_zero plus_enat_simps(3))
with sQ have "∀l. Q l t" by auto
then have "?Q t = 0" by auto
with p have "enat p ≤ enat k * ?P s" by auto
with aP have p': "p ≤ k * e s" by auto
from i Q p' show "∃t p. (c, s) ⇒ p ⇓ t ∧ p ≤ k * e s ∧ Q l t" by blast
qed
qed
subsubsection ‹Relation SepLogic to quantHoare›
definition em :: "qassn ⇒ (pstate_t ⇒ bool)" where
"em P = (%(ps,n). (∀ex. P (Partial_Evaluation.emb ps ex) ≤ enat n) )"
lemma assumes s: "⊨⇩3⇩' { em P} c { em Q }"
shows "⊨⇩2⇩' { P } c { Q }"
proof -
from s obtain k where k: "0<k" and s': "⋀ps n. em P (ps, n) ⟹ (∃ps' ps'' m e e'. (c, ps) ⇒⇩A m ⇓ ps'+ ps'' ∧ ps' ## ps'' ∧ k * n = k * e + e' + m ∧ em Q (ps', e))" unfolding hoare3o_valid_def by auto
{
fix s
assume P: "P s < ∞"
then obtain n where n: "P s = enat n"
by fastforce
with P have "em P (part s, n)" unfolding em_def by auto
with s' obtain ps' ps'' m e e' where c: "(c, part s) ⇒⇩A m ⇓ ps' + ps''" and orth: "ps' ## ps''"
and m: "k * n = k * e + e' + m" and Q: "em Q (ps', e)" by blast
from Q have q: "Q (Partial_Evaluation.emb ps' (Partial_Evaluation.emb ps'' (λ_. 0))) ≤ enat (e)" unfolding em_def by auto
have z: "(Partial_Evaluation.emb ps' (Partial_Evaluation.emb ps'' (λ_. 0))) = (Partial_Evaluation.emb (ps'+ps'') (λ_. 0))"
unfolding Partial_Evaluation.emb_def apply (auto simp: plus_fun_def)
apply (rule ext) subgoal for v apply (cases "ps' v") apply auto using orth by (auto simp: sep_disj_fun_def domain_conv) done
from q z have q: "enat k * Q (Partial_Evaluation.emb (ps'+ps'') (λ_. 0)) ≤ enat k * enat e" using k
by (metis i0_lb mult_left_mono)
have i: "(c, s) ⇒ m ⇓ (Partial_Evaluation.emb (ps'+ps'') (λ_. 0))" using part_to_full'[OF c] by simp
have ii: "enat m + enat k * Q (Partial_Evaluation.emb (ps'+ps'') (λ_. 0)) ≤ enat k * P s" unfolding n using q m
using enat_ile by fastforce
from i ii have "(∃t p. (c, s) ⇒ p ⇓ t ∧ enat p + enat k * Q t ≤ enat k * P s)" by auto
} note B=this
show ?thesis unfolding QuantK_Hoare.hoare2o_valid_def
apply(rule exI[where x=k], safe) apply fact
apply (fact B) done
qed
definition embe :: "(pstate_t ⇒ bool) ⇒ qassn" where
"embe P = (%s. Inf {enat n|n. P (part s, n)} )"
lemma assumes s: "⊨⇩2⇩' { embe P } c { embe Q }" and full: "⋀ps n. P (ps,n) ⟹ dom ps = UNIV"
shows "⊨⇩3⇩' { P} c { Q }"
proof -
from s obtain k where k: "k>0" and s: "⋀s. embe P s < ∞ ⟶ (∃t p. (c, s) ⇒ p ⇓ t ∧ enat p + enat k * embe Q t ≤ enat k * embe P s)"
unfolding QuantK_Hoare.hoare2o_valid_def by auto
{ fix ps n
let ?s =" (Partial_Evaluation.emb ps (λ_. 0))"
assume P: "P (ps, n)"
with full have "dom ps = UNIV" by auto
then have ps: "part ?s = ps" by simp
from P have l': "({enat n |n. P (ps, n)} = {}) = False " by auto
have t: "embe P ?s < ∞" unfolding embe_def Inf_enat_def ps l'
apply(rule ccontr) using l' apply auto
by (metis (mono_tags, lifting) Least_le infinity_ileE)
with s obtain t p where c: "(c, ?s) ⇒ p ⇓ t" and ineq: "enat p + enat k * embe Q t ≤ enat k * embe P ?s" by blast
from t obtain z where z: "embe P ?s = enat z"
using less_infinityE by blast
with ineq obtain y where y: "embe Q t = enat y"
using k by fastforce
then have l: "embe Q t < ∞" by auto
then have zz: "({enat n|n. Q (part t, n)} = {}) = False" unfolding embe_def Inf_enat_def apply safe by simp
from y have "Q (part t, y)" unfolding embe_def zz Inf_enat_def apply auto
using zz apply auto by (smt Collect_empty_eq LeastI enat.inject)
from full_to_part[OF c] ps have c': "(c, ps) ⇒⇩A p ⇓ part t" by auto
have "⋀P n. P (n::nat) ⟹ (LEAST n. P n) ≤ n" apply(rule Least_le) by auto
from z P have zn: "z ≤ n" unfolding embe_def ps unfolding embe_def Inf_enat_def l'
apply auto
by (metis (mono_tags, lifting) Least_le enat_ord_simps(1))
from ineq z y have "enat p + enat k * y ≤ enat k * z" by auto
then have "p + k * y ≤ k * z" by auto
also have "… ≤ k * n" using zn k by simp
finally obtain e' where "k * n = k * y + e' + p" using k by (metis add.assoc add.commute le_iff_add)
have "∃ps' ps'' m e e'. (c, ps) ⇒⇩A m ⇓ ps' + ps'' ∧ ps' ## ps'' ∧ k * n = k * e + e' + m ∧ Q (ps', e)"
apply(rule exI[where x="part t"])
apply(rule exI[where x="0"])
apply(rule exI[where x="p"])
apply(rule exI[where x="y"])
apply(rule exI[where x="e'"]) apply auto by fact+
}
show ?thesis unfolding hoare3o_valid_def apply(rule exI[where x=k], safe)
apply fact by fact
qed
subsection ‹A General Validity Predicate with Time›
definition valid where
"valid P c Q n = (∀s. P s ⟶ (∃s' m. (c, s) ⇒ m ⇓ s' ∧ m ≤ n ∧ Q s'))"
definition validk where
"validk P c Q n = (∃k>0. (∀s. P s ⟶ (∃s' m. (c, s) ⇒ m ⇓ s' ∧ m ≤ k * n ∧ Q s')))"
lemma "validk P c Q n = (∃k>0. valid P c Q (k*n))"
unfolding valid_def validk_def by simp
subsubsection ‹Relation between valid predicate and Quantitative Hoare Logic›
lemma "⊨⇩2⇩' {%s. emb (P s) + enat n} c { λs. emb (Q s) } ⟹ ∃k>0. valid P c Q (k*n)"
proof -
assume valid: "⊨⇩2⇩' {λs. ↑ (P s) + enat n} c {λs. ↑ (Q s)}"
then obtain k where val: "⋀s. ↑ (P s) + enat n < ∞ ⟹ (∃t p. (c, s) ⇒ p ⇓ t ∧ enat p + enat k * ↑ (Q t) ≤ enat k * (↑ (P s) + enat n))"
and k: "k>0" unfolding QuantK_Hoare.hoare2o_valid_def by blast
{
fix s
assume Ps: "P s"
then have " ↑ (P s) + enat n < ∞" by auto
with val obtain t m where
c: "(c, s) ⇒ m ⇓ t" and "enat m + k * ↑ (Q t) ≤ k * (↑ (P s) + enat n)" by blast
then have "m ≤ k * n ∧ Q t" using k
using Ps add.commute add.right_neutral emb.simps(1) emb.simps(2) enat_ord_simps(1) infinity_ileE plus_enat_simps(3)
by (metis (full_types) mult_zero_right not_gr_zero times_enat_simps(1) times_enat_simps(4))
with c
have "(∃s' m. (c, s) ⇒ m ⇓ s' ∧ m ≤ k * n ∧ Q s')" by blast
} note bla=this
show "∃k>0. valid P c Q (k*n)" unfolding valid_def apply(rule exI[where x=k]) using bla k by auto
qed
lemma valid_quantHoare: "∃k>0. valid P c Q (k*n) ⟹ ⊨⇩2⇩' {%s. emb (P s) + enat n} c { λs. emb (Q s) }"
proof -
assume "∃k>0. valid P c Q (k*n)"
then obtain k where valid: "valid P c Q (k*n)" and k: "k>0" by blast
{
fix s
assume "(%s. emb (P s) + enat n) s < ∞"
then have Ps: "P s" apply auto
by (metis emb.elims enat.distinct(2) enat.simps(5) enat_defs(4))
with valid[unfolded valid_def] obtain t m where
c: "(c, s) ⇒ m ⇓ t" and "m ≤ k * n" "Q t" by blast
then have "enat m + k * ↑ (Q t) ≤ k * (↑ (P s) + enat n)" using Ps by simp
with c
have "(∃s' m. (c, s) ⇒ m ⇓ s' ∧ enat m + enat k * ↑ (Q s') ≤ enat k * (↑ (P s) + enat n))" by blast
} note funk=this
show "⊨⇩2⇩' {%s. emb (P s) + enat n} c { λs. emb (Q s) }" unfolding QuantK_Hoare.hoare2o_valid_def
apply(rule exI[where x=k]) using funk k by auto
qed
subsubsection ‹Relation between valid predicate and Hoare Logic based on Separation Logic›
definition "embP2 P = (%(ps,n). ∀s. P (Partial_Evaluation.emb ps s) ∧ n = 0)"
definition "embP3 P = (%(ps,n). dom ps = UNIV ∧ (∀s. P (Partial_Evaluation.emb ps s)) ∧ n = 0)"
lemma emp: "a + Map.empty = a"
by (simp add: plus_fun_conv)
lemma oneway: "⊨⇩3⇩' {embP3 P ** $n} c {embP2 Q} ⟹ validk P c Q n"
proof -
assume partial_true: "⊨⇩3⇩' {embP3 P ** $n} c {embP2 Q}"
from partial_true[unfolded hoare3o_valid_def] obtain k where k: "k>0" and
q : "∀ps na. (embP3 P ∧* $ n) (ps, na) ⟶
(∃ps' ps'' m e e'. (c, ps) ⇒⇩A m ⇓ ps' + ps'' ∧ ps' ## ps'' ∧ k * na = k * e + e' + m ∧ embP2 Q (ps', e)) " by blast
{ fix s
assume "P s"
then have g: " (embP3 P ∧* $ n) (part s, n)"
unfolding embP3_def dollar_def sep_conj_def by auto
from q g
obtain ps' ps'' m e e' where pbig: "(c, part s) ⇒⇩A m ⇓ ps' + ps''" and orth: "ps' ## ps''"
and ii: "k * n = k * e + e' + m" and erg: "embP2 Q (ps', e)" by blast
have ii': "m ≤ k * n" using ii by auto
from part_to_full'[OF pbig] have i: "(c, s ) ⇒ m ⇓ Partial_Evaluation.emb (ps' + ps'') s" by simp
from erg have z2: "⋀s. Q (Partial_Evaluation.emb ps' s)" unfolding embP2_def by auto
have "Partial_Evaluation.emb (ps' + ps'') s = Partial_Evaluation.emb (ps'' + ps') s"
using orth by (simp add: sep_add_commute)
also have "Partial_Evaluation.emb (ps'' + ps') s = Partial_Evaluation.emb (ps') (Partial_Evaluation.emb (ps'') s)"
apply rule
unfolding emb_def plus_fun_conv map_add_def
by (metis option.case_eq_if option.simps(5))
finally have z: "Partial_Evaluation.emb (ps' + ps'') s = Partial_Evaluation.emb (ps') (Partial_Evaluation.emb (ps'') s)" .
have iii: "Q (Partial_Evaluation.emb (ps' + ps'') s)" unfolding z apply (fact) .
from i ii' iii
have "∃s' m. (c, s) ⇒ m ⇓ s' ∧ m ≤ k * n ∧ Q s'" by auto
}
with k show "validk P c Q n" unfolding validk_def by blast
qed
lemma theother: "validk P c Q n ⟹ ⊨⇩3⇩' {embP3 P ** $n} c {embP2 Q }"
proof -
assume valid: "validk P c Q n"
then obtain k where k : "k>0" and v: "(∀s. P s ⟶ (∃s' m. (c, s) ⇒ m ⇓ s' ∧ m ≤ k * n ∧ Q s'))"
unfolding validk_def by blast
{ fix ps na
assume an: "(embP3 P ∧* $ n) (ps, na)"
have dom: "dom ps = UNIV" and Pps: "⋀s. P (Partial_Evaluation.emb ps s)" and nan: "na = n" using an unfolding sep_conj_def
by (auto simp: embP3_def dollar_def)
from v Pps
obtain s' m where big: "(c, (Partial_Evaluation.emb ps (%_. 0))) ⇒ m ⇓ s'" and ii: "m ≤ k * n" and erg: "Q s'" by blast
have "part (Partial_Evaluation.emb ps (λ_. 0)) = ps " using dom by simp
with full_to_part[OF big] have i: "(c, ps) ⇒⇩A m ⇓ part s'" by auto
have iii: "embP2 Q (part s', 0)"
unfolding embP2_def apply auto by fact
have "k * na = k * n - m + m" using ii k nan by simp
have "(∃ps' ps'' m e e'. (c, ps) ⇒⇩A m ⇓ ps' + ps'' ∧ ps' ## ps'' ∧ k * na = k * e + e' + m ∧ embP2 Q (ps', e))"
apply(rule exI[where x="part s'"])
apply(rule exI[where x="0"])
apply(rule exI[where x="m"])
apply(rule exI[where x="0"])
apply(rule exI[where x="k * n - m"]) apply auto
by fact+
}
with k show "⊨⇩3⇩' {embP3 P ** $n} c {embP2 Q }" unfolding hoare3o_valid_def by blast
qed
lemma "validk P c Q n ⟷ ⊨⇩3⇩' {embP3 P ** $n} c {embP2 Q }"
using oneway and theother by metis
end