Section DISCRETE.  (* Prevent these Instances from going global! *)
(** We can turn any set into a Pos_alg by making no element join with any other element (including itself): the discrete PSA *)
Instance Join_discrete (A : Type): Join A := fun a1 a2 a3 : A => False.
Instance Perm_discrete (A: Type)  : @Perm_alg A (Join_discrete A).
Instance psa_discrete (A: Type) :  @Pos_alg A  (Join_discrete A).
End DISCRETE.
Set Implicit Arguments.
(** We provide a way to lift any sepalg into a Pos_alg by removing all of the units. *)
Section PSA_LIFT.
Variable A : Type.
Variable J_A: Join A.
Variable PA_A : Perm_alg A.
Definition lifted : Type := sig nonunit.
Definition lifted_obj (la: lifted) : A := proj1_sig la.
(*  Definition lifted_nonidentity (la : lifted) : nonidentity (lifted_obj la) := proj2_sig la. *)
Coercion lifted_obj : lifted >-> A.
Definition mk_lifted (a : A) (pf : nonunit a) : lifted :=
exist nonunit a pf.
Instance Join_lift: Join lifted := fun a1 a2 a3 : lifted => @join A J_A a1 a2 a3.
Instance Perm_lift: Perm_alg lifted.
Instance Pos_lift: Pos_alg lifted.
Instance Canc_lift {CA: Canc_alg A}: Canc_alg lifted.
Instance Disj_lift {DA: Disj_alg A}: Disj_alg lifted.
(** General facts about lifting *)

(* Specifications: *)
Lemma lifted_eq : forall a b,
lifted_obj a = lifted_obj b ->
a = b.
Lemma mk_lifted_refl1: forall (a:A)  (pf1 pf2: nonunit a),
mk_lifted pf1 = mk_lifted pf2.
Lemma lifted_pjoins : forall a b : lifted,
joins a b = @joins A J_A a b.
Lemma lifted_psub : forall a b : lifted,
join_sub a b -> @join_sub A J_A a b.  (* converse not provable *)
Lemma lifted_full {CA: Canc_alg A} : forall a : lifted,
@full A J_A a -> full a.    (* converse not provable *)
Proof with auto.