123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224(************************************************************************)(* * 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) *)(************************************************************************)moduleDyn=Dyn.Make()moduleStage=structtypet=Synterp|Interpletequalxy=matchx,ywith|Synterp,Synterp->true|Synterp,Interp->false|Interp,Interp->true|Interp,Synterp->falseendtype'asummary_declaration={stage:Stage.t;freeze_function:unit->'a;unfreeze_function:'a->unit;init_function:unit->unit}moduleDecl=structtype'at='asummary_declarationendmoduleDynMap=Dyn.Map(Decl)moduleMarshMap=Dyn.Map(structtype'at='a->'aend)typeml_modules=(stringoption*string)listletsum_mod:ml_modulessummary_declarationoptionref=refNoneletsum_map_synterp=refDynMap.emptyletsum_map_interp=refDynMap.emptyletsum_marsh_synterp=refMarshMap.emptyletsum_marsh_interp=refMarshMap.emptyletmangleid=id^"-SUMMARY"letdeclare_ml_modules_summarydecl=sum_mod:=Somedeclletcheck_namesumname=matchDyn.namesumnamewith|None->()|Some(Dyn.Anyt)->CErrors.anomaly~label:"Summary.declare_summary"Pp.(str"Colliding summary names: "++strsumname++str" vs. "++str(Dyn.reprt)++str".")letdeclare_summary_tagsumname?make_marshallabledecl=let()=check_name(manglesumname)inlettag=Dyn.create(manglesumname)inletsum_map,marsh_map=matchdecl.stagewith|Synterp->sum_map_synterp,sum_marsh_synterp|Interp->sum_map_interp,sum_marsh_interpinlet()=sum_map:=DynMap.addtagdecl!sum_mapinlet()=make_marshallable|>Option.iter(funf->marsh_map:=MarshMap.addtagf!marsh_map)intagletdeclare_summarysumname?make_marshallabledecl=ignore(declare_summary_tagsumname?make_marshallabledecl)moduleID=structtype'at='aendmoduleFrozen=Dyn.Map(ID)moduleHMap=Dyn.HMap(Decl)(ID)moduletypeFrozenStage=sig(** The type [frozen] is a snapshot of the states of all the registered
tables of the system. *)typefrozenvalempty_frozen:frozenvalfreeze_summaries:unit->frozenvalmake_marshallable:frozen->frozenvalunfreeze_summaries:?partial:bool->frozen->unitvalinit_summaries:unit->unitvalproject_from_summary:frozen->'aDyn.tag->'aendletfreeze_summariessum_map=letmap={HMap.map=funtagdecl->decl.freeze_function()}inHMap.mapmapsum_mapletmake_marshallablemarsh_mapsummaries=letmap={Frozen.map=funtagv->matchMarshMap.findtagmarsh_mapwith|exceptionNot_found->v|f->fv}inFrozen.mapmapsummariesletwarn_summary_out_of_scope=CWarnings.create~name:"summary-out-of-scope"~default:DisabledPp.(funname->str"A Coq plugin was loaded inside a local scope (such as a Section)."++spc()++str"It is recommended to load plugins at the start of the file."++spc()++str"Summary entry: "++strname)letunfreeze_summaries?(partial=false)sum_mapsummaries=(* We must be independent on the order of the map! *)letufz(DynMap.Any(name,decl))=trydecl.unfreeze_functionFrozen.(findnamesummaries)withNot_found->ifnotpartialthenbeginwarn_summary_out_of_scope(Dyn.reprname);decl.init_function()endinDynMap.iterufzsum_mapletinit_summariessum_map=DynMap.iter(fun(DynMap.Any(_,decl))->decl.init_function())sum_mapmoduleSynterp=structtypefrozen={summaries:Frozen.t;(** Ordered list w.r.t. the first component. *)ml_module:ml_modulesoption;(** Special handling of the ml_module summary. *)}letempty_frozen={summaries=Frozen.empty;ml_module=None}letfreeze_summaries()=letsummaries=freeze_summaries!sum_map_synterpin{summaries;ml_module=Option.map(fundecl->decl.freeze_function())!sum_mod}letmake_marshallable{summaries;ml_module}={summaries=make_marshallable!sum_marsh_synterpsummaries;ml_module}letunfreeze_summaries?(partial=false){summaries;ml_module}=(* The unfreezing of [ml_modules_summary] has to be anticipated since it
* may modify the content of [summaries] by loading new ML modules *)beginmatch!sum_modwith|None->CErrors.anomalyPp.(str"Undeclared ML-MODULES summary.")|Somedecl->Option.iterdecl.unfreeze_functionml_moduleend;unfreeze_summaries~partial!sum_map_synterpsummariesletinit_summaries()=init_summaries!sum_map_synterp(** Summary projection *)letproject_from_summary{summaries;_}tag=Frozen.findtagsummariesendmoduleInterp=structtypefrozen=Frozen.tletempty_frozen=Frozen.emptyletfreeze_summaries()=freeze_summaries!sum_map_interpletmake_marshallablesummaries=make_marshallable!sum_marsh_interpsummariesletunfreeze_summaries?(partial=false)summaries=unfreeze_summaries~partial!sum_map_interpsummariesletinit_summaries()=init_summaries!sum_map_interp(** Summary projection *)letproject_from_summarysummariestag=Frozen.findtagsummariesletmodify_summarysummariestagv=let()=assert(Frozen.memtagsummaries)inFrozen.addtagvsummariesletremove_from_summarysummariestag=let()=assert(Frozen.memtagsummaries)inFrozen.removetagsummariesend(** For global tables registered statically before the end of coqtop
launch, the following empty [init_function] could be used. *)letnop()=()(** All-in-one reference declaration + registration *)letref_tag?(stage=Stage.Interp)~namex=letr=refxinlettag=declare_summary_tagname{stage;freeze_function=(fun()->!r);unfreeze_function=((:=)r);init_function=(fun()->r:=x)}inr,tagletref?(stage=Stage.Interp)?(local=false)~namex=ifnotlocalthenfst@@ref_tag~stage~namexelseletr=refxinlet()=declare_summaryname~make_marshallable:(fun_->None){stage;freeze_function=(fun()->Some!r);unfreeze_function=(functionSomev->r:=v|None->r:=x);init_function=(fun()->r:=x);}inrletdump=Dyn.dump