(* Sing_alg: adds the property that makes the Permission Algebra into a single-unit Separation Algebra.  (this is the "traditional" kind of Separation Algebra).   *)
Class Sing_alg A {J: Join A}{SA: Sep_alg A} :=
mkSing {
the_unit: A;
the_unit_core: forall a, core a = the_unit
}.
Arguments Sing_alg _ [J] [SA].
Arguments mkSing [A] [J] [SA] _ _.
(* Positive Permission Algebra: there are no units, every element is nonempty *)
Class Pos_alg  {A} {J: Join A} :=
no_units: forall e a, ~unit_for e a.
Arguments Pos_alg _ [J].
(* Has the "cross-split" property described in Dockins et al, "A fresh look at separation algebras and share accounting", 2009 *)
Class Cross_alg (t: Type)  `{J: Join t} :=
cross_split :
forall a b c d z : t,
join a b z ->
join c d z ->
{ x:(t*t*t*t) &  match x with (ac,ad,bc,bd) =>
join ac ad a /\ join bc bd b /\ join ac bc c /\ join ad bd d
end
}.
Arguments Cross_alg _ [J].
(* Has the "triple join" property  *)
Class Trip_alg {A} {J: Join A} :=
triple_join_exists:
forall (a b c ab bc ac : A), join a b ab -> join b c bc -> join a c ac ->
{abc | join ab c abc}.
Arguments Trip_alg _ [J].
(* We do NOT yet introduce "emp" as a notation or synonym for "identity". This is because "emp" is a predicate of Separation Logic, but this file contains only Separation Algebras.  Some separation logics have predicates that are not just "t -> Prop", and therefore it is premature in this file to define "emp". *)
(** * Lemmas about separation algebras. *)

(* Specifications: *)
Lemma  join_ex_units{A}{J: Join A}{SA: Sep_alg A}:
forall a, {e : A & unit_for e a }.
Lemma same_identity {A}{J: Join A}{PA: Perm_alg A}:
forall e e' a, identity e -> unit_for e a -> identity e' -> unit_for e' a -> e = e'.
Lemma same_unit {A}{J: Join A}{PA: Perm_alg A}{SA:Sep_alg A}{CA: Disj_alg A}:
forall {e1 e2 a}, unit_for e1 a -> unit_for e2 a -> e1 = e2.