Section Decomposition.
Fixpoint decomp s t: option (eqs X) :=
if s == t then Some nil
else match s, t with
| var x, t => Some [(var x, t)]
| s, var x => Some [(var x, s)]
| app s1 s2, app t1 t2 =>
match decomp s1 t1, decomp s2 t2 with
| Some E1, Some E2 => Some (E1 ++ E2)
|  _, _ => None
end
| _, _ => None
end.
Fixpoint decomp' E :=
match E with
| nil => Some nil
| e :: E => match decomp (fst e) (snd e),  decomp' E with
| Some E1, Some E2 => Some (E1 ++ E2)
| _, _ => None
end
end.
Ltac decomp_ind :=
match goal with
| [|- decomp ?s ?t = Some ?E -> _] =>
intros H; pattern s, t, E; eapply decomp_some_ind; [idtac..|eapply H]; clear s t E H
| [|- decomp ?s ?t = None -> _] =>
intros H; pattern s, t; eapply decomp_none_ind; [idtac..|eapply H]; clear s t H
| [|- decomp' ?E = Some ?E' -> _] =>
intros H; pattern E, E'; eapply decomp'_some_ind; [idtac..|eapply H]; clear E E' H
| [|- decomp' ?E = None -> _] =>
intros H; pattern E; eapply decomp'_none_ind; [idtac..|eapply H]; clear E H
end.

Lemma decomp_typing s t E Gamma:
decomp s t = Some E ->
forall A, lambda_free s -> lambda_free t ->
(Gamma ⊢(1) s : A) -> (Gamma ⊢(1) t : A) ->
exists L, Gamma ⊢₊₊(1) E : L.