12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273openCoremoduleFDD=Fdd.FDDmoduleField=Packet.Fieldtypet=Set.M(Int64).tMap.M(Field).tletempty:t=Map.empty(moduleField)letmerge:t->t->t=Map.merge_skewed~combine:(fun~key->Set.union)letrecof_fdd(fdd:FDD.t):t=for_fddemptyfddandfor_fdddomfdd=matchFDD.ungetfddwith|Leafr->for_leafdomr|Branch{test=(field,_)}->letvs,residuals=for_fieldfieldfdd(Set.empty(moduleInt64))(Set.empty(moduleFDD))inletdom=Map.updatedomfield~f:(function|None->vs|Somevs'->Set.unionvsvs')inSet.foldresiduals~init:dom~f:for_fdd(** returns list of values appearing in tests with field [f] in [fdd], and
residual trees below f-tests. *)andfor_fieldffddvsresiduals=matchFDD.ungetfddwith|Branch{test=(f',v);tru;fls}whenPoly.(f'=f)->letvs=matchvwithConstv->Set.addvsv|_->vsinfor_fieldfflsvs(Set.addresidualstru)|Branch_|Leaf_->(vs,Set.addresidualsfdd)andfor_leafdomact=Set.foldact~init:dom~f:for_seqandfor_seqdomseq=Map.to_alistseq|>List.fold~init:dom~f:(fundom->function|(Ff,Constv)->Map.updatedomf~f:(function|None->Set.singleton(moduleInt64)v|Somevs->Set.addvsv)|_->dom)moduleAuto=Global_compiler.Automatonletof_automaton(auto:Auto.t):t=Auto.fold_reachableauto~init:empty~f:(fundom_(e,d)->for_fdd(for_fdddome)d)letrepresentative_pks(t:t):Packet.tlist=Map.foldt~init:[Packet.empty]~f:(fun~key:field~data:vspks->Set.to_listvs(* add fresh value, representing the case that all tests fails *)|>List.consInt64.(Set.min_elt_exnvs-1L)|>List.concat_map~f:(funv->List.mappks~f:(Map.add_exn~key:field~data:v)))