let elim_dead_states (nfa : nfa) : unit =
let live_states = backward_reachable nfa nfa.f in
let dead_lhs = create def_machine_size in
let dead_rhs = create (def_machine_size * def_delta_size) in
let dead_eps = create def_machine_size in
let delta_iter q1 rhs =
if mem live_states q1 then
let rhs_iter q2 _ = if not (mem live_states q2) then
add dead_rhs (q1, rhs, q2)
in
Hashtbl.iter rhs_iter rhs
else
add dead_lhs q1
in
let epsilon_iter q1 rhs =
if mem live_states q1 then
Hashtbl.replace nfa.epsilon q1 (cap rhs live_states)
else
add dead_eps q1
in
let do_remove_lhs q = Hashtbl.remove nfa.delta q in
let do_remove_rhs (q1, tbl, q2) =
if Hashtbl.length tbl = 1 then
Hashtbl.remove nfa.delta q1
else
Hashtbl.remove tbl q2
in
Hashtbl.iter delta_iter nfa.delta;
Hashtbl.iter epsilon_iter nfa.epsilon;
nfa.q <- live_states;
iter do_remove_lhs dead_lhs;
iter do_remove_rhs dead_rhs