(* 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
    }.(* 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
    }.(* 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
    }.(* 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
    }.(* 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
    }.

(* Specifications: *)
Lemma core_duplicable {A}{J: Join A}{SA: Sep_alg A}: forall a, join (core a) (core a) (core a).
Lemma core_self_join {A}{J: Join A}{SA: Sep_alg A}: forall a, a = core a -> join a a a.
Lemma core_idem {A}{J: Join A}{SA: Sep_alg A}: forall a, core (core a) = core a.
Lemma core_hom {A}{J: Join A}{PA: Perm_alg A}{SA: Sep_alg A}: forall {a b c}, join a b c -> join (core a) (core b) (core c).
Lemma split_core' {A} {J: Join A}{PA: Perm_alg A}{SA: Sep_alg A}: forall a b c, join a b (core c) -> a = core a.
Lemma split_core{A} {J: Join A}{PA: Perm_alg A}{SA: Sep_alg A}: forall a b c, join a b (core c) -> unit_for a a.
Lemma core_uniq {t} {J: Join t}{PA: Perm_alg t}: forall (SA1: @Sep_alg _ J) (SA2: @Sep_alg _ J), forall x, @core _ _ SA1 x = @core _ _ SA2 x.
Lemma join_core2 {A}{J: Join A}{PA: Perm_alg A}{SA: Sep_alg A}: forall a b c, join a b c -> core a = core b.