From Undecidability.L.Tactics Require Export LClos.
Open Scope LClos.
(* *** Closure calculus interpreter *)
Definition CompBeta s t :=
match s,t with
|CompClos (lam ls) A,CompClos (lam lt) B => Some (CompClos ls (CompClos (lam lt) B::A))
|_,_ => None
end.
Definition CompAppCount j u v :=
match u,v with
(l,u),(k,v) => (j+(l+k),CompApp u v)
end.
Fixpoint CompSeval n (u: nat * Comp) : nat * Comp:=
match n with
S n =>
match u with
| (l,CompApp s t) =>
match CompBeta s t with
| Some u => CompSeval n (S l,u)
| None => CompSeval n (CompAppCount l (CompSeval n (0,s)) (CompSeval n (0,t)))
end
| (l,CompClos (app s t) A) => CompSeval n (l,(CompClos s A) (CompClos t A))
| (l,CompClos (var x) A) => (l,nth x A (CompVar x))
| u => u
end
| _ => u
end.
Proof with repeat (auto || congruence || subst || simpl in * || intuition).
intros vs vt eq. inv vs; inv vt... destruct s0... destruct s,s0... inv eq. repeat constructor... inv H1...
Qed.

(* Lemma CompBeta_lamComp s t u: CompBeta s t = Some u -> (lamComp s /\ lamComp t). Proof with repeat (auto || congruence || subst || simpl in. unfold CompBeta. intros equ. destruct s,t... destruct s... destruct s... destruct s,s0... Qed.  Lemma CompBeta_lamComp2 s t: CompBeta s t = None -> (~lamComp s \/ ~lamComp t). Proof with repeat inv_validComp;try (intros ?;repeat inv_validComp). unfold CompBeta. intros equ. destruct s,t;try now left... right... destruct s. left... left... destruct s0... right... right... congruence. Qed. *)
Lemma CompSeval_validComp s k n: validComp s -> validComp (snd (CompSeval n (k,s))).