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_some_ind (P: exp X -> exp X -> eqs X -> Type):
(forall s, P s s nil) ->
(forall x s, var x <> s -> P (var x) s [(var x, s)]) ->
(forall x s, var x <> s -> P s (var x) [(var x, s)]) ->
(forall s1 s2 t1 t2 E1 E2, s1 s2 <> t1 t2 ->
decomp s1 t1 = Some E1 -> P s1 t1 E1 ->
decomp s2 t2 = Some E2 -> P s2 t2 E2 ->
P (s1 s2) (t1 t2) (E1 ++ E2)) ->
forall s t E, decomp s t = Some E -> P s t E.