Section ParameterizedCombiner.
Existing Instance Join_combiner.
Variable S : Type.
Variable JS : Join S.
Variable pa_S : Perm_alg S.
Variable sa_S : Sep_alg S.
Variable ca_S : Canc_alg S.
Variable da_S : Disj_alg S.
Variable T1 : functor.
Variable J1: forall A, Join (T1 A).
Variable Perm1: forall A, Perm_alg (T1 A).
Variable Sep1: forall A, Sep_alg (T1 A).
Variable T2 : functor.
Definition fcombiner (A : Type) : Type :=
@combiner S JS (T1 A) (T2 A).
Definition fcombiner_fmap (A B : Type) (f: A -> B) (g: B -> A)
(fa : fcombiner A) : fcombiner B :=
match fa with
| CEmpty => CEmpty
| CPart sh rs => CPart sh (fmap T1 f g rs)
| CFull trs => CFull (fmap T2 f g trs)
end.
Arguments fcombiner_fmap [A B] _ _ _.
Proof with auto.
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).

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).