Theory Phi_BI.Algebras
theory Algebras
imports
"HOL-Library.Product_Plus"
"HOL-Library.Finite_Map" HOL.Rat "Phi_Document.Base"
begin
setup ‹
Attrib.setup \<^binding>‹locale_intro› (Scan.succeed Locale.intro_add) ""
#> Attrib.setup \<^binding>‹locale_witness› (Scan.succeed Locale.witness_add) ""
›
section ‹Algebra Structures›
subsection ‹Preliminary Structures›
subsubsection ‹Homomorphism-like›
locale homo_one =
fixes ψ :: " 'a::one ⇒ 'b::one "
assumes homo_one[iff]: "ψ 1 = 1"
begin
declare homo_one_axioms[simp]
end
locale simple_homo_mul =
fixes ψ :: ‹ 'a::one ⇒ 'b::one ›
and D :: ‹ 'a set ›
assumes kernel_is_1[iff]: ‹x ∈ D ⟹ ψ x = 1 ⟷ x = 1›
and simple_homo_mul_dom[simp]: ‹1 ∈ D›
begin
sublocale homo_one by (standard, insert simple_homo_mul_dom, blast)
end
lemma simple_homo_mul_sub_dom:
‹ D' ⊆ D ∧ 1 ∈ D'
⟹ simple_homo_mul ψ D
⟹ simple_homo_mul ψ D' ›
unfolding simple_homo_mul_def
by clarsimp blast
locale homo_zero =
fixes φ :: ‹ 'a::zero ⇒ 'b::zero ›
assumes homo_zero[iff]: ‹φ 0 = 0›
locale homo_mult =
fixes φ :: " 'a::times ⇒ 'b::times "
assumes homo_mult: "φ (x * y) = φ x * φ y"
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; insert local.mult_1_left local.mult_1_right; blast)
class add_0 = plus + zero +
assumes add_0_add_0_left [simp]: ‹0 + x = x›
and add_0_add_0_right[simp]: ‹x + 0 = x›
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
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 Algebras›
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 = y * x ∧ y ## x)›
end
class sep_cancel = sep_magma +
assumes sep_cancel: ‹c ## a ⟹ c ## b ⟹ c * a = c * b ⟹ a = b›
class positive_sep_magma = sep_magma +
assumes join_positivity: ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
class strict_positive_sep_magma = sep_magma +
assumes join_strict_positivity: ‹a ## b ⟹ a = a * b ⟹ False›
text ‹Usually, we extend the carrier set of the partial algebra to the total universe by
importing the outside elements with no defined multiplication on them (except that to
identity element and zero). It works in most cases
but an exception is in semimodule structures where a notion of carrier set is required, so we
give this below.›
class mul_carrier =
fixes mul_carrier :: ‹'a ⇒ bool›
class sep_carrier = mul_carrier + sep_magma +
assumes mul_carrier_closed: ‹ ⟦ mul_carrier a; mul_carrier b; a ## b ⟧ ⟹ mul_carrier (a * b) ›
class sep_refl = sep_magma +
assumes sep_refl_mult_I: ‹a ## b ⟹ a ## a ⟹ b ## b ⟹ a * b ## a * b›
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
lemma join_sub_antisym: ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ False›
for x :: ‹'a :: {sep_semigroup, strict_positive_sep_magma}›
unfolding join_sub_def apply clarsimp
using join_positivity join_strict_positivity join_sub_def by blast
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_distrib = sep_magma +
assumes sep_disj_distrib_right[simp]: ‹b ## c ⟹ a ## b * c ⟷ a ## b ∧ a ## c›
assumes sep_disj_distrib_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_carrier_1 = sep_carrier + sep_magma_1 +
assumes sep_carrier_1[simp]: ‹mul_carrier 1›
class sep_carrier_0 = sep_carrier + sep_magma_0 +
assumes sep_carrier_0[simp]: ‹mul_carrier 0›
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.join_sub_def local.mult_1_left local.sep_magma_1_right)
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 = y * x)›
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 by (standard, metis local.mult_1_left local.positive_mult times.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_left:
‹r ## y ⟹ x ≼⇩S⇩L y ⟹ r * x ≼⇩S⇩L r * y›
unfolding join_sub_def
by(clarsimp, metis local.sep_disj_multD1 local.sep_disj_multI1 local.sep_mult_assoc)
lemma join_sub_frame_right:
‹r ## y ⟹ x ≼⇩S⇩L y ⟹ r * x ≼⇩S⇩L r * y›
unfolding join_sub_def
by(clarsimp, metis local.sep_disj_multD1 local.sep_disj_multI1 local.sep_mult_assoc)
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_commuteI local.sep_disj_multI1 local.sep_mult_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 Algebras›
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_semigroup = sep_disj + times +
assumes discrete_disj[simp]: "¬ x ## y"
begin
subclass sep_magma .
subclass sep_ab_semigroup by (standard; simp add: local.join_sub_def)
subclass sep_cancel by (standard; simp)
subclass strict_positive_sep_magma by (standard; simp)
end
class discrete_monoid = sep_disj + mult_1 +
assumes discrete_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.discrete_disj_1)
show ‹x ## y * z ⟹ y ## z ⟹ x * y ## z›
by (metis local.mult_1_left local.discrete_disj_1)
show ‹x ≼⇩S⇩L y ⟹ y ≼⇩S⇩L x ⟹ x = y›
unfolding join_sub_def by (clarsimp, metis local.mult_1_right)
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.discrete_disj_1)
show ‹x * y ## z ⟹ x ## y ⟹ x ## y * z›
by (metis local.mult_1_right local.discrete_disj_1)
show ‹x ## y ⟹ y ## x›
using local.discrete_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›