123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213(************************************************************************)(* * 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) *)(************************************************************************)openPpopenUtilmoduleArgT=structmoduleDYN=Dyn.Make()moduleMap=DYN.Maptype('a,'b,'c)tag=('a*'b*'c)DYN.tagtypeany=Any:('a,'b,'c)tag->anyleteq=DYN.eqletrepr=DYN.reprletcreate=DYN.createletdump=DYN.dumpletnames=matchDYN.nameswith|None->None|Some(DYN.Anyt)->Some(Any(Obj.magict))(** All created tags are made of triples *)endtype(_,_,_)genarg_type=|ExtraArg:('a,'b,'c)ArgT.tag->('a,'b,'c)genarg_type|ListArg:('a,'b,'c)genarg_type->('alist,'blist,'clist)genarg_type|OptArg:('a,'b,'c)genarg_type->('aoption,'boption,'coption)genarg_type|PairArg:('a1,'b1,'c1)genarg_type*('a2,'b2,'c2)genarg_type->('a1*'a2,'b1*'b2,'c1*'c2)genarg_typetypeargument_type=ArgumentType:('a,'b,'c)genarg_type->argument_typeletrecgenarg_type_eq:typea1a2b1b2c1c2.(a1,b1,c1)genarg_type->(a2,b2,c2)genarg_type->(a1*b1*c1,a2*b2*c2)CSig.eqoption=funt1t2->matcht1,t2with|ExtraArgt1,ExtraArgt2->ArgT.eqt1t2|ListArgt1,ListArgt2->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->SomeReflend|OptArgt1,OptArgt2->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->SomeReflend|PairArg(t1,u1),PairArg(t2,u2)->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->matchgenarg_type_equ1u2with|None->None|SomeRefl->SomeReflend|_->Noneletrecpr_genarg_type:typeabc.(a,b,c)genarg_type->Pp.t=function|ListArgt->pr_genarg_typet++spc()++str"list"|OptArgt->pr_genarg_typet++spc()++str"opt"|PairArg(t1,t2)->str"("++pr_genarg_typet1++spc()++str"*"++spc()++pr_genarg_typet2++str")"|ExtraArgs->str(ArgT.reprs)letargument_type_eqarg1arg2=matcharg1,arg2with|ArgumentTypet1,ArgumentTypet2->matchgenarg_type_eqt1t2with|None->false|SomeRefl->trueletpr_argument_type(ArgumentTypet)=pr_genarg_typettype'auniform_genarg_type=('a,'a,'a)genarg_type(** Alias for concision *)(* Dynamics but tagged by a type expression *)typerlevel=[`rlevel]typeglevel=[`glevel]typetlevel=[`tlevel]type(_,_)abstract_argument_type=|Rawwit:('a,'b,'c)genarg_type->('a,rlevel)abstract_argument_type|Glbwit:('a,'b,'c)genarg_type->('b,glevel)abstract_argument_type|Topwit:('a,'b,'c)genarg_type->('c,tlevel)abstract_argument_typetype'lgeneric_argument=GenArg:('a,'l)abstract_argument_type*'a->'lgeneric_argumenttyperaw_generic_argument=rlevelgeneric_argumenttypeglob_generic_argument=glevelgeneric_argumenttypetyped_generic_argument=tlevelgeneric_argumentletrawwitt=Rawwittletglbwitt=Glbwittlettopwitt=Topwittletwit_listt=ListArgtletwit_optt=OptArgtletwit_pairt1t2=PairArg(t1,t2)letin_gento=GenArg(t,o)letabstract_argument_type_eq:typeabl.(a,l)abstract_argument_type->(b,l)abstract_argument_type->(a,b)CSig.eqoption=funt1t2->matcht1,t2with|Rawwitt1,Rawwitt2->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->SomeReflend|Glbwitt1,Glbwitt2->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->SomeReflend|Topwitt1,Topwitt2->beginmatchgenarg_type_eqt1t2with|None->None|SomeRefl->SomeReflendletout_gen(typea)(typel)(t:(a,l)abstract_argument_type)(o:lgeneric_argument):a=letGenArg(t',v)=oinmatchabstract_argument_type_eqtt'with|None->failwith"out_gen"|SomeRefl->vlethas_type(GenArg(t,v))u=matchabstract_argument_type_eqtuwith|None->false|Some_->trueletunquote:typel.(_,l)abstract_argument_type->_=function|Rawwitt->ArgumentTypet|Glbwitt->ArgumentTypet|Topwitt->ArgumentTypetletgenarg_tag(GenArg(t,_))=unquotettype'araw_abstract_argument_type=('a,rlevel)abstract_argument_typetype'aglob_abstract_argument_type=('a,glevel)abstract_argument_typetype'atyped_abstract_argument_type=('a,tlevel)abstract_argument_type(** Creating args *)moduletypeParam=sigtype('raw,'glb,'top)tendmoduleArgMap(M:Param)=structtype_pack=Pack:('raw,'glb,'top)M.t->('raw*'glb*'top)packincludeArgT.Map(structtype'at='apackend)endletcreate_argname=matchArgT.namenamewith|None->ExtraArg(ArgT.createname)|Some_->CErrors.anomaly(str"generic argument already declared: "++strname++str".")letmake0=create_arg(** Registering genarg-manipulating functions *)moduletypeGenObj=sigtype('raw,'glb,'top)objvalname:stringvaldefault:('raw,'glb,'top)genarg_type->('raw,'glb,'top)objoptionendletget_arg_tag=function|ExtraArgs->s|_->assertfalsemoduleRegister(M:GenObj)=structmoduleGenMap=ArgMap(structtype('r,'g,'t)t=('r,'g,'t)M.objend)letarg0_map=refGenMap.emptyletregister0argf=lets=get_arg_tagarginifGenMap.mems!arg0_mapthenletmsg=strM.name++str" function already registered: "++str(ArgT.reprs)++str"."inCErrors.anomalymsgelsearg0_map:=GenMap.adds(GenMap.Packf)!arg0_mapletget_obj0name=tryletGenMap.Packobj=GenMap.findname!arg0_mapinobjwithNot_found->matchM.default(ExtraArgname)with|None->CErrors.anomaly(strM.name++str" function not found: "++str(ArgT.reprname)++str".")|Someobj->obj(** For now, the following function is quite dummy and should only be applied
to an extra argument type, otherwise, it will badly fail. *)letobjt=get_obj0@@get_arg_tagt(** NB: we need the [Pack] pattern to get [tag]
from [_ ArgT.DYN.tag] to [(_ * _ * _) ArgT.DYN.tag] *)letfold_keysfacc=GenMap.fold(fun(Any(tag,Pack_))acc->f(ArgT.Anytag)acc)!arg0_mapaccend