Theory General_Refinement_Algebras

(* Title:      General Refinement Algebras
   Author:     Walter Guttmann
   Maintainer: Walter Guttmann <walter.guttmann at canterbury.ac.nz>
*)

section ‹General Refinement Algebras›

theory General_Refinement_Algebras

imports Omega_Algebras

begin

class general_refinement_algebra = left_kleene_algebra + Omega +
  assumes Omega_unfold: "yΩ ≤ 1 ⊔ y * yΩ"
  assumes Omega_induct: "x ≤ z ⊔ y * x ⟶ x ≤ yΩ * z"
begin

lemma Omega_unfold_equal:
  "yΩ = 1 ⊔ y * yΩ"
  by (smt (z3) Omega_induct Omega_unfold sup_right_isotone order.antisym mult_right_isotone mult_1_right)

lemma Omega_sup_1:
  "(x ⊔ y)Ω = xΩ * (y * xΩ)Ω"
  apply (rule order.antisym)
  apply (smt Omega_induct Omega_unfold_equal sup_assoc sup_commute sup_right_isotone mult_assoc mult_right_dist_sup mult_right_isotone mult_1_right order_refl)
  by (smt (z3) Omega_induct Omega_unfold_equal sup_assoc sup_commute mult_assoc mult_left_one mult_right_dist_sup mult_1_right order_refl)

lemma Omega_left_slide:
  "(x * y)Ω * x ≤ x * (y * x)Ω"
proof -
  have "1 ⊔ y * (x * y)Ω * x ≤ 1 ⊔ y * x * (1 ⊔ (y * (x * y)Ω) * x)"
    by (smt (z3) Omega_unfold_equal sup_right_isotone mult_assoc mult_left_one mult_left_sub_dist_sup mult_right_dist_sup mult_right_isotone mult_1_right)
  thus ?thesis
    by (smt (z3) Omega_induct Omega_unfold_equal le_sup_iff mult_assoc mult_left_one mult_right_dist_sup mult_right_isotone mult_1_right)
qed

end

text ‹Theorem 50.3›

sublocale general_refinement_algebra < Omega: left_conway_semiring where circ = Omega
  apply unfold_locales
  using Omega_unfold_equal apply simp
  apply (simp add: Omega_left_slide)
  by (simp add: Omega_sup_1)

context general_refinement_algebra
begin

lemma star_below_Omega:
  "x⋆ ≤ xΩ"
  by (metis Omega_induct mult_1_right order_refl star.circ_left_unfold)

lemma star_mult_Omega:
  "xΩ = x⋆ * xΩ"
  by (metis Omega.left_plus_below_circ sup_commute sup_ge1 order.eq_iff star.circ_loop_fixpoint star_left_induct_mult_iff)

lemma Omega_one_greatest:
  "x ≤ 1Ω"
  by (metis Omega_induct sup_bot_left mult_left_one order_refl order_trans zero_right_mult_decreasing)

lemma greatest_left_zero:
  "1Ω * x = 1Ω"
  by (simp add: Omega_one_greatest Omega_induct order.antisym)

proposition circ_right_unfold: "1 ⊔ xΩ * x = xΩ" nitpick [expect=genuine,card=8] oops
proposition circ_slide: "(x * y)Ω * x = x * (y * x)Ω" nitpick [expect=genuine,card=6] oops
proposition circ_simulate: "z * x ≤ y * z ⟹ z * xΩ ≤ yΩ * z" nitpick [expect=genuine,card=6] oops
proposition circ_simulate_right: "z * x ≤ y * z ⊔ w ⟹ z * xΩ ≤ yΩ * (z ⊔ w * xΩ)" nitpick [expect=genuine,card=6] oops
proposition circ_simulate_right_1: "z * x ≤ y * z ⟹ z * xΩ ≤ yΩ * z" nitpick [expect=genuine,card=6] oops
proposition circ_simulate_right_plus: "z * x ≤ y * yΩ * z ⊔ w ⟹ z * xΩ ≤ yΩ * (z ⊔ w * xΩ)" nitpick [expect=genuine,card=6] oops
proposition circ_simulate_right_plus_1: "z * x ≤ y * yΩ * z ⟹ z * xΩ ≤ yΩ * z" nitpick [expect=genuine,card=6] oops
proposition circ_simulate_left_1: "x * z ≤ z * y ⟹ xΩ * z ≤ z * yΩ ⊔ xΩ * bot" oops (* holds in LKA, counterexample exists in GRA *)
proposition circ_simulate_left_plus_1: "x * z ≤ z * yΩ ⟹ xΩ * z ≤ z * yΩ ⊔ xΩ * bot" oops (* holds in LKA, counterexample exists in GRA *)
proposition circ_simulate_absorb: "y * x ≤ x ⟹ yΩ * x ≤ x ⊔ yΩ * bot" nitpick [expect=genuine,card=8] oops (* holds in LKA, counterexample exists in GRA *)

end

class bounded_general_refinement_algebra = general_refinement_algebra + bounded_left_kleene_algebra
begin

lemma Omega_one:
  "1Ω = top"
  by (simp add: Omega_one_greatest order.antisym)

lemma top_left_zero:
  "top * x = top"
  using Omega_one greatest_left_zero by blast

end

sublocale bounded_general_refinement_algebra < Omega: bounded_left_conway_semiring where circ = Omega ..

class left_demonic_refinement_algebra = general_refinement_algebra +
  assumes Omega_isolate: "yΩ ≤ yΩ * bot ⊔ y⋆"
begin

lemma Omega_isolate_equal:
  "yΩ = yΩ * bot ⊔ y⋆"
  using Omega_isolate order.antisym le_sup_iff star_below_Omega zero_right_mult_decreasing by auto

proposition Omega_sum_unfold_1: "(x ⊔ y)Ω = yΩ ⊔ y⋆ * x * (x ⊔ y)Ω" oops
proposition Omega_sup_3: "(x ⊔ y)Ω = (x⋆ * y)Ω * xΩ" oops

end

class bounded_left_demonic_refinement_algebra = left_demonic_refinement_algebra + bounded_left_kleene_algebra
begin

proposition Omega_mult: "(x * y)Ω = 1 ⊔ x * (y * x)Ω * y" oops
proposition Omega_sup: "(x ⊔ y)Ω = (xΩ * y)Ω * xΩ" oops
proposition Omega_simulate: "z * x ≤ y * z ⟹ z * xΩ ≤ yΩ * z" nitpick [expect=genuine,card=6] oops
proposition Omega_separate_2: "y * x ≤ x * (x ⊔ y) ⟹ (x ⊔ y)Ω = xΩ * yΩ" oops
proposition Omega_circ_simulate_right_plus: "z * x ≤ y * yΩ * z ⊔ w ⟹ z * xΩ ≤ yΩ * (z ⊔ w * xΩ)" nitpick [expect=genuine,card=6] oops
proposition Omega_circ_simulate_left_plus: "x * z ≤ z * yΩ ⊔ w ⟹ xΩ * z ≤ (z ⊔ xΩ * w) * yΩ" oops

end

sublocale bounded_left_demonic_refinement_algebra < Omega: bounded_left_conway_semiring where circ = Omega ..

class demonic_refinement_algebra = left_zero_kleene_algebra + left_demonic_refinement_algebra
begin

lemma Omega_mult:
  "(x * y)Ω = 1 ⊔ x * (y * x)Ω * y"
  by (smt (verit, del_insts) Omega.circ_left_slide Omega_induct Omega_unfold_equal order.eq_iff mult_assoc mult_left_dist_sup mult_1_right)

lemma Omega_sup:
  "(x ⊔ y)Ω = (xΩ * y)Ω * xΩ"
  by (smt (z3) Omega_sup_1 Omega_mult mult_assoc mult_left_dist_sup mult_left_one mult_right_dist_sup mult_1_right)

lemma Omega_simulate:
  "z * x ≤ y * z ⟹ z * xΩ ≤ yΩ * z"
  by (smt (z3) Omega_induct Omega_unfold_equal sup_right_isotone mult_assoc mult_left_dist_sup mult_left_isotone mult_1_right)

end

text ‹Theorem 2.4›

sublocale demonic_refinement_algebra < Omega1: itering_1 where circ = Omega
  apply unfold_locales
  apply (simp add: Omega_simulate mult_assoc)
  by (simp add: Omega_simulate)

sublocale demonic_refinement_algebra < Omega1: left_zero_conway_semiring_1 where circ = Omega ..

context demonic_refinement_algebra
begin

lemma Omega_sum_unfold_1:
  "(x ⊔ y)Ω = yΩ ⊔ y⋆ * x * (x ⊔ y)Ω"
  by (smt (z3) Omega1.circ_sup_9 Omega.circ_loop_fixpoint Omega_isolate_equal sup_assoc sup_commute mult_assoc mult_left_zero mult_right_dist_sup)

lemma Omega_sup_3:
  "(x ⊔ y)Ω = (x⋆ * y)Ω * xΩ"
  apply (rule order.antisym)
  apply (metis Omega_sum_unfold_1 Omega_induct eq_refl sup_commute)
  by (simp add: Omega.circ_isotone Omega_sup mult_left_isotone star_below_Omega)

lemma Omega_separate_2:
  "y * x ≤ x * (x ⊔ y) ⟹ (x ⊔ y)Ω = xΩ * yΩ"
  apply (rule order.antisym)
  apply (smt (verit, del_insts) Omega_induct Omega_sum_unfold_1 sup_right_isotone mult_assoc mult_left_isotone star_mult_Omega star_simulation_left)
  by (simp add: Omega.circ_sub_dist_3)

lemma Omega_circ_simulate_right_plus:
  assumes "z * x ≤ y * yΩ * z ⊔ w"
    shows "z * xΩ ≤ yΩ * (z ⊔ w * xΩ)"
proof -
  have "z * xΩ = z ⊔ z * x * xΩ"
    using Omega1.circ_back_loop_fixpoint Omega1.circ_plus_same sup_commute mult_assoc by auto
  also have "... ≤ y * yΩ * z * xΩ ⊔ z ⊔ w * xΩ"
    by (smt (z3) assms sup_assoc sup_commute sup_right_isotone le_iff_sup mult_right_dist_sup)
  finally have "z * xΩ ≤ (y * yΩ)Ω * (z ⊔ w * xΩ)"
    by (smt (z3) Omega_induct sup_assoc sup_commute mult_assoc)
  thus ?thesis
    by (simp add: Omega.left_plus_circ)
qed

lemma Omega_circ_simulate_left_plus:
  assumes "x * z ≤ z * yΩ ⊔ w"
    shows "xΩ * z ≤ (z ⊔ xΩ * w) * yΩ"
proof -
  have "x * ((z ⊔ xΩ * w) * yΩ) ≤ (z * yΩ ⊔ w ⊔ x * xΩ * w) * yΩ"
    by (smt (z3) assms mult_assoc mult_left_dist_sup sup_left_isotone mult_left_isotone)
  also have "... ≤ z * yΩ * yΩ ⊔ w * yΩ ⊔ xΩ * w * yΩ"
    by (smt (z3) Omega.left_plus_below_circ sup_right_isotone mult_left_isotone mult_right_dist_sup)
  finally have 1: "x * ((z ⊔ xΩ * w) * yΩ) ≤ (z ⊔ xΩ * w) * yΩ"
    by (metis Omega.circ_transitive_equal mult_assoc Omega.circ_reflexive sup_assoc le_iff_sup mult_left_one mult_right_dist_sup)
  have "xΩ * z  = xΩ * bot ⊔ x⋆ * z"
    by (metis Omega_isolate_equal mult_assoc mult_left_zero mult_right_dist_sup)
  also have "... ≤ xΩ * w * yΩ ⊔ x⋆ * (z ⊔ xΩ * w) * yΩ"
    by (metis Omega1.circ_back_loop_fixpoint bot_least idempotent_bot_closed le_supI2 mult_isotone mult_left_sub_dist_sup_left semiring.add_mono zero_right_mult_decreasing mult_assoc)
  also have "... ≤ (z ⊔ xΩ * w) * yΩ"
    using 1 by (metis le_supI mult_right_sub_dist_sup_right star_left_induct_mult mult_assoc)
  finally show ?thesis
    .
qed

lemma Omega_circ_simulate_right:
  assumes "z * x ≤ y * z ⊔ w"
    shows "z * xΩ ≤ yΩ * (z ⊔ w * xΩ)"
proof -
  have "y * z ⊔ w ≤ y * yΩ * z ⊔ w"
    using Omega.circ_mult_increasing mult_left_isotone sup_left_isotone by auto
  thus ?thesis
    using Omega_circ_simulate_right_plus assms order.trans by blast
qed

end

sublocale demonic_refinement_algebra < Omega: itering where circ = Omega
  apply unfold_locales
  apply (simp add: Omega_sup)
  using Omega_mult apply blast
  apply (simp add: Omega_circ_simulate_right_plus)
  using Omega_circ_simulate_left_plus by auto

class bounded_demonic_refinement_algebra = demonic_refinement_algebra + bounded_left_zero_kleene_algebra
begin

lemma Omega_one:
  "1Ω = top"
  by (simp add: Omega_one_greatest order.antisym)

lemma top_left_zero:
  "top * x = top"
  using Omega_one greatest_left_zero by auto

end

sublocale bounded_demonic_refinement_algebra < Omega: bounded_itering where circ = Omega ..

class general_refinement_algebra_omega = left_omega_algebra + Omega +
  assumes omega_left_zero: "xω ≤ xω * y"
  assumes Omega_def: "xΩ = xω ⊔ x⋆"
begin

lemma omega_left_zero_equal:
  "xω * y = xω"
  by (simp add: order.antisym omega_left_zero omega_sub_vector)

subclass left_demonic_refinement_algebra
  apply unfold_locales
  apply (metis Omega_def sup_commute eq_refl mult_1_right omega_loop_fixpoint)
  apply (metis Omega_def mult_right_dist_sup omega_induct omega_left_zero_equal)
  by (metis Omega_def mult_right_sub_dist_sup_right sup_commute sup_right_isotone omega_left_zero_equal)

end

class left_demonic_refinement_algebra_omega = bounded_left_omega_algebra + Omega +
  assumes top_left_zero: "top * x = top"
  assumes Omega_def: "xΩ = xω ⊔ x⋆"
begin

subclass general_refinement_algebra_omega
  apply unfold_locales
  apply (metis mult_assoc omega_vector order_refl top_left_zero)
  by (rule Omega_def)

end

class demonic_refinement_algebra_omega = left_demonic_refinement_algebra_omega + bounded_left_zero_omega_algebra
begin

lemma Omega_mult:
  "(x * y)Ω = 1 ⊔ x * (y * x)Ω * y"
  by (metis Omega_def comb1.circ_mult_1 omega_left_zero_equal omega_translate)

lemma Omega_sup:
  "(x ⊔ y)Ω = (xΩ * y)Ω * xΩ"
proof -
  have "(xΩ * y)Ω * xΩ = (x⋆ * y)⋆ * xω ⊔ (x⋆ * y)ω ⊔ (x⋆ * y)⋆ * xω⋆ * xΩ"
    by (smt (z3) sup_commute Omega_def mult_assoc mult_right_dist_sup mult_bot_add_omega omega_left_zero_equal star.circ_sup_1)
  thus ?thesis
    using Omega_def Omega_sup_1 comb2.circ_slide_1 omega_left_zero_equal by auto
qed

lemma Omega_simulate:
  "z * x ≤ y * z ⟹ z * xΩ ≤ yΩ * z"
  using Omega_def comb2.circ_simulate omega_left_zero_equal by auto

subclass demonic_refinement_algebra ..

end

(* hold in GRA and LKA *)
proposition circ_circ_mult: "1Ω * xΩ = xΩΩ" oops
proposition sub_mult_one_circ: "x * 1Ω ≤ 1Ω * x" oops
proposition circ_circ_mult_1: "xΩ * 1Ω = xΩΩ" oops
proposition "y * x ≤ x ⟹ y∘ * x ≤ 1∘ * x" oops

(* unknown *)
proposition circ_simulate_2: "y * xΩ ≤ xΩ * yΩ ⟷ yΩ * xΩ ≤ xΩ * yΩ" oops (* holds in LKA *)
proposition circ_simulate_3: "y * xΩ ≤ xΩ ⟹ yΩ * xΩ ≤ xΩ * yΩ" oops (* holds in LKA *)
proposition circ_separate_mult_1: "y * x ≤ x * y ⟹ (x * y)Ω ≤ xΩ * yΩ" oops
proposition "x∘ = (x * x)∘ * (x ⊔ 1)" oops
proposition "y∘ * x∘ ≤ x∘ * y∘ ⟹ (x ⊔ y)∘ = x∘ * y∘" oops
proposition "y * x ≤ (1 ⊔ x) * y∘ ⟹ (x ⊔ y)∘ = x∘ * y∘" oops

end