123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489(************************************************************************)(* * 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) *)(************************************************************************)(************************************************************************)(* SerAPI: Coq interaction protocol with bidirectional serialization *)(************************************************************************)(* Copyright 2016-2019 MINES ParisTech -- License LGPL 2.1+ *)(* Copyright 2019-2023 Inria -- License LGPL 2.1+ *)(* Written by: Emilio J. Gallego Arias and others *)(************************************************************************)openSexplibopenPpx_hash_lib.StdopenPpx_compare_lib.Builtinlethash_taggedfsttagx=letst=Hash.fold_stringsttaginfstxlethash_pairf1f2st(x1,x2)=letst=f1stx1inf2stx2(**********************************************************************)(* GenArg *)(**********************************************************************)openGenargtyperlevel=[%import:Genarg.rlevel][@@derivingsexp,yojson,hash,compare]typeglevel=[%import:Genarg.glevel][@@derivingsexp,yojson,hash,compare]typetlevel=[%import:Genarg.tlevel][@@derivingsexp,yojson,hash,compare]letsexp_of_genarg_tagtag:Sexp.t=Atom(ArgT.reprtag)letrecsexp_of_genarg_type:typeabc.(a,b,c)genarg_type->Sexp.t=fungt->matchgtwith|ExtraArgtag->List[Atom"ExtraArg";sexp_of_genarg_tagtag]|ListArgrt->List[Atom"ListArg";sexp_of_genarg_typert]|OptArgrt->List[Atom"OptArg";sexp_of_genarg_typert]|PairArg(t1,t2)->List[Atom"PairArg";sexp_of_genarg_typet1;sexp_of_genarg_typet2]letrechash_fold_genarg_type:typeabc.(a,b,c)genarg_typeHash.folder=funstgt->matchgtwith|ExtraArgtag->hash_taggedHash.fold_stringst"ExtraArg"(ArgT.reprtag)|ListArgrt->hash_taggedhash_fold_genarg_typest"ListArg"rt|OptArgrt->hash_taggedhash_fold_genarg_typest"OptArg"rt|PairArg(t1,t2)->hash_tagged(hash_pairhash_fold_genarg_typehash_fold_genarg_type)st"PairArg"(t1,t2)letsexp_of_abstract_argument_type:typelvl.('o,lvl)abstract_argument_type->Sexp.t=funat->matchatwith|Rawwitw->List[Atom"Rawwit";sexp_of_genarg_typew]|Glbwitw->List[Atom"Glbwit";sexp_of_genarg_typew]|Topwitw->List[Atom"Topwit";sexp_of_genarg_typew]letrecargument_type_of_sexp:Sexp.t->argument_type=funsexp->matchsexpwith|List[Atom"ExtraArg";Atomtag]->beginmatchArgT.nametagwith|None->letmsg=Format.asprintf"argument_type %s not registered, this is usually due to a missing serlib plugin"taginraise(Failuremsg)|Some(ArgT.Anyt)->ArgumentType(ExtraArgt)end|List[Atom"ListArg";s1]->let(ArgumentTypet)=argument_type_of_sexps1inArgumentType(ListArgt)|List[Atom"OptArg";s1]->let(ArgumentTypet)=argument_type_of_sexps1inArgumentType(OptArgt)|List[Atom"PairArg";s1;s2]->let(ArgumentTypet1)=argument_type_of_sexps1inlet(ArgumentTypet2)=argument_type_of_sexps2inArgumentType(PairArg(t1,t2))|_->raise(Failure"SEXP Exception")lethash_fold_abstract_argument_type:typelvl.('o,lvl)abstract_argument_typeHash.folder=funstat->matchatwith|Rawwitw->hash_taggedhash_fold_genarg_typest"raw"w|Glbwitw->hash_taggedhash_fold_genarg_typest"glb"w|Topwitw->hash_taggedhash_fold_genarg_typest"top"wtype('raw,'glb,'top)gen_ser={raw_ser:'raw->Sexp.t;raw_des:Sexp.t->'raw;raw_hash:'rawHash.folder;raw_compare:'raw->'raw->int;glb_ser:'glb->Sexp.t;glb_des:Sexp.t->'glb;glb_hash:'glbHash.folder;glb_compare:'glb->'glb->int;top_ser:'top->Sexp.t;top_des:Sexp.t->'top;top_hash:'topPpx_hash_lib.Std.Hash.folder;top_compare:'top->'top->int}moduleT2_=structtype('a,'b)t='a*'b[@@derivinghash,compare]endletgen_ser_list:('raw,'glb,'top)gen_ser->('rawlist,'glblist,'toplist)gen_ser=fung->letopenSexplib.Convin{raw_ser=sexp_of_listg.raw_ser;raw_des=list_of_sexpg.raw_des;raw_hash=Hash.Builtin.hash_fold_listg.raw_hash;raw_compare=compare_listg.raw_compare;glb_ser=sexp_of_listg.glb_ser;glb_des=list_of_sexpg.glb_des;glb_hash=Hash.Builtin.hash_fold_listg.glb_hash;glb_compare=compare_listg.glb_compare;top_ser=sexp_of_listg.top_ser;top_des=list_of_sexpg.top_des;top_hash=Hash.Builtin.hash_fold_listg.top_hash;top_compare=compare_listg.top_compare}letgen_ser_opt:('raw,'glb,'top)gen_ser->('rawoption,'glboption,'topoption)gen_ser=fung->letopenSexplib.Convin{raw_ser=sexp_of_optiong.raw_ser;raw_des=option_of_sexpg.raw_des;raw_hash=Hash.Builtin.hash_fold_optiong.raw_hash;raw_compare=compare_optiong.raw_compare;glb_ser=sexp_of_optiong.glb_ser;glb_des=option_of_sexpg.glb_des;glb_hash=Hash.Builtin.hash_fold_optiong.glb_hash;glb_compare=compare_optiong.glb_compare;top_ser=sexp_of_optiong.top_ser;top_des=option_of_sexpg.top_des;top_hash=Hash.Builtin.hash_fold_optiong.top_hash;top_compare=compare_optiong.top_compare}letgen_ser_pair:('raw1,'glb1,'top1)gen_ser->('raw2,'glb2,'top2)gen_ser->(('raw1*'raw2),('glb1*'glb2),('top1*'top2))gen_ser=fung1g2->letopenSexplib.Convin{raw_ser=sexp_of_pairg1.raw_serg2.raw_ser;raw_des=pair_of_sexpg1.raw_desg2.raw_des;raw_hash=T2_.hash_fold_tg1.raw_hashg2.raw_hash;raw_compare=T2_.compareg1.raw_compareg2.raw_compare;glb_ser=sexp_of_pairg1.glb_serg2.glb_ser;glb_des=pair_of_sexpg1.glb_desg2.glb_des;glb_hash=T2_.hash_fold_tg1.glb_hashg2.glb_hash;glb_compare=T2_.compareg1.glb_compareg2.glb_compare;top_ser=sexp_of_pairg1.top_serg2.top_ser;top_des=pair_of_sexpg1.top_desg2.top_des;top_hash=T2_.hash_fold_tg1.top_hashg2.top_hash;top_compare=T2_.compareg1.top_compareg2.top_compare}moduleSerObj=structtype('raw,'glb,'top)obj=('raw,'glb,'top)gen_serletname="ser_arg"letsexp_of_gentypga=lettyp=typ^": "^Sexp.to_string(sexp_of_genarg_tagga)inSerlib_base.sexp_of_opaque~typletdefault_ga=Some{(* raw_ser = (fun _ -> Sexp.(List [Atom "[XXX ser_gen]"; Atom "raw"; sexp_of_genarg_typega])); *)raw_ser=sexp_of_gen"raw"_ga;raw_des=(Sexplib.Conv_error.no_matching_variant_found"raw_arg");raw_hash=(funsta->Hash.fold_intst(Hashtbl.hasha));raw_compare=Stdlib.compare(* glb_ser = (fun _ -> Sexp.(List [Atom "[XXX ser_gen]"; Atom "glb"; sexp_of_genarg_type ga])); *);glb_ser=sexp_of_gen"glb"_ga;glb_des=(Sexplib.Conv_error.no_matching_variant_found"glb_arg");glb_hash=(funsta->Hash.fold_intst(Hashtbl.hasha));glb_compare=Stdlib.compare(* top_ser = (fun _ -> Sexp.(List [Atom "[XXX ser_gen]"; Atom "top"; sexp_of_genarg_type ga])); *);top_ser=sexp_of_gen"top"_ga;top_des=(Sexplib.Conv_error.no_matching_variant_found"top_arg");top_hash=(funsta->Hash.fold_intst(Hashtbl.hasha));top_compare=Stdlib.compare}endmoduleSerGen=Register(SerObj)letregister_gensertyobj=SerGen.register0tyobjletrecget_gen_ser_ty:typergt.(r,g,t)Genarg.genarg_type->(r,g,t)gen_ser=fungt->matchgtwith|Genarg.ExtraArg_->SerGen.objgt|Genarg.ListArgt->gen_ser_list(get_gen_ser_tyt)|Genarg.OptArgt->gen_ser_opt(get_gen_ser_tyt)|Genarg.PairArg(t1,t2)->gen_ser_pair(get_gen_ser_tyt1)(get_gen_ser_tyt2)letget_gen_ser:typelvl.('o,lvl)abstract_argument_type->('o->'t)=funaty->matchatywith|Genarg.Rawwitty->(get_gen_ser_tyty).raw_ser|Genarg.Glbwitty->(get_gen_ser_tyty).glb_ser|Genarg.Topwitty->(get_gen_ser_tyty).top_serletgeneric_des:typelvl.('o,lvl)abstract_argument_type->Sexp.t->lvlgeneric_argument=funtys->matchtywith|Genarg.Rawwitw->GenArg(ty,(get_gen_ser_tyw).raw_dess)|Genarg.Glbwitw->GenArg(ty,(get_gen_ser_tyw).glb_dess)|Genarg.Topwitw->GenArg(ty,(get_gen_ser_tyw).top_dess)lethash_fold_generic:typelvl.('o,lvl)abstract_argument_type->'oPpx_hash_lib.Std.Hash.folder=funaty->matchatywith|Genarg.Rawwitty->(get_gen_ser_tyty).raw_hash|Genarg.Glbwitty->(get_gen_ser_tyty).glb_hash|Genarg.Topwitty->(get_gen_ser_tyty).top_hashletcompare_generic:typelvl.('o,lvl)abstract_argument_type->'oPpx_compare_lib.compare=funaty->matchatywith|Genarg.Rawwitty->(get_gen_ser_tyty).raw_compare|Genarg.Glbwitty->(get_gen_ser_tyty).glb_compare|Genarg.Topwitty->(get_gen_ser_tyty).top_compare(* We need to generalize this to use the proper printers for opt *)letmk_sexpargstso=Sexp.List[Atom"GenArg";st;so](* XXX: There is still some duplication here in the traversal of g_ty, but
we can live with that for now. *)letsexp_of_genarg_val:typea.ageneric_argument->Sexp.t=fung->matchgwith|GenArg(g_ty,g_val)->mk_sexparg(sexp_of_abstract_argument_typeg_ty)(get_gen_serg_tyg_val)letsexp_of_generic_argument:typea.(a->Sexp.t)->ageneric_argument->Sexp.t=fun_level_tagg->sexp_of_genarg_valgtypergen_argument=RG:'lvlgeneric_argument->rgen_argumentlethash_fold_genarg_val:typea.ageneric_argumentHash.folder=funstg->matchgwith|GenArg(g_ty,g_val)->letst=hash_fold_abstract_argument_typestg_tyinhash_fold_genericg_tystg_vallethash_fold_generic_argument:typea.aHash.folder->ageneric_argumentHash.folder=fun_level_tagg->hash_fold_genarg_valgletcompare_genarg_val:typea.ageneric_argumentPpx_compare_lib.compare=fung1g2->matchg1with|GenArg(g1_ty,g1_val)->matchg2with|GenArg(g2_ty,g2_val)->matchGenarg.abstract_argument_type_eqg1_tyg2_tywith|SomeRefl->compare_genericg1_tyg1_valg2_val(* XXX: Technically, we should implement our own compare so ordering works *)|None->1letcompare_generic_argument:typea.aPpx_compare_lib.compare->ageneric_argumentPpx_compare_lib.compare=fun_level_tagg->compare_genarg_valgletgen_abstype_of_sexp:Sexp.t->rgen_argument=funs->matchswith|List[Atom"GenArg";List[Atom"Rawwit";sty];sobj]->let(ArgumentTypety)=argument_type_of_sexpstyinRG(generic_des(Rawwitty)sobj)|List[Atom"GenArg";List[Atom"Glbwit";sty];sobj]->let(ArgumentTypety)=argument_type_of_sexpstyinRG(generic_des(Glbwitty)sobj)|List[Atom"GenArg";List[Atom"Topwit";sty];sobj]->let(ArgumentTypety)=argument_type_of_sexpstyinRG(generic_des(Topwitty)sobj)|_->raise(Failure"SEXP Exception in abstype")letgeneric_argument_of_sexp_lvlsexp:'aGenarg.generic_argument=let(RGga)=gen_abstype_of_sexpsexpinObj.magicgaletrecyojson_to_sexpjson=matchjsonwith|`Strings->Sexp.Atoms|`Lists->Sexp.List(List.mapyojson_to_sexps)|_->raise(Failure"ser_genarg: yojson_to_sexp")letrecsexp_to_yojsonsexp:Yojson.Safe.t=matchsexpwith|Sexp.Atoms->`Strings|Listl->`List(List.mapsexp_to_yojsonl)letgeneric_argument_of_yojsonlvljson=letsexp=yojson_to_sexpjsoninResult.Ok(generic_argument_of_sexplvlsexp)letgeneric_argument_to_yojson:typea.(a->Yojson.Safe.t)->ageneric_argument->Yojson.Safe.t=fun_level_tagg->sexp_of_generic_argument(fun_->Atom"")g|>sexp_to_yojsontype'ageneric_argument='aGenarg.generic_argumenttypeglob_generic_argument=[%import:Genarg.glob_generic_argument][@@derivingsexp,yojson,hash,compare]typeraw_generic_argument=[%import:Genarg.raw_generic_argument][@@derivingsexp,yojson,hash,compare]typetyped_generic_argument=[%import:Genarg.typed_generic_argument][@@derivingsexp,yojson,hash,compare]letmk_uniformpinpoutphashpcompare={raw_ser=pin;raw_des=pout;raw_hash=phash;raw_compare=pcompare;glb_ser=pin;glb_des=pout;glb_hash=phash;glb_compare=pcompare;top_ser=pin;top_des=pout;top_hash=phash;top_compare=pcompare}letmk_vernac_argpinpoutphashpcompare={raw_ser=pin;raw_des=pout;raw_hash=phash;raw_compare=pcompare;glb_ser=Ser_util.Empty.sexp_of_t;glb_des=Ser_util.Empty.t_of_sexp;glb_hash=Ser_util.Empty.hash_fold_t;glb_compare=Ser_util.Empty.compare;top_ser=Ser_util.Empty.sexp_of_t;top_des=Ser_util.Empty.t_of_sexp;top_hash=Ser_util.Empty.hash_fold_t;top_compare=Ser_util.Empty.compare}moduletypeGenSer0=sigtypet[@@derivingsexp,hash,compare]endmoduleGS0(M:GenSer0)=structletgenser=mk_uniformM.sexp_of_tM.t_of_sexpM.hash_fold_tM.compareendmoduleGSV(M:GenSer0)=structletgenser=mk_vernac_argM.sexp_of_tM.t_of_sexpM.hash_fold_tM.compareendmoduletypeGenSer=sigtyperaw[@@derivingsexp,hash,compare]typeglb[@@derivingsexp,hash,compare]typetop[@@derivingsexp,hash,compare]endmoduleGS(M:GenSer)=structletgenser={raw_ser=M.sexp_of_raw;raw_des=M.raw_of_sexp;raw_hash=M.hash_fold_raw;raw_compare=M.compare_raw;glb_ser=M.sexp_of_glb;glb_des=M.glb_of_sexp;glb_hash=M.hash_fold_glb;glb_compare=M.compare_glb;top_ser=M.sexp_of_top;top_des=M.top_of_sexp;top_hash=M.hash_fold_top;top_compare=M.compare_top}end(* Type for Rocq Ast Analyzers and Synthetizers *)moduletypeRType=sig(** Type and name of the analysis result *)typeavalname:string(** Default value. This is called for generic arguments not
registered via a plugin. If [None], Rocq will emit an anomaly
when a non-registered generic argument is found. The argument is
the name of the non-handled generic argument. *)valdefault:string->aoption(** Combine results of analysis, for standard genarg types *)valfold_list:alist->avalfold_option:aoption->avalfold_pair:a*a->aend(* Ast analizers, Ast -> a *)moduleAnalyzer=structmoduleMake(A:RType):sigtype('raw,'glb,'top)t={raw:'raw->A.a;glb:'glb->A.a;top:'top->A.a}valregister:('raw,'glb,'top)Genarg.genarg_type->('raw,'glb,'top)t->unitvalanalyze:'aGenarg.generic_argument->A.aend=structtype('raw,'glb,'top)t={raw:'raw->A.a;glb:'glb->A.a;top:'top->A.a}moduleObj=structtype('raw,'glb,'top)obj=('raw,'glb,'top)tletname=A.nameletdefaulttag=matchA.default(Genarg.ArgT.reprtag)with|None->None|Somedft->letraw_=dftinletglb_=dftinlettop_=dftinSome{raw;glb;top}endmoduleGenAnalyzer=Genarg.Register(Obj)letregistertaganalyzer=GenAnalyzer.register0taganalyzerletlist_analyzef=letrawr=List.mapf.rawr|>A.fold_listinletglbr=List.mapf.glbr|>A.fold_listinlettopr=List.mapf.topr|>A.fold_listin{raw;glb;top}letoption_analyzef=letrawr=Option.mapf.rawr|>A.fold_optioninletglbr=Option.mapf.glbr|>A.fold_optioninlettopr=Option.mapf.topr|>A.fold_optionin{raw;glb;top}letpair_analyze(f1,f2)=letraw(r1,r2)=(f1.rawr1,f2.rawr2)|>A.fold_pairinletglb(r1,r2)=(f1.glbr1,f2.glbr2)|>A.fold_pairinlettop(r1,r2)=(f1.topr1,f2.topr2)|>A.fold_pairin{raw;glb;top}letrecget_analyzer:typerawglbtop.(raw,glb,top)genarg_type->(raw,glb,top)t=fungt->matchgtwith|ExtraArg_tag->GenAnalyzer.objgt|ListArgty->get_analyzerty|>list_analyze|OptArgty->get_analyzerty|>option_analyze|PairArg(ty1,ty2)->(get_analyzerty1,get_analyzerty2)|>pair_analyzeletanalyze_generic:typelvl.('o,lvl)abstract_argument_type->'o->A.a=funaty->matchatywith|Genarg.Rawwitty->(get_analyzerty).raw|Genarg.Glbwitty->(get_analyzerty).glb|Genarg.Topwitty->(get_analyzerty).topletanalyze:typea.ageneric_argument->A.a=functionGenArg(g_ty,g_val)->analyze_genericg_tyg_valendend