Theory DRAT

(* Title:      Demonic refinement algebra
   Author:     Alasdair Armstrong, Victor B. F. Gomes, Georg Struth
   Maintainer: Georg Struth <g.struth at sheffield.ac.uk>
*)

section ‹Demonic Refinement Algebra with Tests›

theory DRAT
  imports KAT Kleene_Algebra.DRA
begin

text ‹
  In this section, we define demonic refinement algebras with tests and prove the most important theorems from
  the literature. In this context, tests are also known as guards.
›

class drat = dra + test_semiring_zerol
begin

subclass kat_zerol ..

text ‹
  An assertion is a mapping from a guard to a subset similar to tests, but it aborts if the predicate does
  not hold.
›

definition assertion :: "'a  'a" ("_o" [101] 100) where
  "test p  po = !p + 1"

lemma asg: "test p; test q  q  1  1  po"
  by (simp add: assertion_def local.test_subid)

lemma assertion_isol: "test p  y  pox  py  x"
proof
  assume assms: "test p" "y  pox"
  hence "py  p!px + px"
    by (metis add_commute assertion_def local.distrib_left local.iteration_prod_unfold local.iteration_unfoldl_distr local.mult_isol local.top_mult_annil mult_assoc)
  also have "...  x"
    by (simp add: assms(1) local.test_restrictl)
  finally show "py  x"
    by metis
next
  assume assms: "test p" "py  x"
  hence "popy = !ppy + py"
    by (metis assertion_def distrib_right' mult_1_left mult.assoc)
  also have "... = !p + py"
    by (metis mult.assoc top_mult_annil)
  moreover have "popy  pox"
    by (metis assms(2) mult.assoc mult_isol)
  moreover have "!py + py  !p + py"
    using local.add_iso local.top_elim by blast
  ultimately show "y  pox"    
    by (metis add.commute assms(1) distrib_right' mult_1_left order_trans test_add_comp)
qed

lemma assertion_isor: "test p  y  xp  ypo  x"
proof
  assume assms: "test p" "y  xp"
  hence "ypo  xp!p + xp"
    by (metis mult_isor assertion_def assms(1) distrib_left mult_1_right mult.assoc)
  also have "...  x"
    by (metis assms(1) local.iteration_idep local.join.sup.absorb_iff1 local.join.sup_commute local.join.sup_ge2 local.mult_1_right local.mult_isol_var local.mult_isor local.mult_onel local.test_add_comp local.test_comp_mult2 mult_assoc)
  finally show "ypo  x"
    by metis
next
  assume assms: "test p" "ypo  x"
  have "y  y(!p + p)"
    by (metis join.sup_mono mult_isol order_refl order_refl top_elim add.commute assms(1) mult_1_right test_add_comp)
  also have "... = ypop"
    by (metis assertion_def assms(1) distrib_right' mult_1_left mult.assoc top_mult_annil)
  finally show "y  xp"
    by (metis assms(2) mult_isor order_trans)
qed

lemma assertion_iso: "test p; test q  xqo  pox  px  xq"
  by (metis assertion_isol assertion_isor mult.assoc)

lemma total_correctness: "test p; test q  px!q = 0  x!q  !p"
  apply standard
  apply (metis local.test_eq4 local.top_elim mult_assoc)
  by (metis annil order.antisym test_comp_mult2 join.bot_least mult_assoc mult_isol)

lemma test_iteration_sim: "test p; px  xp  px  xp"
  by (metis iteration_sim)

lemma test_iteration_annir: "test p  !p(px) = !p"
  by (metis annil test_comp_mult1 iteration_idep mult.assoc)

text ‹Next we give an example of a program transformation from von Wright~cite"Wright02".›

lemma loop_refinement: "test p; test q  (px)!p  (pqx)!(pq)(px)!p"
proof -
  assume assms: "test p" "test q"
  hence "(px)!p = ((pq) + !(pq))(px)!p"
    by (simp add: local.test_mult_closed)
  also have "... = (pq)(px)!p + !(pq)(px)!p"
    by (metis distrib_right')
  also have "... = (pq)!p + (pq)(px)(px)!p + !(pq)(px)!p"
    by (metis iteration_unfoldr_distr mult.assoc iteration_unfold_eq distrib_left mult.assoc)
  also have "... = (pq)(px)(px)!p + !(pq)(px)!p"
    by (metis assms less_eq_def test_preserve2 join.bot_least)
  finally have "(px)!p  pqx(px)!p + !(pq)(px)!p"
    by (metis assms(1) assms(2) order.eq_iff local.test_mult_comm_var local.test_preserve mult_assoc)
  thus ?thesis
    by (metis coinduction add.commute mult.assoc)
qed

text ‹Finally, we prove different versions of Back's atomicity refinement theorem for action systems.›

lemma atom_step1: "rb  br  (a + b + r) = br(abr)"
  apply (subgoal_tac "(a + b + r) = (b + r)(a(b + r))")
  apply (metis iteration_sep mult.assoc)
  by (metis add_assoc' add.commute iteration_denest)

 
lemma atom_step2: 
  assumes "s = sq" "qb = 0" "rq  qr" "ql  lq" "r = r" "test q"
  shows "slbrq(abrq)  slr(abqr)"
proof -
  have "slbrq(abrq)  slbrq(abqr)"
    by (metis assms(3) assms(5) star_sim1 mult.assoc mult_isol iteration_iso)
  also have "...  sqlbr(abqr)"
    using assms(1) assms(6) local.mult_isor local.test_restrictr by auto
  also have "...  slqbr(abqr)"
    by (metis assms(4) iteration_sim mult.assoc mult_double_iso mult_double_iso)
  also have "...  slrqr(abqr)" 
    by (metis assms(2) join.bot_least iteration_sim mult.assoc mult_double_iso)
  also have "...  slr(abqr)"
    by (metis assms(6) mult.assoc mult_isol test_restrictl iteration_idem mult.assoc)
  finally show "slbrq(abrq)  slr(abqr)"
    by metis
qed

lemma atom_step3: 
  assumes "rl  lr" "al  la" "bl  lb" "ql  lq" "b = b"
  shows "lr(abqr) = (abq + l + r)"
proof -
  have "(abq + r)l  ablq + lr"
    by (metis distrib_right join.sup_mono assms(1,4) mult.assoc mult_isol)
  also have "...  albq + lr"
    by (metis assms(3) assms(5) star_sim1 add_iso mult.assoc mult_double_iso)
  also have "...  l(abq + r)"
    by (metis add_iso assms(2) mult_isor distrib_left mult.assoc)
  finally have "(abq + r)l  l(abq + r)"
    by metis
  moreover have "lr(abqr) = l(abq + r)"
    by (metis add.commute mult.assoc iteration_denest)
  ultimately show ?thesis
    by (metis add.commute add.left_commute iteration_sep)
qed

text ‹
  This is Back's atomicity refinement theorem, as specified by von Wright~\cite {Wright02}.
›

theorem atom_ref_back: 
  assumes "s = sq" "a = qa" "qb = 0"
          "rb  br" "rl  lr" "rq  qr"
          "al  la" "bl  lb" "ql  lq"
          "r = r" "b = b" "test q"
  shows "s(a + b + r + l)q  s(abq + r + l)"
proof -
  have "(a + b + r)l  l(a + b + r)"
    by (metis join.sup_mono distrib_right' assms(5) assms(7) assms(8) distrib_left)
  hence "s(l + a + b + r)q = sl(a + b + r)q"
    by (metis add.commute add.left_commute mult.assoc iteration_sep)
  also have "...  slbrq(abrq)"
    by (metis assms(2,4,10,11) atom_step1 iteration_slide eq_refl mult.assoc)
  also have "...  slr(abqr)" 
    by (metis assms(1) assms(10) assms(12) assms(3) assms(6) assms(9) atom_step2)
  also have "...  s(abq + l + r)"
    by (metis assms(11) assms(5) assms(7) assms(8) assms(9) atom_step3 eq_refl mult.assoc)
  finally show ?thesis
    by (metis add.commute add.left_commute)
qed

text ‹
  This variant is due to H\"ofner, Struth and Sutcliffe~cite"HofnerSS09".
›

theorem atom_ref_back_struth: 
  assumes "s  sq" "a  qa" "qb = 0"
          "rb  br" "rq  qr"
          "(a + r + b)l  l(a + r + b)" "ql  lq"
          "r = r" "q  1"
  shows "s(a + b + r + l)q  s(abq + r + l)"
proof -
  have "s(a + b + r + l)q = sl(a + b + r)q"
    by (metis add.commute add.left_commute assms(6) iteration_sep mult.assoc)
  also have "... = sl(b + r)(a(b + r))q"
    by (metis add_assoc' add.commute iteration_denest add.commute mult.assoc)
  also have "... = slbr(abr)q"
    by (metis assms(4) iteration_sep mult.assoc)
  also have "...  slbr(qabr)q"
    by (metis assms(2) iteration_iso mult_isol_var eq_refl order_refl)
  also have "... = slbrq(abrq)"
    by (metis iteration_slide mult.assoc)
  also have "...  sqlbrq(abrq)"
    by (metis assms(1) mult_isor)
  also have "...  slqbrq(abrq)"
    by (metis assms(7) iteration_sim mult.assoc mult_double_iso)
  also have "...  slqrq(abrq)"
    by (metis assms(3) iteration_idep mult.assoc order_refl)
  also have "...  slqrq(abrq)"
    by (metis assms(8) eq_refl)
  also have "...  slqrq(abqr)"
    by (metis assms(5) iteration_iso mult.assoc mult_isol star_sim1)
  also have "... = slqrq(abqr)"
    by (metis assms(8))
  also have "...  slrq(abqr)"
    by (metis assms(9) mult_1_right mult_double_iso mult_isor)
  also have "...  slr(abqr)"
    by (metis assms(9) mult_1_right mult_double_iso)
  also have "... = sl(abq + r)"
    by (metis add.commute mult.assoc iteration_denest)
  also have "...  s(abq + r + l)"
    by (metis add.commute iteration_subdenest mult.assoc mult_isol)
  finally show ?thesis .
qed
    

text ‹Finally, we prove Cohen's~cite"Cohen00" variation of the atomicity refinement theorem.›

lemma atom_ref_cohen: 
  assumes "rpy  yr" "ypl  ly" "rpl  lr"
          "pr!p = 0" "pl!p = 0" "!plp = 0"
          "y0 = 0" "r0 = 0" "test p"
  shows "(y + r + l) = (pl)(y + !pl + r!p)(rp)"
proof -    
  have "(y + r)pl  ly + lr"
    by (metis distrib_right' join.sup_mono assms(2) assms(3))
  hence stepA: "(y + r)pl  (pl + !pl)(y + r)"
    by (metis assms(9) distrib_left distrib_right' mult_1_left mult_isol order_trans star_ext test_add_comp)
  have subStepB: "(!pl + y + pr + !pr) = (!pl + y + rp + r!p)"
    by (metis add_assoc' annil assms(8) assms(9) distrib_left distrib_right' star_slide star_subid test_add_comp join.bot_least)
  have "rp(y + r!p + !pl)  y(rp + r!p)"
    by (metis assms(1,4,9) distrib_left add_0_left add.commute annil mult.assoc test_comp_mult2 distrib_left mult_oner test_add_comp)
  also have "...  (y + r!p + !pl)(rp + (y + r!p + !pl))"
    by (meson local.eq_refl local.join.sup_ge1 local.join.sup_ge2 local.join.sup_mono local.mult_isol_var local.order_trans)
  finally have "rp(y + r!p + !pl)  (y + r!p + !pl)(y + r!p + !pl + rp)" 
    by (metis add.commute)
  hence stepB: "(!pl + y + pr + !pr) = (y + !pl + r!p)(rp)" 
    by (metis subStepB iteration_sep3[of "rp" "y + r!p + !pl"]  add_assoc' add.commute)
  have "(y + r + l) = (pl + !pl + y + r)"
    by (metis add_comm add.left_commute assms(9) distrib_right' mult_onel test_add_comp)
  also have "... = (pl)(!pl + y + r)" using stepA
    by (metis assms(6-8) annil add.assoc add_0_left distrib_right' add.commute mult.assoc iteration_sep4[of "y+r" "!pl" "pl"])
  also have "... = (pl)(!pl + y + pr + !pr)"
    by (metis add.commute assms(9) combine_common_factor mult_1_left test_add_comp)
  finally show ?thesis using stepB
    by (metis mult.assoc)
qed
end

end