Theory Phi_Algebras.Algebras
theory Algebras
imports Main HOL.Rat
"Phi_Statespace.StateFun" "Phi_Document.Base" "HOL-Library.Product_Plus"
"HOL-Library.Finite_Map"
abbrevs "!!" = "!!"
begin
setup ‹Attrib.setup \<^binding>‹locale_intro› (Scan.succeed Locale.intro_add) ""›
section ‹Algebra Structures›
subsection ‹Preliminary Structures›
subsubsection ‹Homomorphism-like›
locale homo_one =
fixes φ :: " 'a::one ⇒ 'b::one "
assumes homo_one[iff]: "φ 1 = 1"
locale homo_zero =
fixes φ :: ‹ 'a::zero ⇒ 'b::zero ›
assumes homo_zero[iff]: ‹φ 0 = 0›
locale homo_mult = homo_one φ
for φ :: " 'a::{one,times} ⇒ 'b::{one,times} "
+ assumes homo_mult: "φ (x * y) = φ x * φ y"
lemma homo_mult:
‹homo_mult φ ⟷ (φ 1 = 1) ∧ (∀ x y. φ (x * y) = φ x * φ y)›
unfolding homo_mult_def homo_mult_axioms_def homo_one_def ..
locale mult_strip_011 =
fixes ψ :: " 'a::times ⇒ 'b::times "
assumes mult_strip_011: ‹a * ψ b = ψ c ⟷ (∃a'. a = ψ a' ∧ a' * b = c)›
locale homo_add =
fixes φ :: ‹ 'a::plus ⇒ 'b::plus ›
assumes homo_add: ‹φ (x + y) = φ x + φ y›
subsubsection ‹Group-like›
class mult_1 = times + one +
assumes mult_1_left [simp]: "1 * x = x"
and mult_1_right[simp]: "x * 1 = x"
subclass (in monoid_mult) mult_1
by (standard; simp)
class ab_group_mult = inverse + comm_monoid_mult +
assumes ab_left_inverse: "inverse a * a = 1"
assumes ab_diff_conv_add_uminus: "a / b = a * (inverse b)"
class semigroup_mult_left_cancel = semigroup_mult +
assumes semigroup_mult_left_cancel: ‹a * c = b * c ⟷ a = b›
class no_inverse = times + one +
assumes no_inverse[simp]: ‹a * b = 1 ⟷ a = 1 ∧ b = 1›
class no_negative = plus + zero +
assumes no_negative[simp]: ‹a + b = 0 ⟷ a = 0 ∧ b = 0›
instantiation nat :: no_negative begin
instance by standard simp
end
instantiation nat :: no_inverse begin
instance by standard simp
end
thm add_nonneg_nonneg
class add_order_0 = ord + zero + plus +
assumes add_nonneg_nonneg: ‹0 ≤ a ⟹ 0 ≤ b ⟹ 0 ≤ a + b›
and add_pos_pos: ‹0 < a ⟹ 0 < b ⟹ 0 < a + b›
subclass (in ordered_comm_monoid_add) add_order_0
by (standard; simp add: add_nonneg_nonneg add_pos_pos)
subsection ‹Separation Algebra›
subsubsection ‹Separation Disjunction›
class sep_disj =
fixes sep_disj :: "'a => 'a => bool" (infix "##" 60)
class total_sep_disj = sep_disj +
assumes total_sep_disj[simp]: ‹x ## y›
class comm_sep_disj = sep_disj +
assumes sep_disj_commuteI: "x ## y ⟹ y ## x"
begin
lemma sep_disj_commute: "x ## y ⟷ y ## x"
by (blast intro: sep_disj_commuteI)
end
subsubsection ‹Separation Magma›
class sep_magma = sep_disj + times
begin
definition join_sub (infix "≼⇩S⇩L" 50)
where ‹join_sub y z ⟷ (∃x. z = x * y ∧ x ## y)›
end
class positive_sep_magma = sep_magma+
assumes join_positivity: ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
subsubsection ‹Separation Semigroup›
class sep_semigroup = positive_sep_magma +
assumes sep_mult_assoc:
"⟦ x ## y; x * y ## z ⟧ ⟹ (x * y) * z = x * (y * z)"
assumes sep_disj_multD1: "⟦ x ## y * z; y ## z ⟧ ⟹ x ## y"
assumes sep_disj_multI1: "⟦ x ## y * z; y ## z ⟧ ⟹ x * y ## z"
assumes sep_disj_multD2: "⟦ x * y ## z; x ## y ⟧ ⟹ y ## z"
assumes sep_disj_multI2: "⟦ x * y ## z; x ## y ⟧ ⟹ x ## y * z"
begin
lemma sep_mult_assoc':
"⟦ y ## z; x ## y * z ⟧ ⟹ x * (y * z) = (x * y) * z"
by (metis local.sep_disj_multD1 local.sep_disj_multI1 local.sep_mult_assoc)
end
class sep_ab_semigroup = sep_semigroup + comm_sep_disj +
assumes sep_mult_commute: "x ## y ⟹ x * y = y * x"
begin
lemma self_sep_disj:
‹x ## y ⟹ x * y ## x * y ⟹ x ## x›
‹x ## y ⟹ x * y ## x * y ⟹ y ## y›
using local.sep_disj_commute local.sep_disj_multD1 sep_disj_multD2 by blast+
end
class sep_disj_intuitive = sep_magma +
assumes sep_disj_intuitive_right[simp]: ‹b ## c ⟹ a ## b * c ⟷ a ## b ∧ a ## c›
assumes sep_disj_intuitive_left [simp]: ‹a ## b ⟹ a * b ## c ⟷ a ## c ∧ b ## c›
subsubsection ‹Unital Separation›
class sep_magma_1 = sep_magma + mult_1 +
assumes sep_magma_1_left [simp]: "x ## 1"
assumes sep_magma_1_right [simp]: "1 ## x"
class sep_magma_0 = sep_magma_1 + mult_zero + zero_neq_one +
assumes sep_magma_0_left [simp]: "x ## 0 ⟷ x = 1"
assumes sep_magma_0_right [simp]: "0 ## x ⟷ x = 1"
class sep_no_inverse = sep_magma_1 +
assumes sep_no_inverse[simp]: ‹x ## y ⟹ x * y = 1 ⟷ x = 1 ∧ y = 1›
class positive_sep_magma_1 = sep_magma_1 + positive_sep_magma
begin
subclass sep_no_inverse
by (standard; metis local.join_positivity local.mult_1_right local.sep_magma_1_left sep_magma.join_sub_def)
end
subsubsection ‹Separation Monoid›
class sep_monoid = sep_magma_1 + sep_semigroup
begin
subclass positive_sep_magma_1 ..
end
definition (in times) subsume (infix "≼⇩×" 50)
where ‹subsume y z ⟷ (∃x. z = x * y)›
class positive_mult = times +
assumes positive_mult: ‹x ≼⇩× y ⟹ y ≼⇩× x ⟹ x = y›
class positive_mult_one = positive_mult + mult_1
begin
subclass no_inverse apply standard
by (metis local.mult_1_right local.positive_mult local.subsume_def)
end
class total_sep_monoid = monoid_mult + positive_mult + total_sep_disj
begin
subclass sep_magma .
subclass sep_monoid proof
fix x y z :: 'a
show ‹x ## 1› by simp
show ‹1 ## x› by simp
show ‹x ## y ⟹ x * y ## z ⟹ x * y * z = x * (y * z)›
using mult_assoc by blast
show ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
by (clarsimp simp add: join_sub_def, metis local.positive_mult times.subsume_def)
show ‹x ## y * z ⟹ y ## z ⟹ x ## y› by simp
show ‹x ## y * z ⟹ y ## z ⟹ x * y ## z› by simp
show ‹x * y ## z ⟹ x ## y ⟹ y ## z› by simp
show ‹x * y ## z ⟹ x ## y ⟹ x ## y * z › by simp
qed
subclass positive_mult_one ..
end
subsubsection ‹Separation Algebra›
class sep_algebra = sep_magma_1 + sep_ab_semigroup
begin
subclass sep_monoid ..
lemma sep_mult_left_commute[simp]:
"b ## (a * c) ⟹ a ## c ⟹ b * (a * c) = a * (b * c)"
by (metis local.sep_disj_commute local.sep_disj_multD2 local.sep_mult_assoc local.sep_mult_commute)
lemma join_sub_frame:
‹r ## y ⟹ x ≼⇩S⇩L y ⟹ r * x ≼⇩S⇩L r * y›
unfolding join_sub_def
by (clarsimp, metis local.sep_disj_commuteI local.sep_disj_multI1 local.sep_mult_commute)
lemma join_sub_ext_left:
‹z ## y ⟹ x ≼⇩S⇩L y ⟹ x ≼⇩S⇩L z * y›
unfolding join_sub_def
by (clarsimp, metis local.sep_disj_multD1 local.sep_disj_multI1 local.sep_mult_assoc sep_mult_left_commute)
lemma join_sub_ext_right:
‹y ## z ⟹ x ≼⇩S⇩L y ⟹ x ≼⇩S⇩L y * z›
unfolding join_sub_def
by (clarsimp, metis local.sep_disj_commute local.sep_disj_multD1 local.sep_disj_multI1 local.sep_mult_assoc local.sep_mult_commute)
end
subsubsection ‹Special Separation Algebra›
class total_sep_algebra = comm_monoid_mult + positive_mult + total_sep_disj
begin
subclass sep_magma .
subclass sep_algebra proof
fix x y z :: 'a
show ‹x ## 1› by simp
show ‹1 ## x› by simp
show ‹x ## y ⟹ x * y = y * x› by (simp add: mult_commute)
show ‹x ## y * z ⟹ y ## z ⟹ x * y ## z› by simp
show ‹x ## y * z ⟹ y ## z ⟹ x ## y› by simp
show ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
by (metis local.join_sub_def local.positive_mult times.subsume_def)
show ‹x ## y ⟹ y ## x› by simp
show ‹x * y ## z ⟹ x ## y ⟹ y ## z› by simp
show ‹x * y ## z ⟹ x ## y ⟹ x ## y * z› by simp
show ‹x ## y ⟹ x * y ## z ⟹ x * y * z = x * (y * z)›
by (simp add: mult_assoc)
qed
subclass total_sep_monoid ..
end
class discrete_sep_semigroup = sep_disj + times +
assumes discrete_sep_disj[simp]: "x ## y ⟷ x = y"
and discrete_mult[simp]: "x * y = (if x = y then x else undefined)"
begin
subclass sep_magma .
subclass sep_ab_semigroup proof
fix x y z :: 'a
show ‹x ## y ⟹ x * y = y * x› by simp
show ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y› unfolding join_sub_def by force
show ‹x ## y * z ⟹ y ## z ⟹ x ## y› by simp
show ‹x ## y * z ⟹ y ## z ⟹ x * y ## z› by simp
show ‹x ## y ⟹ y ## x› by simp
show ‹x * y ## z ⟹ x ## y ⟹ y ## z› by simp
show ‹x * y ## z ⟹ x ## y ⟹ x ## y * z› by simp
show ‹x ## y ⟹ x * y ## z ⟹ x * y * z = x * (y * z)› by simp
qed
end
class nonsepable_semigroup = sep_disj + times +
assumes nonsepable_disj[simp]: "¬ x ## y"
begin
subclass sep_magma .
subclass sep_ab_semigroup by (standard; simp add: local.join_sub_def)
end
class nonsepable_monoid = sep_disj + mult_1 +
assumes nonsepable_disj_1[simp]: ‹x ## y ⟷ x = 1 ∨ y = 1›
begin
subclass sep_magma .
subclass sep_algebra proof
fix x y z :: 'a
show ‹x ## y ⟹ x * y = y * x› by fastforce
show ‹x ## y * z ⟹ y ## z ⟹ x ## y›
by (metis local.mult_1_right local.nonsepable_disj_1)
show ‹x ## y * z ⟹ y ## z ⟹ x * y ## z›
by (metis local.mult_1_left local.nonsepable_disj_1)
show ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
unfolding join_sub_def apply clarsimp
by (metis local.mult_1_left)
show ‹x ## 1› by simp
show ‹1 ## x› by simp
show ‹x * y ## z ⟹ x ## y ⟹ y ## z›
by (metis local.mult_1_left local.nonsepable_disj_1)
show ‹x * y ## z ⟹ x ## y ⟹ x ## y * z›
by (metis local.mult_1_right local.nonsepable_disj_1)
show ‹x ## y ⟹ y ## x›
using local.nonsepable_disj_1 by blast
show ‹x ## y ⟹ x * y ## z ⟹ x * y * z = x * (y * z)› by force
qed
end
subsubsection ‹Strict Subsumption›
definition join_sub_strict :: ‹'a::sep_magma ⇒ 'a::sep_magma ⇒ bool› (infix "≺⇩S⇩L" 50)
where ‹join_sub_strict y z ⟷ join_sub y z ∧ y ≠ z›