(* * Copyright (c) 2009-2011, Andrew Appel, Robert Dockins and Aquinas Hobor. * *)
Set Implicit Arguments.
(* Parameterized separating structures, useful for knot_prop_sa and maybe for the general sa_knot. *)
Section unmaps.
Variables (A: Type)(J_A: Join A).
Variables (B: Type)(J_B: Join B).
Definition unmap_left (f:A -> B) :=
forall x' y z,
join x' (f y) (f z) ->
{ x:A & { y0:A | join x y0 z /\ f x = x' /\ f y0 = f y }}.
Definition unmap_right (f:A -> B) :=
forall x y z',
join (f x) (f y) z' ->
{ y0: A & { z:A | join x y0 z /\ f y0 = f y /\ f z = z' }}.
End unmaps.
(* Implicit Arguments unmap_right. Implicit Arguments unmap_left. *)
(* Definition Join_paf (F: functor): Type := forall A, Join (F A). Definition Perm_paf {F: functor} (paf_join: forall A, Join (F A)): Type := forall A: Type, Perm_alg (F A). Definition Sep_paf {F: functor} (paf_join: forall A, Join (F A)): Type := forall A: Type, Sep_alg (F A). Definition Canc_paf {F: functor} (paf_join: forall A, Join (F A)): Type := forall A: Type, Canc_alg (F A). Definition Disj_paf {F: functor} (paf_join: forall A, Join (F A)): Type := forall A: Type, Disj_alg (F A). *)
(* TODO: change pafunctor, unmap_left, unmap_right into prop *)
Record pafunctor (F: functor) (paf_join: forall A, Join (F A)): Type := Pafunctor
{
paf_join_hom : forall A B (f : A -> B) (g: B -> A), join_hom (fmap F f g);
paf_preserves_unmap_left : forall A B (f : A -> B) (g: B -> A),
unmap_left (paf_join A) (paf_join B) (fmap F f g);
paf_preserves_unmap_right : forall A B (f : A -> B) (g: B -> A),
unmap_right (paf_join A) (paf_join B) (fmap F f g)
}.
(* GENERATORS *)
Section ConstPAFunctor.
Variables (T : Type)(J_T: Join T).

Lemma paf_const : pafunctor (fconst T) (fun _ => J_T).
constructor; intros; hnf; intros.