(** *** Step-indexed self-interpreter *)
Definition E := Eval cbv in
rho (.\ "Eval","n","u";"u"
(.\"";!none)
(.\"s","t"; "n" !none
(.\"n"; "Eval" "n" "s"
(.\"s"; "Eval" "n" "t"
(.\"t"; "s"
(.\""; !none)
(.\"",""; !none)
(.\"s"; "Eval" "n" (!Subst "s" !Zero "t")))
!none)
!none))
(.\"s"; !some (!Lam "s"))).
Definition cLam s := lambda(lambda(lambda(0 s))).
Hint Unfold cLam : cbv.

(* Specifications: *)
Lemma E_rec_app_Sn_1 s t n s1 t1 :
proc s1 ->
proc t1 ->
E (enc n) (tenc s) ≡ some (cLam s1) ->
E (enc n) (tenc t) ≡ some (cLam t1) ->
E (enc (S n)) (tenc (app s t)) ≡ E (enc n) (Subst s1 Zero (cLam t1)).
Lemma E_rec_app_Sn_2 s t n : E (enc n) (tenc s) ≡ none -> E (enc (S n)) (tenc (s t)) ≡ none.
Lemma E_rec_app_Sn_3 s t n t1 : proc t1
-> E (enc n) (tenc s) ≡ some (cLam t1)
-> E (enc n) (tenc t) ≡ none
-> E (enc (S n)) (tenc (s t)) ≡ none.
Lemma E_correct k s : E (enc k) (tenc s) ≡ oenc (eval k s).
Proof with value.