123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899openUtiltype'reslookup_res=Labelof'res|Nothing|EverythingmoduleMake=functor(Y:Map.OrderedType)->functor(Z:Map.OrderedType)->structmoduleY_tries=structtypet=(Y.t*int)optionletcomparexy=matchx,ywithNone,None->0|Some(l,n),Some(l',n')->letm=Y.comparell'inifInt.equalm0thenn-n'elsem|Some(l,n),None->1|None,Some(l,n)->-1endmoduleZSet=Set.Make(Z)moduleX_tries=structtypet=ZSet.tletnil=ZSet.emptyletis_nil=ZSet.is_emptyletadd=ZSet.unionletsub=ZSet.diffendmoduleTrie=Trie.Make(Y_tries)(X_tries)type'adecompose_fun='a->(Y.t*'alist)optiontype'treelookup_fun='tree->(Y.t*'treelist)lookup_restypet=Trie.ttypepattern=(Y.t*int)optionlistletempty=Trie.empty(* [path_of dna pat] returns the list of nodes of the pattern [pat] read in
prefix ordering, [dna] is the function returning the main node of a pattern *)letpath_ofdna=letrecpath_of_deferred=function|[]->[]|h::tl->pathrectlhandpathrecdeferredt=matchdnatwith|None->None::(path_of_deferreddeferred)|Some(lbl,[])->(Some(lbl,0))::(path_of_deferreddeferred)|Some(lbl,(h::def_sublasv))->(Some(lbl,List.lengthv))::(pathrec(def_subl@deferred)h)inpathrec[]lettm_oftmlbl=try[Trie.nexttmlbl]withNot_found->[]letrecskip_argntm=ifInt.equaln0then[tm]elseletlabels=Trie.labelstminletmaplbl=matchlblwith|None->skip_arg(predn)(Trie.nexttmlbl)|Some(_,m)->skip_arg(predn+m)(Trie.nexttmlbl)inList.map_appendmaplabelsletlookuptmdnat=letreclookrecttm=matchdnatwith|Nothing->tm_oftmNone|Label(lbl,v)->letfoldaccuc=List.map_append(funtm->lookrecctm)accuintm_oftmNone@(List.fold_leftfold(tm_oftm(Some(lbl,List.lengthv)))v)|Everything->skip_arg1tminList.map_append(funtm->ZSet.elements(Trie.gettm))(lookrecttm)letpatterndnapat=path_ofdnapatletaddtmpinf=Trie.addp(ZSet.singletoninf)tmletrmvtmpinf=Trie.removep(ZSet.singletoninf)tmend