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.

Lemma decomp_none_ind (P: exp X -> exp X -> Type):
(forall x t, const x <> t -> ~ isVar t -> P (const x) t) ->
(forall x t, const x <> t -> ~ isVar t -> P t (const x)) ->
(forall s t, lambda s <> t -> P (lambda s) t) ->
(forall s t, s <> lambda t -> P s (lambda t)) ->
(forall s1 s2 t1 t2, s1 s2 <> t1 t2 -> P s1 t1 -> P (s1 s2) (t1 t2)) ->
(forall s1 s2 t1 t2, s1 s2 <> t1 t2 -> P s2 t2 -> P (s1 s2) (t1 t2)) ->
forall s t, decomp s t = None -> P s t.