let merge_subnfas (graph : graph)
(a : assignment)
(sub : submapping) : lang =
let merged_lang = ref Unrestricted in
let insertnfa outer (qs', qs) inner (qf, qf') =
let offset = outer.next_q in
let convert x = x + offset in
let epss = which_states ~create:false outer.epsilon qs' in
let epss2 = which_states ~create:false outer.epsilon qf in
Hashset.remove epss qs;
Hashset.remove epss2 qf';
merge_nfas outer inner;
add_trans outer qs' Epsilon (convert inner.s);
add_trans outer (convert inner.f) Epsilon qf' in
let intersect_step id (lhs, rhs) =
let id_node = find_node graph id in
let machine = match id_node.lang with
| Machine m -> m
| _ -> failwith "Encountered inconsistent depgraph state." in
let q_l', q_l = get_assignment a lhs machine.s in
let q_r, q_r' = get_assignment a rhs machine.f in
let submachine = extract_nfa machine q_l q_r in
merged_lang := simple_intersect (Machine submachine) (!merged_lang) in
let merge_step id (lhs, rhs) =
let id_node = find_node graph id in
let machine = match id_node.lang with
| Machine m -> m
| _ -> failwith "Encountered inconsistent depgraph state." in
let qs', qs = get_assignment a lhs machine.s in
let qf, qf' = get_assignment a rhs machine.f in
let othermachine = match !merged_lang with
| Machine m -> m
| _ -> failwith "Shouldn't happen."
in
insertnfa machine (qs', qs) othermachine (qf, qf')
in
Hashtbl.iter intersect_step sub;
Hashtbl.iter merge_step sub;
!merged_lang