123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273(************************************************************************)(* * 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()typesubstitutivity=Dispose|Substitute|Keep|Anticipatetypeobject_name=Libnames.full_path*Names.KerName.ttypeopen_filter=|Unfiltered|FilteredofCString.Pred.ttypecategory=stringletknown_cats=refCString.Set.emptyletcreate_categorys=letcats'=CString.Set.adds!known_catsinif!known_cats==cats'thenCErrors.anomalyPp.(str"create_category called twice on "++strs);known_cats:=cats';sletunfiltered=Unfilteredletmake_filter~finitecats=ifCList.is_emptycatsthenCErrors.anomalyPp.(str"Libobject.make_filter got an empty list.");letcats=List.fold_left(funcatsCAst.{v=cat;loc}->ifnot(CString.Set.memcat!known_cats)thenCErrors.user_err?locPp.(str"Unknown import category "++strcat++str".");CString.Pred.addcatcats)CString.Pred.emptycatsinletcats=iffinitethencatselseCString.Pred.complementcatsinFilteredcatsletin_filter~catf=matchcat,fwith|_,Unfiltered->true|None,Filteredf->not(CString.Pred.is_finitef)|Somecat,Filteredf->CString.Pred.memcatfletsimple_open?catffilterio=ifin_filter~catfilterthenfioletfilter_eqf1f2=matchf1,f2with|Unfiltered,Unfiltered->true|Unfiltered,_|_,Unfiltered->false|Filteredf1,Filteredf2->CString.Pred.equalf1f2letfilter_andf1f2=matchf1,f2with|Unfiltered,f|f,Unfiltered->Somef|Filteredf1,Filteredf2->letf=CString.Pred.interf1f2inifCString.Pred.is_emptyfthenNoneelseSome(Filteredf)letfilter_orf1f2=matchf1,f2with|Unfiltered,f|f,Unfiltered->Unfiltered|Filteredf1,Filteredf2->Filtered(CString.Pred.unionf1f2)type('a,'b)object_declaration={object_name:string;object_stage:Summary.Stage.t;cache_function:'b->unit;load_function:int->'b->unit;open_function:open_filter->int->'b->unit;classify_function:'a->substitutivity;subst_function:Mod_subst.substitution*'a->'a;discharge_function:'a->'aoption;rebuild_function:'a->'a;}letdefault_object?(stage=Summary.Stage.Interp)s={object_name=s;object_stage=stage;cache_function=(fun_->());load_function=(fun__->());open_function=(fun___->());subst_function=(fun_->CErrors.anomalyPp.(str"The object "++strs++str" does not know how to substitute!"));classify_function=(fun_->Keep);discharge_function=(fun_->None);rebuild_function=(funx->x);}(* The suggested object declaration is the following:
declare_object { (default_object "MY OBJECT") with
cache_function = fun (sp,a) -> Mytbl.add sp a}
and the listed functions are only those which definitions actually
differ from the default.
This helps introducing new functions in objects.
*)letident_subst_function(_,a)=atypeobj=Dyn.t(* persistent dynamic objects *)(** {6 Substitutive objects}
- The list of bound identifiers is nonempty only if the objects
are owned by a functor
- Then comes either the object segment itself (for interactive
modules), or a compact way to store derived objects (path to
a earlier module + substitution).
*)typealgebraic_objects=|Objsoftlist|RefofNames.ModPath.t*Mod_subst.substitutionandt=|ModuleObjectofNames.Id.t*substitutive_objects|ModuleTypeObjectofNames.Id.t*substitutive_objects|IncludeObjectofalgebraic_objects|KeepObjectofNames.Id.t*tlist|ExportObjectof{mpl:(open_filter*Names.ModPath.t)list}|AtomicObjectofobjandsubstitutive_objects=Names.MBId.tlist*algebraic_objectsmoduleDynMap=Dyn.Map(structtype'at=('a,Nametab.object_prefix*'a)object_declarationend)letcache_tab=refDynMap.emptyletdeclare_object_fullodecl=letna=odecl.object_nameinlettag=Dyn.createnainlet()=cache_tab:=DynMap.addtagodecl!cache_tabintagletmake_onameNametab.{obj_dir;obj_mp}id=Libnames.make_pathobj_dirid,Names.KerName.makeobj_mp(Names.Label.of_idid)letdeclare_named_object_fullodecl=letodecl=letoname=make_onamein{object_name=odecl.object_name;object_stage=odecl.object_stage;cache_function=(fun(p,(id,o))->odecl.cache_function(onamepid,o));load_function=(funi(p,(id,o))->odecl.load_functioni(onamepid,o));open_function=(funfi(p,(id,o))->odecl.open_functionfi(onamepid,o));classify_function=(fun(id,o)->odecl.classify_functiono);subst_function=(fun(subst,(id,o))->id,odecl.subst_function(subst,o));discharge_function=(fun(id,o)->Option.map(funx->id,x)(odecl.discharge_functiono));rebuild_function=Util.on_sndodecl.rebuild_function;}indeclare_object_fullodeclletdeclare_named_objectodecl=lettag=declare_named_object_fullodeclinletinfunidv=Dyn.Dyn(tag,(id,v))ininfunletdeclare_named_object_genodecl=lettag=declare_object_fullodeclinletinfunv=Dyn.Dyn(tag,v)ininfunletdeclare_objectodecl=letodecl={odeclwithcache_function=(fun(_,o)->odecl.cache_functiono);load_function=(funi(_,o)->odecl.load_functionio);open_function=(funfi(_,o)->odecl.open_functionfio);}inlettag=declare_object_fullodeclinletinfunv=Dyn.Dyn(tag,v)ininfunletcache_object(sp,Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabindecl.cache_function(sp,v)letload_objecti(sp,Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabindecl.load_functioni(sp,v)letopen_objectfi(sp,Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabindecl.open_functionfi(sp,v)letsubst_object(subs,Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabinDyn.Dyn(tag,decl.subst_function(subs,v))letclassify_object(Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabinmatchdecl.classify_functionvwith|Dispose->Dispose|Substitute->Substitute|Keep->Keep|Anticipate->Anticipateletdischarge_object(Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabinmatchdecl.discharge_functionvwith|None->None|Somev->Some(Dyn.Dyn(tag,v))letrebuild_object(Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabinDyn.Dyn(tag,decl.rebuild_functionv)letobject_stage(Dyn.Dyn(tag,v))=letdecl=DynMap.findtag!cache_tabindecl.object_stageletdump=Dyn.dumpletlocal_object_nodischarge?stages~cache={(default_object?stages)withcache_function=cache;classify_function=(fun_->Dispose);}letlocal_object?stages~cache~discharge={(local_object_nodischarge?stages~cache)withdischarge_function=discharge;}letglobal_object_nodischarge?cat?stages~cache~subst=letimportio=ifInt.equali1thencacheoin{(default_object?stages)withcache_function=cache;open_function=simple_open?catimport;subst_function=(matchsubstwith|None->fun_->CErrors.anomalyPp.(str"The object "++strs++str" does not know how to substitute!")|Somesubst->subst;);classify_function=ifOption.has_somesubstthen(fun_->Substitute)else(fun_->Keep);}letglobal_object?cat?stages~cache~subst~discharge={(global_object_nodischarge?cats~cache~subst)withdischarge_function=discharge}letsuperglobal_object_nodischarge?stages~cache~subst={(default_object?stages)withload_function=(fun_x->cachex);cache_function=cache;subst_function=(matchsubstwith|None->fun_->CErrors.anomalyPp.(str"The object "++strs++str" does not know how to substitute!")|Somesubst->subst;);classify_function=ifOption.has_somesubstthen(fun_->Substitute)else(fun_->Keep);}letsuperglobal_object?stages~cache~subst~discharge={(superglobal_object_nodischarge?stages~cache~subst)withdischarge_function=discharge}