(* * Copyright (c) 2009-2012, Andrew Appel, Robert Dockins and Aquinas Hobor. * This presentation of Permission Algebras and Separation Algebras * includes ideas from a discussion with Jonas Jensen and also from * a paper by Francois Pottier. *)
Set Implicit Arguments.
Class Join (t: Type) : Type := join: t -> t -> t -> Prop.
(* "Permission Algebra": commutative semigroup, such that if units exist, they must have certain properties. *)
Class Perm_alg (t: Type) {J: Join t} : Type :=
mkPerm   {
join_eq: forall {x y z z'}, join x y z -> join x y z' -> z = z';
join_assoc: forall {a b c d e}, join a b d -> join d c e ->
{f : t & join b c f /\ join a f e};
join_comm: forall {a b c}, join a b c -> join b a c;
join_positivity: forall {a a' b b'}, join a a' b -> join b b' a -> a=b
}.
Arguments Perm_alg _ {J}.
Definition unit_for {t}{J: Join t} (e a: t) := join e a a.
Definition identity {t} {J: Join t} (e: t) := forall a b, join e a b -> a=b.
Hint Extern 2 (@join _ _ _ _ _) =>
(eapply join_comm; trivial;
try eassumption;
(* This next line looks superfluous, but it is not: it catches the case where H is join at a function type, where the goal is join at an applied function. *)
match goal with H: @join _ _ _ _ _ |- _ => apply H end)
: core.
(* Hint Immediate @join_comm. *)
Hint Unfold unit_for : core.
(* Sep_alg: additional properties that makes a Permission Algebra into a Separation Algebra. *)
Class Sep_alg A {J: Join A} : Type :=
mkSep {
core: A -> A;
core_unit: forall t, unit_for (core t) t;
join_core: forall {a b c}, join a b c -> core a = core c
}.
Arguments Sep_alg _ {J}.
(* Disj_alg: adds the property that no nonempty element can join with itself. *)
Class Disj_alg  (t: Type) {J: Join t} :=
join_self: forall {a b}, join a a b -> identity a.
Arguments Disj_alg _ {J}.

Lemma join_ex_identity  {A}{J: Join A}{PA: Perm_alg A}{SA: Sep_alg A}:
forall a, {e : A & prod (identity e) (unit_for e a) }.