Theory DRA

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

section ‹Demonic Refinement Algebras›

theory DRA
  imports Kleene_Algebra 
begin

text ‹
  A demonic refinement algebra *DRA)~cite"vonwright04refinement" is a Kleene algebra without right annihilation plus 
  an operation for possibly infinite iteration.
›
class dra = kleene_algebra_zerol +
  fixes strong_iteration :: "'a  'a" (‹_ [101] 100)
  assumes iteration_unfoldl [simp] : "1 + x  x = x"
  and coinduction: "y  z + x  y  y  x  z"
  and isolation [simp]: "x + x  0 = x"
begin

text ‹$\top$ is an abort statement, defined as an infinite skip. It is the maximal element of any DRA.›

abbreviation top_elem :: "'a" () where "  1"

text ‹Simple/basic lemmas about the iteration operator›

lemma iteration_refl: "1  x"
  using local.iteration_unfoldl local.order_prop by blast

lemma iteration_1l: "x  x  x"
  by (metis local.iteration_unfoldl local.join.sup.cobounded2)

lemma top_ref: "x  "
proof -
  have "x  1 + 1  x"
    by simp
  thus ?thesis
    using local.coinduction by fastforce
qed

lemma it_ext: "x  x"
proof -
  have "x  x  x"
    using iteration_refl local.mult_isol by fastforce
  thus ?thesis
    by (metis (full_types) local.isolation local.join.sup.coboundedI1 local.star_ext)
qed

lemma it_idem [simp]: "(x) = x"
(*nitpick [expect=genuine]*)
oops

lemma top_mult_annil [simp]: "  x = "
  by (simp add: local.coinduction local.order.antisym top_ref)

lemma top_add_annil [simp]: " + x = "
  by (simp add: local.join.sup.absorb1 top_ref)

lemma top_elim: "x  y  x  "
  by (simp add: local.mult_isol top_ref)

lemma iteration_unfoldl_distl [simp]: " y + y  x  x = y  x"
  by (metis distrib_left mult.assoc mult_oner iteration_unfoldl)

lemma iteration_unfoldl_distr [simp]: " y + x  x  y = x  y"
  by (metis distrib_right' mult_1_left iteration_unfoldl)

lemma iteration_unfoldl' [simp]: "z  y + z  x  x  y = z  x  y"
  by (metis iteration_unfoldl_distl local.distrib_right)

lemma iteration_idem [simp]: "x  x = x"
proof (rule order.antisym)
  have "x  x  1 + x  x  x"
    by (metis add_assoc iteration_unfoldl_distr local.eq_refl local.iteration_unfoldl local.subdistl_eq mult_assoc)
  thus "x  x  x"
    using local.coinduction mult_assoc by fastforce
  show "x   x  x"
    using local.coinduction by auto
qed

lemma iteration_induct: "x  x  x  x"
proof -
  have "x + x  (x  x) = x  x"
    by (metis (no_types) local.distrib_left local.iteration_unfoldl local.mult_oner)
  thus ?thesis
    by (simp add: local.coinduction)
qed

lemma iteration_ref_star: "x  x"
  by (simp add: local.star_inductl_one)

lemma iteration_subdist: "x  (x + y)"
  by (metis add_assoc' distrib_right' mult_oner coinduction join.sup_ge1 iteration_unfoldl)

lemma iteration_iso: "x  y  x  y"
  using iteration_subdist local.order_prop by auto
 
lemma iteration_unfoldr [simp]: "1 + x  x = x"
  by (metis add_0_left annil eq_refl isolation mult.assoc iteration_idem iteration_unfoldl iteration_unfoldl_distr star_denest star_one star_prod_unfold star_slide tc)

lemma iteration_unfoldr_distl [simp]: " y + y  x  x = y  x"
  by (metis distrib_left mult.assoc mult_oner iteration_unfoldr)

lemma iteration_unfoldr_distr [simp]: " y + x  x  y = x  y"
  by (metis iteration_unfoldl_distr iteration_unfoldr_distl)

lemma iteration_unfold_eq: "x  x = x  x"
  by (metis iteration_unfoldl_distr iteration_unfoldr_distl)
  
lemma iteration_unfoldr' [simp]: "z  y + z  x  x  y = z  x  y"
  by (metis distrib_left mult.assoc iteration_unfoldr_distr)

lemma iteration_double [simp]: "(x) = "
  by (simp add: iteration_iso iteration_refl order.eq_iff top_ref)

lemma star_iteration [simp]: "(x) = "
  by (simp add: iteration_iso order.eq_iff top_ref)

lemma iteration_star [simp]: "(x) = x"
  by (metis (no_types) iteration_idem iteration_refl local.star_inductr_var_eq2 local.sup_id_star1)

lemma iteration_star2 [simp]: "x  x = x"
proof -
  have f1: "(x)  x = x"
    by (metis (no_types) it_ext iteration_induct iteration_star local.bubble_sort local.join.sup.absorb1)
  have "x = x  x"
    by simp
  hence "x  x = x  (x)  (x  (x))"
    using f1 by (metis (no_types) iteration_star local.star_denest_var_4 mult_assoc)
  thus ?thesis
    using f1 by (metis (no_types) iteration_star local.star_denest_var_4 local.star_denest_var_8)
qed

lemma iteration_zero [simp]: "0 = 1"
  by (metis add_zeror annil iteration_unfoldl)

lemma iteration_annil [simp]: "(x  0) = 1 + x  0"
  by (metis annil iteration_unfoldl mult.assoc)

lemma iteration_subdenest: "x  y  (x + y)"
  by (metis add_commute iteration_idem iteration_subdist local.mult_isol_var)
  
lemma sup_id_top: "1  y  y   = "
  using order.eq_iff local.mult_isol_var top_ref by fastforce

lemma iteration_top [simp]: "x   = "
  by (simp add: iteration_refl sup_id_top)

text ‹Next, we prove some simulation laws for data refinement.›

lemma iteration_sim: "z  y  x  z  z  y  x  z"
proof -
  assume assms: "z  y  x  z"
  have "z  y = z + z  y  y"
    by simp
  also have "...  z + x  z  y"
    by (metis assms add.commute add_iso mult_isor)
  finally show "z  y  x  z"
    by (simp add: local.coinduction mult_assoc)
qed

text ‹Nitpick gives a counterexample to the dual simulation law.›

lemma "y  z  z  x  y  z  z  x"
(*nitpick [expect=genuine]*)
oops
  
text ‹Next, we prove some sliding laws.›

lemma iteration_slide_var: "x  (y  x)  (x  y)  x"
  by (simp add: iteration_sim mult_assoc)

lemma iteration_prod_unfold [simp]: "1 + y  (x  y)  x = (y  x)"
proof (rule order.antisym)
  have "1 + y  (x  y)  x  1 + (y  x)  y  x"
    using iteration_slide_var local.join.sup_mono local.mult_isor by blast
  thus "1 + y  (x  y)  x   (y  x)"
    by (simp add: mult_assoc)
  have "(y  x) = 1 + y  x  (y  x)"
    by simp
  thus "(y  x)  1 + y  (x  y)  x"
    by (metis iteration_sim local.eq_refl local.join.sup.mono local.mult_isol mult_assoc)
qed

lemma iteration_slide: "x  (y  x) = (x  y)  x"
  by (metis iteration_prod_unfold iteration_unfoldl_distr distrib_left mult_1_right mult.assoc)

lemma star_iteration_slide [simp]: " y  (x  y) = (x  y)"
  by (metis iteration_star2 local.conway.dagger_unfoldl_distr local.join.sup.orderE local.mult_isor local.star_invol local.star_subdist local.star_trans_eq)

text ‹The following laws are called denesting laws.›

lemma iteration_sub_denest: "(x + y)  x  (y  x)"
proof -
  have "(x + y) = x  (x + y) + y  (x + y) + 1"
    by (metis add.commute distrib_right' iteration_unfoldl)
  hence "(x + y)  x  (y  (x + y) + 1)"
    by (metis add_assoc' join.sup_least join.sup_ge1 join.sup_ge2 coinduction)
  moreover hence "x  (y  (x + y) + 1)  x  (y  x)"
    by (metis add_iso mult.assoc mult_isol add.commute coinduction mult_oner mult_isol)
  ultimately show ?thesis
    using local.order_trans by blast
qed

lemma iteration_denest: "(x + y) = x  (y  x)"
proof -
  have "x  (y  x)  x  x  (y  x) + y  x  (y  x) + 1"
    by (metis add.commute iteration_unfoldl_distr add_assoc' add.commute iteration_unfoldl order_refl)
  thus ?thesis
    by (metis add.commute iteration_sub_denest order.antisym coinduction distrib_right' iteration_sub_denest mult.assoc mult_oner order.antisym)
qed
(*
end

sublocale dra ⊆ conway_zerol strong_iteration 
  apply (unfold_locales)
  apply (simp add: iteration_denest iteration_slide)
  apply simp
  by (simp add: iteration_sim)


context dra
begin
*)
lemma iteration_denest2 [simp]: "y  x  (x + y) + y = (x + y)"
proof -
  have "(x + y) = y  x  (y  x)  y + y"
    by (metis add.commute iteration_denest iteration_slide iteration_unfoldl_distr)
  also have "... = y  x  (y  x)  y + y  0 + y"
    by (metis isolation mult.assoc distrib_right' annil mult.assoc)
  also have "... = y  x  (y  x)  y + y"
    by (metis add.assoc distrib_left mult_1_right add_0_left mult_1_right)
  finally show ?thesis
    by (metis add.commute iteration_denest iteration_slide mult.assoc)
qed

lemma iteration_denest3: "(y  x)  y = (x + y)"
proof (rule order.antisym)
  have  "(y  x)  y  (y  x)  y"
    by (simp add: iteration_iso iteration_ref_star local.mult_isor)
  thus  "(y  x)  y  (x + y)"
    by (metis iteration_denest iteration_slide local.join.sup_commute)
  have "(x + y) = y + y  x  (x + y)"
    by (metis iteration_denest2 local.join.sup_commute)
  thus "(x + y)  (y  x)  y"
    by (simp add: local.coinduction) 
qed

text ‹Now we prove separation laws for reasoning about distributed systems in the context of action systems.›

lemma iteration_sep: "y  x  x  y  (x + y) = x  y"
proof -
  assume "y  x  x  y"
  hence "y  x  x(x + y)"
    by (metis star_sim1 add.commute mult_isol order_trans star_subdist)
  hence "y  x  (x + y) + y  x  (x + y) + y"
    by (metis mult_isor mult.assoc iteration_star2 join.sup.mono eq_refl)
  thus ?thesis
    by (metis iteration_denest2 add.commute coinduction add.commute less_eq_def iteration_subdenest)
qed

lemma iteration_sim2: "y  x  x  y  y  x  x  y"
  by (metis add.commute iteration_sep iteration_subdenest)

lemma iteration_sep2: "y  x  x  y  (x + y) = x  y"
proof - 
  assume "y  x  x  y"
  hence "y  (y  x)  y  x  y  y"
    by (metis mult.assoc mult_isor iteration_sim star_denest_var_2 star_sim1 star_slide_var star_trans_eq tc_eq)
  moreover have "x  y  y  x  y"
    by (metis eq_refl mult.assoc iteration_star2)
  moreover have "(y  x)  y  y  (y  x)  y"
    by (metis mult_isor mult_onel star_ref)
  ultimately show ?thesis
    by (metis order.antisym iteration_denest3 iteration_subdenest order_trans)
qed

lemma iteration_sep3: "y  x  x  (x + y)  (x + y) = x  y"
proof -
  assume "y  x  x  (x + y)"
  hence "y  x  x  (x + y)"
    by (metis star_sim1)
  hence "y  x  (x + y) + y  x  (x + y)  (x + y) + y"
    by (metis add_iso mult_isor)
  hence "(x + y)  x  y"
    by (metis mult.assoc iteration_denest2 iteration_star2 add.commute coinduction)
  thus ?thesis
    by (metis add.commute less_eq_def iteration_subdenest)
qed

lemma iteration_sep4: "y  0 = 0  z  x = 0  y  x  (x + z)  y  (x + y + z) = x  (y + z)"
proof -
  assume assms: "y  0 = 0" "z  x = 0" "y  x  (x + z)  y"
  have "y  y  z  y  z  y"
    by (metis mult_isor star_1l mult_oner order_trans star_plus_one subdistl)
  have "y  z  x  x  y  z"
    by (metis join.bot_least assms(1) assms(2) independence1 mult.assoc)
  have "y  (x + y  z)  (x + z)  y + y  y  z"
    by (metis assms(3) distrib_left mult.assoc add_iso)
  also have "...  (x + y  z)  y + y  y  z" 
    by (metis star_ref join.sup.mono eq_refl mult_1_left mult_isor)
  also have "...  (x + y  z)  y + y  z   y" using y  y  z  y  z  y
    by (metis add.commute add_iso)
  finally have "y  (x + y  z)  (x + y  z)  y"
    by (metis add.commute add_idem' add.left_commute distrib_right)
  moreover have "(x + y + z)  (x + y + y  z)"
    by (metis star_ref join.sup.mono eq_refl mult_1_left mult_isor iteration_iso)  
  moreover have "... = (x + y  z)  y"
    by (metis add_commute calculation(1) iteration_sep2 local.add_left_comm)
  moreover have "... = x  (y  z)  y" using y  z  x  x  y  z
    by (metis iteration_sep mult.assoc)
  ultimately have "(x + y + z)  x  (y + z)"
    by (metis add.commute mult.assoc iteration_denest3)
  thus ?thesis
    by (metis add.commute add.left_commute less_eq_def iteration_subdenest)
qed

text ‹Finally, we prove some blocking laws.›

text ‹Nitpick refutes the next lemma.›

lemma "x  y = 0  x  y = y"
(*nitpick*)
oops

lemma iteration_idep: "x  y = 0  x  y = x"
  by (metis add_zeror annil iteration_unfoldl_distl)

text ‹Nitpick refutes the next lemma.›

lemma "y  w  x  y + z  y  w  x  z"
(*nitpick [expect=genuine]*)
oops

text ‹At the end of this file, we consider a data refinement example from von Wright~cite"Wright02".›

lemma data_refinement:
  assumes "s'  s  z" and "z  e'  e" and "z  a'  a  z" and "z  b  z" and "b = b"
  shows "s'  (a' + b)  e'  s  a  e"
proof -
  have "z  b  z"
    by (metis assms(4) star_inductr_var)
  have "(z  a')  b  (a  z)  b"
    by (metis assms(3) mult.assoc mult_isor)
  hence "z  (a'  b)   a  z" using z  b  z
    by (metis mult.assoc mult_isol order_trans iteration_sim mult.assoc)
  have "s'  (a' + b)  e'  s'  b  (a'  b)  e'"
    by (metis add.commute assms(5) eq_refl iteration_denest mult.assoc)
  also have "...  s  z  b  (a'  b)  e'"
    by (metis assms(1) mult_isor)
  also have "...  s  z  (a'  b)  e'" using z  b  z
    by (metis mult.assoc mult_isol mult_isor)
  also have "...  s  a  z  e'" using z  (a'  b)   a  z
    by (metis mult.assoc mult_isol mult_isor)
  finally show ?thesis
    by (metis assms(2) mult.assoc mult_isol mult.assoc mult_isol order_trans)
qed

end

end