From Undecidability.L Require Export Util.L_facts.
Hint Resolve eval_converges : core.
(* * Step indexed evaluation *)
Inductive seval : nat -> term -> term -> Prop :=
| sevalR n s : seval n (lam s) (lam s)
| sevalS n s t u v w :
seval n s (lam u) -> seval n t (lam v) -> seval n (subst u 0 (lam v)) w -> seval (S n) (s t) w.
Local Notation "s '⇓' n t" := (seval n s t) (at level 51).
Proof with eauto using star_trans, star_trans_l, star_trans_r.
intros. induction H as [ | n s t u v w _ [IHe1 _] _ [IHe2 _] _ [IHe3 lam_w]].
- repeat econstructor.
- split...
transitivity ((lam u) t)...
transitivity ((lam u) (lam v))... now rewrite stepApp.
Qed.
Hint Resolve seval_eval : core.
(* Equivalence between step index evaluation and evaluation *)
Proof with eauto using seval_S, seval.
intros H; revert n t; induction H; intros n u A...
- inv A...
- inv A...
Qed.
(*  Evaluation as a function *)
Fixpoint eva (n : nat) (u : term) :=
match u with
| var n => None
| lam s => Some (lam s)
| app s t => match n with
| 0   => None
| S n => match eva n s, eva n t with
| Some (lam s), Some t => eva n (subst s 0 t)
|   _ , _ => None
end
end
end.
(* Equivalence between the evaluation function and step indexed evaluation *)

Lemma equiv_eva s t : lambda t -> s == t -> exists n, eva n s = Some t.