123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110(*
* MultiPMap - Polymorphic maps with multiple associations
* Copyright (C) 1996-2003 Xavier Leroy, Nicolas Cannasse, Markus Mottl
* Copyright (C) 2008 David Teller, LIFO, Universite d'Orleans
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in file LICENSE.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)moduleS=BatSet.PSetmoduleM=BatMap.PMaptype('a,'b)t={content :('a,'bS.t)M.t;keys:'a->'a->int;data:'b->'b->int}letempty={content =M.empty;keys=compare;data=compare}letis_emptyt=M.is_empty t.contentletcreatekeysdata={content =M.create keys;data=data;keys=keys}letfindkt=tryM.findkt.contentwithNot_found->S.createt.dataletaddkdt={(t)withcontent=M.addk(S.addd(findkt))t.content}letremove_allkt={(t)withcontent=M.removekt.content}letremovekdt=tryletset=S.removed(M.findkt.content)in{(t)withcontent=ifS.is_emptysetthenM.removekt.contentelseM.addksett.content;}withNot_found->tletmemkd=M.memkd.content(*let exists=mem *)letiterfd=M.iterfd.contentletmap(f:('bS.t->'cS.t))(cmp:('b->'b->int)->('c->'c->int))(t:('a,'b)t)={content=M.mapft.content;keys=t.keys;data=cmpt.data}letmapi(f:('a->'bS.t->'cS.t))(cmp:('b->'b->int)->('c->'c->int))(t:('a,'b)t)={content=M.mapift.content;keys=t.keys;data=cmpt.data}letfoldfdi=M.foldfd.contentiletfoldifdi=M.foldifd.contentiletmodifykft={twithcontent=M.modifykft.content}letmodify_defdftkft={twithcontent=M.modify_defdftkft.content}letmodify_optkft={twithcontent=M.modify_optkft.content}letenumt=BatEnum.concat(BatEnum.map(fun(k,e)->BatEnum.map(funx->(k,x))(S.enume))(M.enumt.content))letof_enum?(keys=compare)?(data=compare)e=let base=createkeysdatainBatEnum.fold(funacc(k,d)->addkdacc)baseeletprint?(first="{\n")?(last="\n}")?(sep=",\n")?(kvsep=": ")print_kprint_voutt=BatEnum.print~first~last~sep(funout (k,v)->BatPrintf.fprintfout"%a%s%a"print_kkkvsepprint_vv)out(enumt)moduleInfix=structlet(-->)mapkey=findkeymaplet(<--)map(key,value)=addkeyvalue mapend