(* * Copyright (c) 2009-2011, Andrew Appel, Robert Dockins and Aquinas Hobor. * *)
Open Local Scope nat_scope.
Module Type TY_FUNCTOR_SA_PROP.
Declare Module TF:TY_FUNCTOR_PROP.
Parameter Join_F: forall A, Join (F A). Existing Instance Join_F.
(*   Parameter Perm_F: forall A, Perm_alg (F A). EXisting Instance Perm_F. *)
Parameter paf_F : pafunctor f_F.        Existing Instance paf_F.
Parameter Perm_F: Perm_paf f_F Join_F.
Parameter Sep_F: Sep_paf f_F Join_F.
Parameter Canc_F: Canc_paf f_F Join_F.
Parameter Disj_F: Disj_paf f_F Join_F.
End TY_FUNCTOR_SA_PROP.
Module Type KNOT_HERED_SA.
Declare Module TFSA:TY_FUNCTOR_SA_PROP.
Declare Module K:KNOT_HERED with Module TF:=TFSA.TF.
Parameter Join_knot: Join knot.  Existing Instance Join_knot.
Parameter Perm_knot : Perm_alg knot.  Existing Instance Perm_knot.
Parameter Sep_knot : (forall A, Sep_alg (F A)) -> Sep_alg knot.  Existing Instance Sep_knot.
Parameter Canc_knot : (forall A, Canc_alg (F A)) -> Canc_alg knot.  Existing Instance Canc_knot.
Parameter Disj_knot : (forall A, Disj_alg (F A)) -> Disj_alg knot.  Existing Instance Disj_knot.
Instance Join_nat_F: Join (nat * F predicate) :=
Join_prod nat  (Join_equiv nat) (F predicate) _.
Instance Perm_nat_F : Perm_alg (nat * F predicate) :=
@Perm_prod nat _ _ _ (Perm_equiv _) (Perm_F predicate _ (Perm_equiv _)).
Instance Sep_nat_F (Sep_F: forall A, Sep_alg (F A)): Sep_alg (nat * F predicate) :=
@Sep_prod nat _ _ _ (Sep_equiv _) (Sep_F predicate).
Instance Canc_nat_F (Canc_F: forall A, Canc_alg (F A)): Canc_alg (nat * F predicate) :=
@Canc_prod nat _ _ _ (Canc_equiv _) (Canc_F predicate).
Instance Disj_nat_F (Disj_F: forall A, Disj_alg (F A)): Disj_alg (nat * F predicate) :=
@Disj_prod nat _ _ _ (Disj_equiv _) (Disj_F predicate).

Axiom join_unsquash : forall x1 x2 x3 : knot,
join x1 x2 x3 = join (unsquash x1) (unsquash x2) (unsquash x3).