123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110(* This file is free software, part of Archsat. See file "LICENSE" for more details. *)(* Arbitrary tags for expressions.
Uses a mixed map (see containers.data.CCMixmap) *)(* Mixmap Implementation (from containers) *)(* ************************************************************************ *)(* Implementation taken from containers. *)type'binjection={get:(unit->unit)->'boption;set:'b->(unit->unit);}letcreate_inj()=letr=refNoneinletgetf=r:=None;f();!randsetv=(fun()->r:=Somev)in{get;set}moduletypeS=sigtypekeytypet(** A map containing values of different types, indexed by {!key}. *)valempty:t(** Empty map *)valget:inj:'ainjection->key->t->'aoption(** Get the value corresponding to this key, if it exists and
belongs to the same key *)valadd:inj:'ainjection->key->'a->t->t(** Bind the key to the value, using [inj] *)endmoduletypeORD=sigtypetvalcompare:t->t->intendmoduleMake(X:ORD):Swithtypekey=X.t=structmoduleM=Map.Make(X)typekey=X.ttypet=(unit->unit)M.tletempty=M.emptyletget~injxmap=tryinj.get(M.findxmap)withNot_found->Noneletadd~injxymap=M.addx(inj.sety)mapend(* Functor instantiation *)(* ************************************************************************ *)moduleM=Make(structtypet=intletcompare(a:int)(b:int)=compareabend)typemap=M.ttype'at={id:int;inj:'alistinjection;}letequalkk'=k.id=k'.idletmk_keyid={id;inj=create_inj();}letmax_id=ref0letcreate()=incrmax_id;mk_key!max_idletempty=M.emptyletgetmk=matchM.get~inj:k.injk.idmwith|None->[]|Somel->lletlastmk=matchgetmkwith|x::_->Somex|[]->Noneletreplacemkl=M.add~inj:k.injk.idlmletaddmkv=replacemk(v::getmk)