Section Substitution.
End Substitution.
Hint Rewrite add_ren add_subst mul_ren mul_subst
enc_ren enc_subst : asimpl.
Hint Rewrite enc_zero enc_succ : simplify.
Hint Resolve normal_enc : core.
Proof with try (right; intros [] ?; discriminate).
unfold enc.
destruct s...
destruct s...
enough ({ n | s = AppL (repeat (var 0) n) (var 1)} +
forall n, s <> AppL (repeat (var 0) n) (var 1)).
- destruct H; [left|right]; intuition.
destruct s0 as [n]; exists n; now subst.
injection H; eapply n; eauto.
- induction s...
+ destruct f as [| []]...
left; now (exists 0).
+ destruct s1 as [[] | | |]...
destruct IHs2 as [[n IHs2]|IHs2].
* left. exists (S n). now subst.
* right. intros []; try discriminate.
cbn; injection 1; eapply IHs2.
Qed.
End ChurchEncoding.
Hint Rewrite @add_ren @add_subst @mul_ren @mul_subst
@enc_ren @enc_subst : asimpl.

Lemma church_commute X (s: exp X) n:
s = enc n ->
lambda lambda (var 0) ((ren (shift >> shift) s) (var 1) (var 0)) ≡
lambda lambda (ren (shift >> shift) s) ((var 0) (var 1)) (var 0).