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:=Dpos; out:=Σ0 |}::
{| nxt:=St0; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St1; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St1; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St2; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St2; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St2; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St2; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St3; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St3; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St3; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St3; dir:=Dpos; out:=Σ1 |}::
{| nxt:=St4; dir:=Dneg; out:=Σ0 |}::
{| nxt:=St4; dir:=Dneg; out:=Σ1 |}::
{| nxt:=St4; dir:=Dpos; out:=Σ0 |}::
{| nxt:=St4; dir:=Dpos; out:=Σ1 |}::
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 St1 Σ0) (tm St1 Σ1)
(tm St2 Σ0) (tm St2 Σ1)
(tm St3 Σ0) (tm St3 Σ1)
(tm St4 Σ0) (tm St4 Σ1).
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.

Lemma nat_eqb_spec n1 n2 : if Nat.eqb n1 n2 then n1=n2 else n1<>n2.