Section fixH.
Variable H : Heap.
(* We define a function to unfold a closure, needed for the Turing machine M_unf. *)
(* function that unfolds if unfoldable *)
Definition unfoldTailRecStep '(stack,res) : (list (HClos*nat) * Pro) + option Pro :=
match stack with
| ((a,P),k)::stack =>
match P with
c::P =>
match c with
varT n =>
if ( k <=? n)
then
match lookup H a (n-k) with
| Some (b,Q) =>
inl (((b,Q),1)::(a,retT::P,S k)::stack,lamT::res)
| None => inr None
end
else
inl ((a,P,k)::stack,varT n::res)
| appT => inl ((a,P,k)::stack,appT::res)
| lamT => inl ((a,P,S k)::stack,lamT::res)
| retT => inl ((a,P,pred k)::stack,retT::res)
end
| [] => inl (stack,res)
end
| [] => inr (Some res)
end.

(* Lemma unfoldTailRecStep_retT a k stack res fuel m: loopSum ((m+1) + fuel) unfoldTailRecStep ((a,repeat retT m,k)::stack,res) = loopSum fuel unfoldTailRecStep (stack,repeat retT m ++ res).   Lemma unfoldTailRecStep_split_stack stack fuel: exists fuel', forall stack' res, loopSum fuel unfoldTailRecStep (stack++stack',res) = match loopSum ((fuel-fuel') + 1) unfoldTailRecStep (stack,res) with | Some res' => loopSum fuel' unfoldTailRecStep (stack',rev res') | x => x end /\ fuel' <= fuel.  (* Lemma unfoldTailRecStep_splita a k s P stack res fuel: loopSum fuel unfoldTailRecStep ((a,compile s++P,k)::stack,res) = loopSum fuel unfoldTailRecStep ((a,compile s,k)::(a,P,k)::stack,res). *)
Lemma unfoldTailRecStep_complete' a k s P s' stack res fuel:
unfolds H a k s s' ->
exists n,
loopSum (n + fuel) unfoldTailRecStep  ((a,compile s++P,k)::stack,res)
= loopSum fuel unfoldTailRecStep ((a,P,k)::stack,rev (compile s')++res) /\ n <= L_facts.size s' *3.