constructor; intros;
extensionality pd; unfold fcombiner_fmap.
icase pd; rewrite fmap_id...
icase pd; rewrite <- fmap_comp...
Qed.
Definition f_combiner : functor := Functor ff_combiner.
Variable top_S : S.
Variable topS_full : full top_S.
Variable combjoin : forall A, (T1 A) -> (T1 A) -> (T2 A) -> Prop.
Variable combjoin_eq : forall A v1 v1' v2 v2',
combjoin A v1 v1' v2 ->
combjoin A v1 v1' v2' ->
v2 = v2'.
Variable combjoin_assoc : forall A (v1 v2 v3 v4: T1 A) (v5: T2 A),
join v1 v2 v3 ->
combjoin A v3 v4 v5 ->
{v' : (T1 A) & join v2 v4 v' /\ combjoin A v1 v' v5}.
Variable combjoin_com : forall A v1 v2 v3,
combjoin A v1 v2 v3 ->
combjoin A v2 v1 v3.
Variable combjoin_canc : forall A v1 v1' v2 v3,
combjoin A v1 v2 v3 ->
combjoin A v1' v2 v3 ->
v1 = v1'.
Variable saf_T1 : pafunctor T1 J1.
Instance Join_fcombiner (A: Type) : Join (fcombiner A) :=
Join_combiner top_S (J1 A) (combjoin A).
Instance Perm_fcombiner (A: Type): Perm_alg (fcombiner A).
Definition combjoin_hom (A : Type) (B : Type)
(f : T1 A -> T1 B) (g : T2 A -> T2 B) : Prop :=
forall x y z,
combjoin A x y z ->
combjoin B (f x) (f y) (g z).
Arguments combjoin_hom [A B] _ _.
Variable fmaps_combjoin_hom: forall A B (f : A -> B) (g: B -> A),
combjoin_hom (fmap T1 f g) (fmap T2 f g).

(* Specifications: *)
Lemma fmap_fcombiner_hom: forall A B (f : A -> B) (g: B -> A),
join_hom (JA := Join_fcombiner A) (JB := Join_fcombiner B) (fmap f_combiner f g).