(* This one is only true under various restrictions. *)
(* Lemma full_combiner: forall (d : combiner), (* we require that As have complements *)
(forall a : ijoinable, exists a' : ijoinable, join (projT1 a) (projT1 a') A_top) ->
(* we require that T2 be nonempty *)
forall (at2 : T2),
full d ->
{t2 : T2 | d = DFull t2}.
*)
End CombineJoin.
Arguments combiner [A] _ _ _.
Arguments Join_combiner [A] [JA] _ [T1 T2] _ _ _ _ _.
Arguments CEmpty [A JA T1 T2].
Arguments CPart [A JA T1 T2] _ _.
Arguments CFull [A JA T1 T2] _.
(* Arguments identity_combiner. Arguments combiner_identity. Arguments combiner_full. *)
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] _ _ _.

Lemma ff_combiner : functorFacts fcombiner fcombiner_fmap.
Proof with auto.