(* * 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).
(* Hint Immediate @join_comm. *)
Hint Unfold unit_for.

Lemma join_assoc_uniq:
forall {t} {J: Join t} (PA1 PA2: @Perm_alg t J),
forall a b c d e H H',
(projT1 (@join_assoc _ _ PA1  a b c d e H H'))
= (projT1 (@join_assoc _ _ PA2  a b c d e H H')).