Theory Distributivity

section ‹Distributivity and Factorisability›

text ‹This section corresponds to Section 2.4 and Figure 4 of the paper~cite"UnboundedSL".›

theory Distributivity
  imports UnboundedLogic
begin

context logic
begin

subsection DotPos

lemma DotPos:
  "A, Δ  B  (Mult π A, Δ  Mult π B)" (is "?A  ?B")
proof
  show "?A  ?B"
    by (metis (no_types, lifting) entails_def sat.simps(1))
  show "?B  ?A"
    using can_divide entails_def sat.simps(1)
    by metis
qed

text ‹Only one direction holds with a wildcard›

lemma WildPos:
  "A, Δ  B  (Wildcard A, Δ  Wildcard B)"
  by (metis (no_types, lifting) entails_def sat.simps(12))

subsection DotDot

lemma dot_mult1:
  "Mult p (Mult q A), Δ  Mult (smult p q) A"
proof (rule entailsI)
  fix σ s
  assume "σ, s, Δ  Mult p (Mult q A)"
  then show "σ, s, Δ  Mult (smult p q) A"
    using double_mult by auto
qed

lemma dot_mult2:
  "Mult (smult p q) A, Δ  Mult p (Mult q A)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult (smult p q) A"
  then obtain a where "a, s, Δ  A" "σ = (smult p q)  a"
    by auto
  then have "q  a, s, Δ  Mult q A" by auto
  then show "σ, s, Δ  Mult p (Mult q A)"  
    by (metis σ = smult p q  a double_mult sat.simps(1))
qed

lemma DotDot:
  "Mult p (Mult q A), Δ  Mult (smult p q) A"
  by (simp add: dot_mult1 dot_mult2 equivalent_def)

lemma can_factorize:
  "r. q = smult r p"
  by (metis sinv_inverse smult_asso smult_comm sone_neutral)

lemma WildDot:
  "Wildcard (Mult p A), Δ  Wildcard A"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Wildcard (Mult p A)  σ, s, Δ  Wildcard A"
    using double_mult by fastforce
  fix σ s
  assume asm0: "σ, s, Δ  Wildcard A"
  then obtain q a where "σ = q  a" "a, s, Δ  A"
    using sat.simps(12) by blast
  then obtain r where "q = smult r p"
    using can_factorize by blast
  then have "σ = r  (p  a)"
    by (simp add: σ = q  a double_mult)
  then show "σ, s, Δ  Wildcard (Mult p A)"
    using a, s, Δ  A sat.simps(1) sat.simps(12) by blast
qed

lemma DotWild:
  "Mult p (Wildcard A), Δ  Wildcard A"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Mult p (Wildcard A)  σ, s, Δ  Wildcard A"
    using double_mult by fastforce
  fix σ s
  assume asm0: "σ, s, Δ  Wildcard A"
  then obtain q a where "σ = q  a" "a, s, Δ  A"
    by force
  then obtain r where "q = smult p r"
    using can_factorize smult_comm by presburger
  then have "σ = p  (r  a)"
    by (simp add: σ = q  a double_mult)
  then show "σ, s, Δ  Mult p (Wildcard A)"
    using a, s, Δ  A by auto
qed

lemma WildWild:
  "Wildcard (Wildcard A), Δ  Wildcard A"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Wildcard (Wildcard A)  σ, s, Δ  Wildcard A"
    using double_mult by fastforce
  show "σ s. σ, s, Δ  Wildcard A  σ, s, Δ  Wildcard (Wildcard A)"
    by (metis one_neutral sat.simps(12))
qed




subsection DotStar

lemma dot_star1:
  "Mult p (Star A B), Δ  Star (Mult p A) (Mult p B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Star A B)"
  then obtain a b x where "σ = p  x" "Some x = a  b" "a, s, Δ  A" "b, s, Δ  B"
    by auto
  then show "σ, s, Δ  Star (Mult p A) (Mult p B)"
    using plus_mult by auto
qed


lemma dot_star2:
  "Star (Mult p A) (Mult p B), Δ  Mult p (Star A B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Star (Mult p A) (Mult p B)"
  then obtain a b where "Some σ = (p  a)  (p  b)" "a, s, Δ  A" "b, s, Δ  B"
    by auto
  then obtain x where "Some x = a  b"
    by (metis plus_mult unique_inv)
  then have "σ = p  x"
    by (metis Some σ = p  a  p  b option.sel plus_mult)
  then show "σ, s, Δ  Mult p (Star A B)"
    using Some x = a  b a, s, Δ  A b, s, Δ  B by auto
qed

lemma DotStar:
  "Mult p (Star A B), Δ  Star (Mult p A) (Mult p B)"
  by (simp add: dot_star1 dot_star2 equivalent_def)

lemma WildStar1:
  "Wildcard (Star A B), Δ  Star (Wildcard A) (Wildcard B)"
proof (rule entailsI)
  fix σ s assume asm0: "σ, s, Δ  Wildcard (Star A B)"
  then obtain p ab a b where "σ = p  ab" "Some ab = a  b" "a, s, Δ  A" "b, s, Δ  B"
    by auto
  then have "Some σ = (p  a)  (p  b)"
    using plus_mult by blast
  then show "σ, s, Δ  Star (Wildcard A) (Wildcard B)"
    using a, s, Δ  A b, s, Δ  B by auto
qed


subsection DotWand


lemma dot_wand1:
  "Mult p (Wand A B), Δ  Wand (Mult p A) (Mult p B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Wand A B)"
  then obtain x where "σ = p  x" "x, s, Δ  Wand A B"
    by auto
  show "σ, s, Δ  Wand (Mult p A) (Mult p B)"
  proof (rule sat_wand)
    fix a σ'
    assume "a, s, Δ  Mult p A  Some σ' = σ  a"
    then obtain aa where "aa, s, Δ  A" "a = p  aa"
      by auto
    then obtain b where "Some b = x  aa"
      by (metis σ = p  x a, s, Δ  Mult p A  Some σ' = σ  a compatible_def compatible_iff option.exhaust_sel)
    then have "b, s, Δ  B"
      using aa, s, Δ  A x, s, Δ  Wand A B by auto
    then show "σ', s, Δ  Mult p B"
      by (metis Some b = x  aa σ = p  x a = p  aa a, s, Δ  Mult p A  Some σ' = σ  a can_divide option.inject plus_mult sat_mult)
  qed
qed

lemma dot_wand2:
  "Wand (Mult p A) (Mult p B), Δ  Mult p (Wand A B)"
proof (rule entailsI)
  fix σ s Δ
  assume asm: "σ, s, Δ  Wand (Mult p A) (Mult p B)"
  show "σ, s, Δ  Mult p (Wand A B)"
  proof (rule sat_mult)
    fix a assume "σ = p  a"
    show "a, s, Δ  Wand A B"
    proof (rule sat_wand)
      fix aa σ'
      assume "aa, s, Δ  A  Some σ' = a  aa"
      then have "p  aa, s, Δ  Mult p A" by auto
      then have "Some (p  σ') = σ  p  aa"
        by (simp add: σ = p  a aa, s, Δ  A  Some σ' = a  aa plus_mult)
      then have "p  σ', s, Δ  Mult p B"
        using p  aa, s, Δ  Mult p A asm by force
      then show "σ', s, Δ  B"
        by (metis can_divide sat.simps(1))
    qed
  qed
qed

lemma DotWand:
  "Mult p (Wand A B), Δ  Wand (Mult p A) (Mult p B)"
  by (simp add: dot_wand1 dot_wand2 equivalent_def)


(* Again: Need intuitionism
lemma WildWand:
  "Wildcard (Wand A B), Δ ⊢ Wand (Wildcard A) (Wildcard B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ ⊨ Wildcard (Wand A B)"
  then obtain x p where "σ = p ⊙ x" "x, s, Δ ⊨ Wand A B"
    by auto
  show "σ, s, Δ ⊨ Wand (Wildcard A) (Wildcard B)"
  proof (rule sat_wand)
    fix a σ'
    assume "a, s, Δ ⊨ Wildcard A ∧ Some σ' = σ ⊕ a"
    then obtain aa q where "aa, s, Δ ⊨ A" "a = q ⊙ aa"
      by auto
    then obtain b where "Some b = x ⊕ aa"
      by (metis ‹σ = p ⊙ x› ‹a, s, Δ ⊨ Wildcard A ∧ Some σ' = σ ⊕ a› compatible_def compatible_multiples not_None_eq)



    then have "b, s, Δ ⊨ B"
      using ‹aa, s, Δ ⊨ A› ‹x, s, Δ ⊨ Wand A B› by auto


    then show "σ', s, Δ ⊨ Wildcard B"
      
      by (metis ‹Some b = x ⊕ aa› ‹σ = p ⊙ x› ‹a = p ⊙ aa› ‹a, s, Δ ⊨ Mult p A ∧ Some σ' = σ ⊕ a› can_divide option.inject plus_mult sat_mult)
  qed
qed

*)



subsection DotOr

lemma dot_or1:
  "Mult p (Or A B), Δ  Or (Mult p A) (Mult p B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Or A B)"
  then obtain x where "σ = p  x" "x, s, Δ  A  x, s, Δ  B"
    by auto
  then show "σ, s, Δ  Or (Mult p A) (Mult p B)"
  proof (cases "x, s, Δ  A")
    case True
    then show ?thesis 
      using σ = p  x by auto
  next
    case False
    then show ?thesis
      using σ = p  x x, s, Δ  A  x, s, Δ  B by auto
  qed
qed

lemma dot_or2:
  "Or (Mult p A) (Mult p B), Δ  Mult p (Or A B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Or (Mult p A) (Mult p B)"
  then show "σ, s, Δ  Mult p (Or A B)"
  proof (cases "σ, s, Δ  Mult p A")
    case True
    then show ?thesis by auto
  next
    case False
    then show ?thesis
      using σ, s, Δ  Or (Mult p A) (Mult p B) by auto
  qed
qed

lemma DotOr:
  "Mult p (Or A B), Δ  Or (Mult p A) (Mult p B)"
  by (simp add: dot_or1 dot_or2 equivalent_def)

lemma WildOr:
  "Wildcard (Or A B), Δ  Or (Wildcard A) (Wildcard B)"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Wildcard (Or A B)  σ, s, Δ  Or (Wildcard A) (Wildcard B)"
    by auto
  show "σ s. σ, s, Δ  Or (Wildcard A) (Wildcard B)  σ, s, Δ  Wildcard (Or A B)"
    by auto
qed


subsection DotAnd

lemma dot_and1:
  "Mult p (And A B), Δ  And (Mult p A) (Mult p B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (And A B)"
  then obtain x where "σ = p  x" "x, s, Δ  A" "x, s, Δ  B"
    by auto
  then show "σ, s, Δ  And (Mult p A) (Mult p B)"
    by auto
qed

lemma dot_and2:
  "And (Mult p A) (Mult p B), Δ  Mult p (And A B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  And (Mult p A) (Mult p B)"
  then show "σ, s, Δ  Mult p (And A B)"
    using logic.can_divide logic_axioms by fastforce
qed

lemma DotAnd:
  "And (Mult p A) (Mult p B), Δ  Mult p (And A B)"
  by (simp add: dot_and1 dot_and2 equivalent_def)

lemma WildAnd:
  "Wildcard (And A B), Δ  And (Wildcard A) (Wildcard B)"
  using entails_def by fastforce



subsection DotImp


lemma dot_imp1:
  "Imp (Mult p A) (Mult p B), Δ  Mult p (Imp A B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Imp (Mult p A) (Mult p B)"
  then show "σ, s, Δ  Mult p (Imp A B)"
    using sat_mult by force
qed

lemma dot_imp2:
  "Mult p (Imp A B), Δ  Imp (Mult p A) (Mult p B)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Imp A B)"
  then show "σ, s, Δ  Imp (Mult p A) (Mult p B)"
    using can_divide by auto
qed

lemma DotImp:
  "Mult p (Imp A B), Δ  Imp (Mult p A) (Mult p B)"
  by (simp add: dot_imp1 dot_imp2 equivalent_def)

subsection DotPure


lemma pure_mult1:
  assumes "pure A"
  shows "Mult p A, Δ  A"
  using assms entails_def logic.pure_def logic_axioms by fastforce

lemma pure_mult2:
  assumes "pure A"
  shows "A, Δ  Mult p A"
    using assms entailsI pure_def sat_mult
    by metis

lemma DotPure: 
  assumes "pure A"
  shows "Mult p A, Δ  A"
  by (simp add: assms equivalent_def pure_mult1 pure_mult2)

lemma WildPure: 
  assumes "pure A"
  shows "Wildcard A, Δ  A"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Wildcard A  σ, s, Δ  A"
    using assms pure_def sat.simps(12) by blast
  show "σ s. σ, s, Δ  A  σ, s, Δ  Wildcard A"
    by (metis one_neutral sat.simps(12))
qed


subsection DotFull

lemma mult_one_same1:
  "Mult one A, Δ  A"
  by (simp add: entails_def one_neutral)


lemma mult_one_same2:
  "A, Δ  Mult one A"
  by (simp add: entailsI one_neutral)

lemma DotFull:
  "Mult one A, Δ  A"
  using equivalent_def mult_one_same1 mult_one_same2 by blast




subsection DotExists


lemma dot_exists1:
  "Mult p (Exists x A), Δ  Exists x (Mult p A)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Exists x A)"
  then show "σ, s, Δ  Exists x (Mult p A)"
    by auto
qed

lemma dot_exists2:
  "Exists x (Mult p A), Δ  Mult p (Exists x A)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Exists x (Mult p A)"
  then show "σ, s, Δ  Mult p (Exists x A)" by auto
qed

lemma DotExists:
  "Mult p (Exists x A), Δ  Exists x (Mult p A)"
  by (simp add: dot_exists1 dot_exists2 equivalent_def)


lemma WildExists:
  "Wildcard (Exists x A), Δ  Exists x (Wildcard A)"
proof (rule equivalentI)
  show "σ s. σ, s, Δ  Wildcard (Exists x A)  σ, s, Δ  Exists x (Wildcard A)"
    by auto
  show "σ s. σ, s, Δ  Exists x (Wildcard A)  σ, s, Δ  Wildcard (Exists x A)"
    by auto
qed

subsection DotForall

lemma dot_forall1:
  "Mult p (Forall x A), Δ  Forall x (Mult p A)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Mult p (Forall x A)"
  then show "σ, s, Δ  Forall x (Mult p A)"
    by auto
qed

lemma dot_forall2:
  "Forall x (Mult p A), Δ  Mult p (Forall x A)"
proof (rule entailsI)
  fix σ s Δ
  assume "σ, s, Δ  Forall x (Mult p A)"
  obtain a where "σ = p  a"
    using sat.simps(1) sat_mult by blast
  have "a, s, Δ  Forall x A"
  proof (rule sat_forall)
    fix v show "a, s(x := v), Δ  A"
      using σ = p  a σ, s, Δ  Forall x (Mult p A) can_divide by auto
  qed
  then show "σ, s, Δ  Mult p (Forall x A)"
    using σ = p  a by auto
qed

lemma DotForall:
  "Mult p (Forall x A), Δ  Forall x (Mult p A)"
  by (simp add: dot_forall1 dot_forall2 equivalent_def)

lemma WildForall:
  "Wildcard (Forall x A), Δ  Forall x (Wildcard A)"
  by (metis (no_types, lifting) entailsI sat.simps(12) sat.simps(9))

subsection Split

lemma split:
  "Mult (sadd a b) A, Δ  Star (Mult a A) (Mult b A)"
proof (rule entailsI)
  fix σ s
  assume "σ, s, Δ  Mult (sadd a b) A"
  then show "σ, s, Δ  Star (Mult a A) (Mult b A)"
    using distrib_mult by fastforce
qed

end

end