Section NFA_NonHalt.
Hypothesis nfa_h0:
forall {i0},
nfa None i0 None = true.
Hypothesis nfa_h:
forall {s0 u0 i0},
tm s0 i0 = None ->
nfa (Some (s0,u0)) i0 None = true.
Hypothesis nfa_r:
forall {s0 u0 i0 s1 i1},
tm s0 i0 = Some {| nxt:= s1; out:=i1; dir:=Dpos |} ->
nfa (Some (s0,u0)) i0 (Some (s1,dfa u0 i1)) = true.
Hypothesis nfa_l:
forall {s0 i0 s1 u1 i1 i2 su2 su3},
tm s0 i0 = Some {| nxt:= s1; out:=i1; dir:=Dneg |} ->
nfa (Some (s1,u1)) i2 su2 = true ->
nfa su2 i1 su3 = true ->
nfa (Some (s0,dfa u1 i2)) i0 su3 = true.
Hypothesis dfa_0:
dfa U0 Σ0 = U0.
Inductive NFA_match: (option (St*U))->Word->Prop :=
| NFA_match_O: NFA_match None nil
| NFA_match_S v0 v1 i w: nfa v0 i v1 = true -> NFA_match v1 w -> NFA_match v0 (i::w)
.
Definition makeES' (l0 r0:Word)(m0:Σ)(s0:St):ExecState Σ :=
(s0,make_tape' half_tape_all0 l0 m0 r0 half_tape_all0).
Fixpoint DFA_match(w:Word):U :=
match w with
| nil => U0
| h::t => dfa (DFA_match t) h
end.
Definition ES_matched(l0 r0:Word)(m0:Σ)(s0:St):Prop :=
exists n0,
NFA_match (Some (s0,DFA_match l0)) ((m0::r0)++(repeat Σ0 n0)).
Hypothesis nfa_acc_0: nfa_acc (Some (St0,U0)) = true.
Hypothesis nfa_acc_h: nfa_acc None = false.
Hypothesis nfa_acc_closed:
forall {su0 su1},
nfa su0 Σ0 su1 = true ->
nfa_acc su0 = true ->
nfa_acc su1 = true.
End NFA_NonHalt.
Definition StU_list :=
concat (map (fun s => map (fun u => (s,u)) U_list) St_list).
Definition oStU_list :=
None::(map Some StU_list).
Definition forallb_U f :=
forallb f U_list.
Definition forallb_oStU f :=
forallb f oStU_list.
Definition nfa_h0_dec:bool :=
forallb_Σ (fun i0 => nfa None i0 None).
Definition nfa_h_dec:bool :=
forallb_St (fun s0 =>
forallb_U (fun u0 =>
forallb_Σ (fun i0 =>
match tm s0 i0 with
| None => nfa (Some (s0,u0)) i0 None
| _ => true
end))).
Definition nfa_r_dec:bool :=
forallb_St (fun s0 =>
forallb_U (fun u0 =>
forallb_Σ (fun i0 =>
match tm s0 i0 with
| Some {| nxt:= s1; out:=i1; dir:=Dpos |} =>
nfa (Some (s0,u0)) i0 (Some (s1,dfa u0 i1))
| _ => true
end))).
Definition nfa_l_dec:bool :=
forallb_St (fun s0 =>
forallb_Σ (fun i0 =>
match tm s0 i0 with
| Some {| nxt:= s1; out:=i1; dir:=Dneg |} =>
forallb_U (fun u1 =>
forallb_Σ (fun i2 =>
forallb_oStU (fun su2 =>
forallb_oStU (fun su3 =>
if nfa (Some (s1,u1)) i2 su2 then
if nfa su2 i1 su3 then nfa (Some (s0,dfa u1 i2)) i0 su3 else true else true
))))
| _ => true
end)).
Definition dfa_0_dec:=
U_eqb (dfa U0 Σ0) U0.
Definition nfa_acc_0_dec:=
nfa_acc (Some (St0,U0)).
Definition nfa_acc_h_dec:=
negb (nfa_acc None).
Definition nfa_acc_closed_dec :=
forallb_oStU (fun su0 =>
forallb_oStU (fun su1 =>
if nfa su0 Σ0 su1 then
if nfa_acc su0 then nfa_acc su1 else true
else true
)).
Definition all_cond_dec :=
nfa_h0_dec &&&
nfa_h_dec &&&
nfa_r_dec &&&
nfa_l_dec &&&
dfa_0_dec &&&
nfa_acc_0_dec &&&
nfa_acc_h_dec &&&
nfa_acc_closed_dec.
End verifyNFA.
Definition pair_enc{T1 T2}(T1_enc:T1->positive)(T2_enc:T2->positive):(T1*T2)->positive :=
fun x =>
let (x1,x2):=x in
enc_pair (T1_enc x1,T2_enc x2).

Lemma pair_enc_inj{T1 T2}(T1_enc:T1->positive)(T2_enc:T2->positive):
is_inj T1_enc ->
is_inj T2_enc ->
is_inj (pair_enc T1_enc T2_enc).