Section TNF.
Fixpoint list_nat_sum(ls:list nat):nat :=
match ls with
| nil => O
| h::t => h+(list_nat_sum t)
end.
Definition isHaltTrans(tr:option (Trans Σ)):nat :=
match tr with
| Some _ => 0
| None => 1
end.
Definition CountHaltTrans tm :=
list_nat_sum (map (fun s=>list_nat_sum (map (fun i => isHaltTrans (tm s i)) Σ_list)) St_list).
Ltac destruct_and :=
match goal with
| H:?A/\?B |- _ => destruct H
end.
Record TNF_Node := {
TNF_tm: TM Σ;
TNF_cnt: nat;
TNF_ptr: St;
}.
Definition TNF_Node_WF(x:TNF_Node):Prop :=
let (tm,cnt,ptr) := x in
cnt = CountHaltTrans tm /\
cnt <> 0 /\
UnusedState_ptr tm ptr.
Definition Trans_list:=
{| nxt:=St0; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St0; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St0; dir:=Dneg; out:=Σ2 |}::
{| nxt:=St0; dir:=Dneg; out:=Σ3 |}::
{| nxt:=St0; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St0; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St0; dir:=Dpos; out:=Σ2 |}::
{| nxt:=St0; dir:=Dpos; out:=Σ3 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ2 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ3 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ2 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ3 |}::
nil.
Definition St_leb s1 s2 :=
Nat.leb (St_to_nat s2) (St_to_nat s1).
Definition TM_simplify tm :=
makeTM
(tm St0 Σ0) (tm St0 Σ1) (tm St0 Σ2) (tm St0 Σ3)
(tm St1 Σ0) (tm St1 Σ1) (tm St1 Σ2) (tm St1 Σ3).
Definition TM_upd' tm s i tr :=
TM_simplify (TM_upd Σ Σ_eqb tm s i tr).
Definition TNF_Node_upd(x:TNF_Node) s i tr:=
let (tm,cnt,ptr):=x in
{|
TNF_tm:=TM_upd' tm s i (Some tr);
TNF_cnt:=Nat.pred cnt;
TNF_ptr:=(if St_eqb ptr (nxt _ tr) then (St_suc ptr) else ptr)
|}.
Definition TNF_Node_expand(x:TNF_Node) s i:=
let (tm,cnt,ptr):=x in
if Nat.eqb cnt 1 then nil else
map (TNF_Node_upd x s i)
(filter (fun tr => St_leb ptr (nxt _ tr)) Trans_list).
Hypothesis BB:nat.
Ltac nat_eq_dec s1 s2 :=
eq_dec nat_eqb_spec Nat.eqb s1 s2.
Ltac St_le_dec s1 s2 :=
eq_dec St_leb_spec St_leb s1 s2.
Definition TNF_Node_HTUB(x:TNF_Node):Prop :=
let (tm,_,_):=x in
HaltTimeUpperBound _ BB (InitES Σ Σ0) (LE _ tm).

Lemma TNF_Node_expand_spec {x:TNF_Node}{n s t}:
HaltsAt Σ (TNF_tm x) n (InitES Σ Σ0) ->
Steps Σ (TNF_tm x) n (InitES Σ Σ0) (s,t) ->
n<=BB ->
TNF_Node_WF x ->
(forall x', In x' (TNF_Node_expand x s (t Z0)) -> TNF_Node_WF x') /\
((forall x', In x' (TNF_Node_expand x s (t Z0)) -> TNF_Node_HTUB x') -> TNF_Node_HTUB x).