123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201(** This module implements various useful modules to generate IDs and
to keep track of there association with string as in a symbol table *)(** Signature of modules encoding symbol tables *)moduletypeCorrespondanceTableTYPE=sig(** [identifier] is the type of the identifier stored in the
table. It is meant to be associated with a [string] *)typeidentifier(** The type of the table *)typetable(** This exception can be raised when some identifier or some symbol
is not found in a query *)exceptionNot_found(** [empty] is an empty table *)valempty:table(** [find_id_of_sym sym t] returns the identifier of the string
[sym] stored in [t]. Raises [Not_found] if no such identifier
exists. *)valfind_id_of_sym:string->table->identifier(** [find_sym_from_id id t] returns the string (i.e. the symbol)
corresponding to the identifier [id] in table [t] *)valfind_sym_from_id:identifier->table->string(** [add_sym sym t] returns a pair [(id,t')] where [id] is the
identifier associated with [sym] in [t']. If [sym] already was
in [t] then [t']=[t] and [id] is the identifier which it was
associated with. Otherwise, a new identifier is generated and
the new association is stored in [t'].*)valadd_sym:string->table->identifier*table(** [to_string t] outputs the table [t] in a string.*)valto_string:table->string(** [log_content level t] logs the content of table [t].*)vallog_content:Logs.level->table->unit(** [fold f table a] returns [f id1 sym1 (f id2 sym2 ( ... ( f idN
symN a) ... ))] where the [(id,sym)] pairs are the ones that are
stored in the table [table]. The order of these key-value pairs in
the table is unspecified. *)valfold:(identifier->string->'a->'a)->table->'a->'aend(** Signature of modules encoding a generator of identifiers *)moduletypeIdGen_TYPE=sig(** The type of the identifier generated *)typeid(** The type of the generator *)typet(** [init ()] returns a new generator *)valinit:unit->t(** [get_fresh_id gen] returnds a pair [(id,gen')] where [id] is a
fresh [id] and [gen'] a new generator that knows [id] was already
generated.*)valget_fresh_id:t->(id*t)(** [eq id1 id2] returns [true] if [id1=id2] and [fase] otherwise. *)valeq:id->id->bool(** [compare id1 id2] returns an integer which is [0] if [id1=id2],
negative of [id1] is less than [id2] and positive otherwise. *)valcompare:id->id->intvalid_to_string:id->string(** [IdMap] implements maps whose keys are identifiers *)moduleIdMap:Map.Swithtypekey=id(** [Table] implements correspondance tables with the current
identifiers *)moduleTable:CorrespondanceTableTYPEwithtypeidentifier=idend(** Signature of encoding identifiers *)moduletypeIdType=sig(** The type of the identifiers *)typet(** [compare id1 id2] returns an integer which is [0] if [id1=id2],
negative of [id1] is less than [id2] and positive otherwise. *)valcompare:t->t->int(** [succ id] returns a new identifer strictly greater than [id] *)valsucc:t->t(** [start] is some identifer *)valstart:t(** [to_string id] returns a string describing the identifier *)valto_string:t->stringendmoduleLog=(valLogs.src_log(Logs.Src.create"ACGtkLib.idGenerator"~doc:"logs ACGtkLib idGenerator events"):Logs.LOG)(** This module is a functor that generates a identifier generator
from a module implementing these identifiers *)moduleIdGen(ID:IdType)=structtypeid=ID.ttypet=Generatorofidletinit()=GeneratorID.startletget_fresh_id(Generatorn)=n,Generator(ID.succn)leteqij=ID.compareij=0letcompare=ID.compareletid_to_string=ID.to_stringmoduleIdMap=Map.Make(ID)moduleTable=structtypeidentifier=idtypetable={symbols:idTries.Tries.t;ids:stringIdMap.t;gen:t}exceptionNot_foundletempty={symbols=Tries.Tries.empty;ids=IdMap.empty;gen=init()}letfind_id_of_symsymbol{symbols=table;ids=_;gen=_}=tryTries.Tries.findsymboltablewith|Tries.Tries.Not_found->raiseNot_foundletfind_sym_from_idid{symbols=_;ids=table;gen=_}=tryIdMap.findidtablewith|Not_found->raiseNot_foundletadd_symsym({symbols=syms;ids=ids;gen=vargen}astable)=tryTries.Tries.findsymsyms,tablewith|Tries.Tries.Not_found->letnew_var,new_vargen=get_fresh_idvargeninnew_var,{symbols=Tries.Tries.addsymnew_varsyms;ids=IdMap.addnew_varsymids;gen=new_vargen}letto_string{symbols=syms;ids=ids;gen=_}=letbuff=Buffer.create20inlet()=Buffer.add_stringbuff"Table from symbols to ids\n"inlet()=Tries.Tries.fold(funkeyvalue()->Buffer.add_stringbuff(Printf.sprintf"\t%s\t<->\t%s\n"key(ID.to_stringvalue)))()symsinlet()=Buffer.add_stringbuff"Table from symbols to ids\n"inlet()=IdMap.iter(funkeyvalue->Buffer.add_stringbuff(Printf.sprintf"\t%s\t<->\t%s\n%!"(ID.to_stringkey)value))idsinBuffer.contentsbuffletlog_contentlevel{symbols=syms;ids=ids;gen=_}=Log.msglevel(funm->m"Table from symbols to ids");Log.msglevel(funm->let()=Tries.Tries.fold(funkeyvalue()->Log.msglevel(funm->m"\t%s\t<->\t%s\n"key(ID.to_stringvalue)))()symsinm"Done.");Log.msglevel(funm->m"Table from symbols to ids");Log.msglevel(funm->let()=IdMap.iter(funkeyvalue->Log.msglevel(funm->m"\t%s\t<->\t%s\n%!"(ID.to_stringkey)value))idsinm"Done.")letfoldftablestart=IdMap.foldftable.idsstartendendmoduleIntId=structtypet=intletcompareij=i-jletsucci=i+1letstart=0letto_string=string_of_intend(** Module implementing the special case where identifiers ar
integers. *)moduleIntIdGen=IdGen(IntId)