12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)moduletypeS=sigtypelabeltypedatatypetvalempty:tvalget:t->datavalnext:t->label->tvallabels:t->labellistvaladd:labellist->data->t->tvalremove:labellist->data->t->tvaliter:(labellist->data->unit)->t->unitendmoduletypeGrp=sigtypetvalnil:tvalis_nil:t->boolvaladd:t->t->tvalsub:t->t->tendmoduleMake(Y:Map.OrderedType)(X:Grp)=structmoduleT_codom=Map.Make(Y)typedata=X.ttypelabel=Y.ttypet=NodeofX.t*tT_codom.tletcodom_for_allfm=letfoldkeyvaccu=fv&&accuinT_codom.foldfoldmtrueletempty=Node(X.nil,T_codom.empty)letnext(Node(_,m))lbl=T_codom.findlblmletget(Node(hereset,_))=heresetletlabels(Node(_,m))=(* FIXME: this is order-dependent. Try to find a more robust presentation? *)List.rev(T_codom.fold(funx_acc->x::acc)m[])letis_empty_node(Node(a,b))=(X.is_nila)&&(T_codom.is_emptyb)letassure_arcmlbl=ifT_codom.memlblmthenmelseT_codom.addlbl(Node(X.nil,T_codom.empty))mletcleanse_arcs(Node(hereset,m))=letm=ifcodom_for_allis_empty_nodemthenT_codom.emptyelseminNode(hereset,m)letrecat_pathf(Node(hereset,m))=function|[]->cleanse_arcs(Node(fhereset,m))|h::t->letm=assure_arcmhincleanse_arcs(Node(hereset,T_codom.addh(at_pathf(T_codom.findhm)t)m))letaddpathvtm=at_path(funhereset->X.addvhereset)tmpathletremovepathvtm=at_path(funhereset->X.subheresetv)tmpathletiterftlm=letrecapprecpfx(Node(hereset,m))=letpath=List.revpfxinfpathhereset;T_codom.iter(funltm->apprec(l::pfx)tm)minapprec[]tlmend