(* Our typed calculus is turing-complete.
   We demonstrate this by embedding the
   "untyped" CBV lambda terms.
   First we define a type U with the characteristic
   equation U = U -> U, and then we show that all closed
   terms formed from abstraction, application and
   variables can be given this type.

   Turing-completeness follows from the fact that
   untyped CBV l-calc is turing-complete.
 *)

Fixpoint isULTerm (e:expr) : Prop :=
  match e with
  | Lam e' => isULTerm e'
  | App e1 e2 => isULTerm e1 /\ isULTerm e2
  | Var _ => True
  | _ => False
  end.

Lemma U_contractive : contractive (fun X => ty_lam X X).