123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192(** This module implements various useful modules to generate IDs and
to keep track of there association with string as in a symbol table *)moduleLog=Xlog.Make(structletname="IdGenerator"end)(** Signature of modules encoding symbol tables *)moduletypeCorrespondanceTableTYPE=sigtypeidentifier(** [identifier] is the type of the identifier stored in the
table. It is meant to be associated with a [string] *)typetable(** The type of the table *)exceptionCT_Not_found(** This exception can be raised when some identifier or some symbol
is not found in a query *)valempty:table(** [empty] is an empty table *)valfind_id_of_sym:string->table->identifier(** [find_id_of_sym sym t] returns the identifier of the string
[sym] stored in [t]. Raises [CT_Not_found] if no such identifier
exists. *)valfind_id_of_sym_opt:string->table->identifieroption(** [find_id_of_sym_opt sym t] returns [Some id] where [id] is the
identifier of the string [sym] stored in [t], and returns [None]
if no such identifier exists. *)valfind_sym_from_id:identifier->table->string(** [find_sym_from_id id t] returns the string (i.e. the symbol)
corresponding to the identifier [id] in table [t] *)valadd_sym:string->table->identifier*table(** [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'].*)valpp:Format.formatter->table->unit(** [pp f t] pretty prints the table [t] on the formatter [f] *)valfold:(identifier->string->'a->'a)->table->'a->'a(** [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. *)end(** Signature of modules encoding a generator of identifiers *)moduletypeIdGen_TYPE=sigtypeid(** The type of the identifier generated *)typet(** The type of the generator *)valinit:unit->t(** [init ()] returns a new generator *)valget_fresh_id:t->id*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.*)valeq:id->id->bool(** [eq id1 id2] returns [true] if [id1=id2] and [fase] otherwise. *)valcompare:id->id->int(** [compare id1 id2] returns an integer which is [0] if [id1=id2],
negative of [id1] is less than [id2] and positive otherwise. *)valid_to_string:id->stringmoduleIdMap:Map.Swithtypekey=id(** [IdMap] implements maps whose keys are identifiers *)moduleTable:CorrespondanceTableTYPEwithtypeidentifier=id(** [Table] implements correspondance tables with the current
identifiers *)end(** Signature of encoding identifiers *)moduletypeIdType=sigtypet(** The type of the identifiers *)valcompare:t->t->int(** [compare id1 id2] returns an integer which is [0] if [id1=id2],
negative of [id1] is less than [id2] and positive otherwise. *)valsucc:t->t(** [succ id] returns a new identifer strictly greater than [id] *)valstart:t(** [start] is some identifer *)valto_string:t->string(** [to_string id] returns a string describing the identifier *)valpp:Format.formatter->t->unit(** [pp f id] pretty prints the id [id] on the formatter [f] *)end(** 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}exceptionCT_Not_foundletempty={symbols=Tries.Tries.empty;ids=IdMap.empty;gen=init()}letfind_id_of_symsymbol{symbols=table;ids=_;gen=_}=tryTries.Tries.findsymboltablewithTries.Tries.Not_found->raiseCT_Not_foundletfind_id_of_sym_optsymbol{symbols=table;ids=_;gen=_}=trySome(Tries.Tries.findsymboltable)withTries.Tries.Not_found->Noneletfind_sym_from_idid{symbols=_;ids=table;gen=_}=tryIdMap.findidtablewithNot_found->let()=Log.err(funm->m"id '%s' not found in table."(ID.to_stringid))inraiseCT_Not_foundletadd_symsym({symbols=syms;ids;gen=vargen}astable)=try(Tries.Tries.findsymsyms,table)withTries.Tries.Not_found->letnew_var,new_vargen=get_fresh_idvargenin(new_var,{symbols=Tries.Tries.addsymnew_varsyms;ids=IdMap.addnew_varsymids;gen=new_vargen;})letidmap_ppmmap=IdMap.iter(funkeyvalue->Format.fprintfm"@[%a ->@ %30s@]"ID.ppkeyvalue)mapletppm{symbols=syms;ids;gen=_}=let()=Format.fprintfm"@[Table from symbols to ids:@\n@[<v 3>%a]@]@."(Tries.Tries.pp(funfmtsymid->Format.fprintffmt"%10s -> %a"symID.ppid))symsinFormat.fprintfm"@[Table from symbols to ids:@\n@[<v 3>%a]@]@."idmap_ppidsletfoldftablestart=IdMap.foldftable.idsstartendendmoduleIntId=structtypet=intletcompareij=i-jletsucci=i+1letstart=0letto_string=string_of_intletpp=Format.pp_print_intendmoduleIntIdGen=IdGen(IntId)(** Module implementing the special case where identifiers ar
integers. *)