Instance Disj_prop {DA: Disj_alg A}: Disj_alg (sig P).
(*  Instance CS_prop {CS: Cross_alg A}: Cross_alg (sig P). ... not true ...  Instance Sep_fun (SA: Sep_alg t'): Sep_alg (key -> t').  Instance Sep_pi (SA : forall i:I, Sep_alg (Pi i)): Sep_alg P.    Instance Sep_sigma (SA : forall i:I, Sep_alg (Sigma i)) : Sep_alg S.  Instance Disj_sigma: (forall i, Disj_alg (Sigma i)) -> Disj_alg S. End SepAlgSigma.  Existing Instance Join_sigma. Existing Instance Perm_sigma. Existing Instance Sep_sigma. Existing Instance Canc_sigma. Existing Instance Disj_sigma.  (** The SA operator on cartesian products. *)
Section SepAlgProd.
Variables (A: Type) (Ja: Join A).
Variables (B: Type) (Jb: Join B) .
Variables (PAa: Perm_alg A)(PAb: Perm_alg B).
Instance Join_prod : Join (A*B) :=
fun (x y z:A*B) =>  join (fst x) (fst y) (fst z) /\ join (snd x) (snd y) (snd z).
Instance Perm_prod  : Perm_alg (A*B).
Instance Sep_prod (SAa: Sep_alg A) (SAb: Sep_alg B) : Sep_alg (A*B).
Instance Disj_prod {DAa: Disj_alg A} {DAb:  Disj_alg B}: Disj_alg (A*B).
End SepAlgProd.
Arguments Perm_prod [A] [Ja] [B] [Jb] _ _.
Arguments Sep_prod [A] [Ja] [B] [Jb] _ _.
Existing Instance Join_prod.
Existing Instance Perm_prod.
Existing Instance Sep_prod.
Existing Instance Canc_prod.
Existing Instance Disj_prod.
(** The SA operator on disjoint sums. *)
Section SepAlgSum.
Variables (A: Type) (Ja: Join A) .
Variables (B: Type) (Jb: Join B) .
Variables (PAa: Perm_alg A) (PAb: Perm_alg B).
Instance Join_sum : Join (A+B) :=
(fun (x y z: A+B) =>
match x, y, z with
| inl xa, inl ya, inl za => join xa ya za
| inr xb, inr yb, inr zb => join xb yb zb
| _, _, _ => False
end).
Instance Perm_sum: Perm_alg (A+B).
Instance Sep_sum (SAa: Sep_alg A) (SAb: Sep_alg B): Sep_alg (A+B).
Instance Disj_sum {DAa: Disj_alg A} {DAb:  Disj_alg B}: Disj_alg (A+B).
End SepAlgSum.
Existing Instance Join_sum.
Existing Instance Perm_sum.
Existing Instance Sep_sum.
Existing Instance Canc_sum.
Existing Instance Disj_sum.
(** The SA operator on lists.  Lists are joined componentwise. *)
Section sa_list.
Variables (A: Type) (Ja: Join A)  (PAa: Perm_alg A).
Inductive list_join : list A -> list A -> list A -> Prop :=
| lj_nil : list_join nil nil nil
| lj_cons : forall x y z xs ys zs,
join x y z ->
list_join xs ys zs ->
list_join (x::xs) (y::ys) (z::zs).
Instance Join_list: Join (list A) := list_join.
Instance Perm_list: Perm_alg (list A).
Instance Sep_list (SAa: Sep_alg A) : Sep_alg (list A).
Instance Disj_list {DAa: Disj_alg A} : Disj_alg (list A).
End sa_list.
Existing Instance Join_list.
Existing Instance Perm_list.
Existing Instance Sep_list.
Existing Instance Canc_list.
Existing Instance Disj_list.
(** A join homomorphism is a function from one separation algebra to another which preserves the join relation.  This is used when we build the sa_preimage (to add a Perm_alg to the knot). *)
Definition raw_join_hom A B (j1: A -> A -> A -> Prop) (j2: B -> B -> B -> Prop) (f:A ->B) :=
forall x y z,
j1 x y z ->
j2 (f x) (f y) (f z).
Arguments raw_join_hom [A B] _ _ _.
Definition join_hom {A} {JA: Join A} {B} {JB: Join B} (f:A ->B) :=
forall x y z,
join x y z ->
join (f x) (f y) (f z).
(** The SA induced by the preimage of a section in a section-retraction pair.  This SA construction is used to generate a separation algebra over "knots". *)
Section sa_preimage.
Variables A B:Type.
Variable B_J: Join B.
Variable PA: Perm_alg B.
Variable f:A -> B.
Variable f':B -> A.
Hypothesis Hf'_f : forall x, f' (f x) = x.
Hypothesis Hf_f' : join_hom (f oo f').

(* Specifications: *)
Lemma f_inj : forall x y : A,  f x = f y -> x = y.
Instance Join_preimage: Join A :=
fun a b c => join (f a) (f b) (f c).