Theory HS_VC_KA_rel

(*  Title:       Verification components with relational MKA 
    Author:      Jonathan Julián Huerta y Munive, 2020
    Maintainer:  Jonathan Julián Huerta y Munive <jonjulian23@gmail.com>
*)

subsection ‹ Relational model › (* by Victor Gomes, Georg Struth *)

text ‹ In this subsection, we follow Gomes and Struth~cite‹"afp:vericomp"› and show that relations 
form Kleene algebras.  ›

theory HS_VC_KA_rel
  imports Kleene_Algebra.Kleene_Algebra

begin

context dioid_one_zero
begin

lemma power_inductl: "z + x ⋅ y ≤ y ⟹ (x ^ n) ⋅ z ≤ y"
  by(induct n, auto, metis mult.assoc mult_isol order_trans)

lemma power_inductr: "z + y ⋅ x ≤ y ⟹ z ⋅ (x ^ n) ≤ y"
proof (induct n)
  case 0 show ?case
    using "0.prems" by auto
  case Suc
  {fix n
    assume "z + y ⋅ x ≤ y ⟹ z ⋅ x ^ n ≤ y"
      and "z + y ⋅ x ≤ y"
    hence "z ⋅ x ^ n ≤ y"
      by auto
    also have "z ⋅ x ^ Suc n = z ⋅ x ⋅ x ^ n"
      by (metis mult.assoc power_Suc)
    moreover have "... = (z ⋅ x ^ n) ⋅ x"
      by (metis mult.assoc power_commutes)
    moreover have "... ≤ y ⋅ x"
      by (metis calculation(1) mult_isor)
    moreover have "... ≤ y"
      using ‹z + y ⋅ x ≤ y› by auto
    ultimately have "z ⋅ x ^ Suc n ≤ y" by auto}
  thus ?case
    by (metis Suc)
qed

end

interpretation rel_dioid: dioid_one_zero "(∪)" "(O)" Id "{}" "(⊆)" "(⊂)"
  by (unfold_locales, auto)

lemma power_is_relpow: "rel_dioid.power X n = X ^^ n"
proof (induct n)
  case 0 show ?case
    by (metis rel_dioid.power_0 relpow.simps(1))
  case Suc thus ?case
    by (metis rel_dioid.power_Suc2 relpow.simps(2))
qed

lemma rel_star_def: "X^* = (⋃n. rel_dioid.power X n)"
  by (simp add: power_is_relpow rtrancl_is_UN_relpow)

lemma rel_star_contl: "X O Y^* = (⋃n. X O rel_dioid.power Y n)"
  by (metis rel_star_def relcomp_UNION_distrib)

lemma rel_star_contr: "X^* O Y = (⋃n. (rel_dioid.power X n) O Y)"
  by (metis rel_star_def relcomp_UNION_distrib2)

interpretation rel_ka: kleene_algebra "(∪)" "(O)" Id "{}" "(⊆)" "(⊂)" rtrancl
proof
  fix x y z :: "'a rel"
  show "Id ∪ x O x* ⊆ x*"
    by (metis order_refl r_comp_rtrancl_eq rtrancl_unfold)
next
  fix x y z :: "'a rel"
  assume "z ∪ x O y ⊆ y"
  thus "x* O z ⊆ y"
    by (simp only: rel_star_contr, metis (lifting) SUP_le_iff rel_dioid.power_inductl)
next
  fix x y z :: "'a rel"
  assume "z ∪ y O x ⊆ y"
  thus "z O x* ⊆ y"
    by (simp only: rel_star_contl, metis (lifting) SUP_le_iff rel_dioid.power_inductr)
qed

end