(* Demonstrate an example of the factorial program working correctly. *)
Eval vm_compute in (snd (eval 100 empty_mem (App e_fac (Nat 6)))).
(* 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.

(* Specifications: *)
Lemma U_contractive : contractive (fun X => ty_lam X X).
Definition U := Rec (fun X => ty_lam X X).
Lemma U_eqn : U = ty_lam U U.
Fixpoint Ulist (n:nat) :=
match n with
| 0 => nil
| S n' => U :: Ulist n'
end.
Lemma ULTyped' : forall e n,
isULTerm e ->
closed' n e ->
Typ (Ulist n) e U.
Theorem ULTyped : forall e,
closed e /\ isULTerm e ->
Typ nil e U.