123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879(************************************************************************)(* * 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) *)(************************************************************************)openNamesopenModPathopenTermopenDeclarationsopenNamegenopenLibobjectopenGoptionsopenLibnamesopenGlobnamesopenCErrorsopenUtilopenPpopenMiniml(** Sets and maps for [global_reference] that use the "user" [kernel_name]
instead of the canonical one *)moduleRefmap'=GlobRef.Map_envmoduleRefset'=GlobRef.Set_env(*S Utilities about [module_path] and [kernel_names] and [global_reference] *)letoccur_kn_in_refkn=letopenGlobRefinfunction|IndRef(kn',_)|ConstructRef((kn',_),_)->MutInd.CanOrd.equalknkn'|ConstRef_|VarRef_->false(* Return the "canonical" name used for declaring a name *)letrepr_of_r=letopenGlobRefinfunction|ConstRefkn->Constant.userkn|IndRef(kn,_)|ConstructRef((kn,_),_)->MutInd.userkn|VarRefv->Lib.make_knvletmodpath_of_rr=KerName.modpath(repr_of_rr)letlabel_of_rr=KerName.label(repr_of_rr)letrecbase_mp=function|MPdot(mp,l)->base_mpmp|mp->mpletis_modfile=function|MPfile_->true|_->falseletraw_string_of_modfile=function|MPfilef->String.capitalize_ascii(Id.to_string(List.hd(DirPath.reprf)))|_->assertfalseletis_toplevelmp=ModPath.equalmpModPath.initial||ModPath.equalmp(Lib.current_mp())letat_toplevelmp=is_modfilemp||is_toplevelmpletmp_lengthmp=letmp0=Lib.current_mp()inletreclen=function|mpwhenModPath.equalmpmp0->1|MPdot(mp,_)->1+lenmp|_->1inlenmpletrecprefixes_mpmp=matchmpwith|MPdot(mp',_)->MPset.addmp(prefixes_mpmp')|_->MPset.singletonmpletrecget_nth_label_mpn=function|MPdot(mp,l)->ifInt.equaln1thenlelseget_nth_label_mp(n-1)mp|_->failwith"get_nth_label: not enough MPdot"letcommon_prefix_from_listmp0mpl=letprefixes=prefixes_mpmp0inletrecf=function|[]->None|mp::l->ifMPset.memmpprefixesthenSomempelseflinfmplletrecparse_labels2llmp1=function|mpwhenModPath.equalmp1mp->mp,ll|MPdot(mp,l)->parse_labels2(l::ll)mp1mp|mp->mp,llletlabels_of_refr=letmp_top=Lib.current_mp()inletmp,l=KerName.repr(repr_of_rr)inparse_labels2[l]mp_topmp(*S The main tables: constants, inductives, records, ... *)(* These tables are not registered within coq save/undo mechanism
since we reset their contents at each run of Extraction *)(* We use [constant_body] (resp. [mutual_inductive_body]) as checksum
to ensure that the table contents aren't outdated. *)(*s Constants tables. *)lettypedefs=ref(Cmap_env.empty:(constant_body*ml_type)Cmap_env.t)letinit_typedefs()=typedefs:=Cmap_env.emptyletadd_typedefkncbt=typedefs:=Cmap_env.addkn(cb,t)!typedefsletlookup_typedefkncb=trylet(cb0,t)=Cmap_env.findkn!typedefsinifcb0==cbthenSometelseNonewithNot_found->Noneletcst_types=ref(Cmap_env.empty:(constant_body*ml_schema)Cmap_env.t)letinit_cst_types()=cst_types:=Cmap_env.emptyletadd_cst_typekncbs=cst_types:=Cmap_env.addkn(cb,s)!cst_typesletlookup_cst_typekncb=trylet(cb0,s)=Cmap_env.findkn!cst_typesinifcb0==cbthenSomeselseNonewithNot_found->None(*s Inductives table. *)letinductives=ref(Mindmap_env.empty:(mutual_inductive_body*ml_ind)Mindmap_env.t)letinit_inductives()=inductives:=Mindmap_env.emptyletadd_indknmibml_ind=inductives:=Mindmap_env.addkn(mib,ml_ind)!inductivesletlookup_indknmib=trylet(mib0,ml_ind)=Mindmap_env.findkn!inductivesinifmib==mib0thenSomeml_indelseNonewithNot_found->Noneletunsafe_lookup_indkn=snd(Mindmap_env.findkn!inductives)letinductive_kinds=ref(Mindmap_env.empty:inductive_kindMindmap_env.t)letinit_inductive_kinds()=inductive_kinds:=Mindmap_env.emptyletadd_inductive_kindknk=inductive_kinds:=Mindmap_env.addknk!inductive_kindsletis_coinductiver=letkn=letopenGlobRefinmatchrwith|ConstructRef((kn,_),_)->kn|IndRef(kn,_)->kn|_->assertfalseintryMindmap_env.findkn!inductive_kinds==CoinductivewithNot_found->falseletis_coinductive_type=function|Tglob(r,_)->is_coinductiver|_->falseletget_record_fieldsr=letkn=letopenGlobRefinmatchrwith|ConstructRef((kn,_),_)->kn|IndRef(kn,_)->kn|_->assertfalseintrymatchMindmap_env.findkn!inductive_kindswith|Recordf->f|_->[]withNot_found->[]letrecord_fields_of_type=function|Tglob(r,_)->get_record_fieldsr|_->[](*s Recursors table. *)(* NB: here we can use the equivalence between canonical
and user constant names. *)letrecursors=refKNset.emptyletinit_recursors()=recursors:=KNset.emptyletadd_recursorsenvind=letkn=MutInd.canonicalindinletmk_knid=KerName.make(KerName.modpathkn)(Label.of_idid)inletmib=Environ.lookup_mindindenvinArray.iter(funmip->letid=mip.mind_typenameinletkn_rec=mk_kn(Nameops.add_suffixid"_rec")andkn_rect=mk_kn(Nameops.add_suffixid"_rect")inrecursors:=KNset.addkn_rec(KNset.addkn_rect!recursors))mib.mind_packetsletis_recursor=function|GlobRef.ConstRefc->KNset.mem(Constant.canonicalc)!recursors|_->false(*s Record tables. *)(* NB: here, working modulo name equivalence is ok *)letprojs=ref(GlobRef.Map.empty:(inductive*int)GlobRef.Map.t)letinit_projs()=projs:=GlobRef.Map.emptyletadd_projectionnknip=projs:=GlobRef.Map.add(GlobRef.ConstRefkn)(ip,n)!projsletis_projectionr=GlobRef.Map.memr!projsletprojection_arityr=snd(GlobRef.Map.findr!projs)letprojection_infor=GlobRef.Map.findr!projs(*s Table of used axioms *)letinfo_axioms=refRefset'.emptyletlog_axioms=refRefset'.emptyletinit_axioms()=info_axioms:=Refset'.empty;log_axioms:=Refset'.emptyletadd_info_axiomr=info_axioms:=Refset'.addr!info_axiomsletremove_info_axiomr=info_axioms:=Refset'.remover!info_axiomsletadd_log_axiomr=log_axioms:=Refset'.addr!log_axiomsletopaques=refRefset'.emptyletinit_opaques()=opaques:=Refset'.emptyletadd_opaquer=opaques:=Refset'.addr!opaquesletremove_opaquer=opaques:=Refset'.remover!opaques(*s Extraction modes: modular or monolithic, library or minimal ?
Nota:
- Recursive Extraction : monolithic, minimal
- Separate Extraction : modular, minimal
- Extraction Library : modular, library
*)letmodular_ref=reffalseletlibrary_ref=reffalseletset_modularb=modular_ref:=bletmodular()=!modular_refletset_libraryb=library_ref:=bletlibrary()=!library_refletextrcompute=reffalseletset_extrcomputeb=extrcompute:=bletis_extrcompute()=!extrcompute(*s Printing. *)(* The following functions work even on objects not in [Global.env ()].
Warning: for inductive objects, this only works if an [extract_inductive]
have been done earlier, otherwise we can only ask the Nametab about
currently visible objects. *)letsafe_basename_of_globalr=letlast_chancer=tryNametab.basename_of_globalrwithNot_found->anomaly(Pp.str"Inductive object unknown to extraction and not globally visible.")inletopenGlobRefinmatchrwith|ConstRefkn->Label.to_id(Constant.labelkn)|IndRef(kn,0)->Label.to_id(MutInd.labelkn)|IndRef(kn,i)->(try(unsafe_lookup_indkn).ind_packets.(i).ip_typenamewithNot_found->last_chancer)|ConstructRef((kn,i),j)->(try(unsafe_lookup_indkn).ind_packets.(i).ip_consnames.(j-1)withNot_found->last_chancer)|VarRefv->vletstring_of_globalr=trystring_of_qualid(Nametab.shortest_qualid_of_globalId.Set.emptyr)withNot_found->Id.to_string(safe_basename_of_globalr)letsafe_pr_globalr=str(string_of_globalr)(* idem, but with qualification, and only for constants. *)letsafe_pr_long_globalr=tryPrinter.pr_globalrwithNot_found->matchrwith|GlobRef.ConstRefkn->letmp,l=KerName.repr(Constant.userkn)instr((ModPath.to_stringmp)^"."^(Label.to_stringl))|_->assertfalseletpr_long_mpmp=letlid=DirPath.repr(Nametab.dirpath_of_modulemp)instr(String.concat"."(List.rev_mapId.to_stringlid))letpr_long_globalref=pr_path(Nametab.path_of_globalref)(*S Warning and Error messages. *)leterr?locs=user_err?locsletwarn_extraction_axiom_to_realize=CWarnings.create~name:"extraction-axiom-to-realize"~category:"extraction"(funaxioms->lets=ifInt.equal(List.lengthaxioms)1then"axiom"else"axioms"instrbrk("The following "^s^" must be realized in the extracted code:")++hov1(spc()++prlist_with_sepspcsafe_pr_globalaxioms)++str"."++fnl())letwarn_extraction_logical_axiom=CWarnings.create~name:"extraction-logical-axiom"~category:"extraction"(funaxioms->lets=ifInt.equal(List.lengthaxioms)1then"axiom was"else"axioms were"in(strbrk("The following logical "^s^" encountered:")++hov1(spc()++prlist_with_sepspcsafe_pr_globalaxioms++str".\n")++strbrk"Having invalid logical axiom in the environment when extracting"++spc()++strbrk"may lead to incorrect or non-terminating ML terms."++fnl()))letwarning_axioms()=letinfo_axioms=Refset'.elements!info_axiomsinifnot(List.is_emptyinfo_axioms)thenwarn_extraction_axiom_to_realizeinfo_axioms;letlog_axioms=Refset'.elements!log_axiomsinifnot(List.is_emptylog_axioms)thenwarn_extraction_logical_axiomlog_axiomsletwarn_extraction_opaque_accessed=CWarnings.create~name:"extraction-opaque-accessed"~category:"extraction"(funlst->strbrk"The extraction is currently set to bypass opacity, "++strbrk"the following opaque constant bodies have been accessed :"++lst++str"."++fnl())letwarn_extraction_opaque_as_axiom=CWarnings.create~name:"extraction-opaque-as-axiom"~category:"extraction"(funlst->strbrk"The extraction now honors the opacity constraints by default, "++strbrk"the following opaque constants have been extracted as axioms :"++lst++str"."++fnl()++strbrk"If necessary, use \"Set Extraction AccessOpaque\" to change this."++fnl())letwarning_opaquesaccessed=letopaques=Refset'.elements!opaquesinifnot(List.is_emptyopaques)thenletlst=hov1(spc()++prlist_with_sepspcsafe_pr_globalopaques)inifaccessedthenwarn_extraction_opaque_accessedlstelsewarn_extraction_opaque_as_axiomlstletwarning_ambiguous_name=CWarnings.create~name:"extraction-ambiguous-name"~category:"extraction"(fun(q,mp,r)->strbrk"The name "++pr_qualidq++strbrk" is ambiguous, "++strbrk"do you mean module "++pr_long_mpmp++strbrk" or object "++pr_long_globalr++str" ?"++fnl()++strbrk"First choice is assumed, for the second one please use "++strbrk"fully qualified name."++fnl())leterror_axiom_scheme?locri=err?loc(str"The type scheme axiom "++spc()++safe_pr_globalr++spc()++str"needs "++inti++str" type variable(s).")letwarn_extraction_inside_module=CWarnings.create~name:"extraction-inside-module"~category:"extraction"(fun()->strbrk"Extraction inside an opened module is experimental."++spc()++strbrk"In case of problem, close it first.")letcheck_inside_module()=ifLib.is_modtype()thenerr(str"You can't do that within a Module Type."++fnl()++str"Close it and try again.")elseifLib.is_module()thenwarn_extraction_inside_module()letcheck_inside_section()=ifGlobal.sections_are_opened()thenerr(str"You can't do that within a section."++fnl()++str"Close it and try again.")letwarn_extraction_reserved_identifier=CWarnings.create~name:"extraction-reserved-identifier"~category:"extraction"(funs->strbrk("The identifier "^s^" contains __ which is reserved for the extraction"))letwarning_ids=warn_extraction_reserved_identifiersleterror_constant?locr=err?loc(safe_pr_globalr++str" is not a constant.")leterror_inductive?locr=err?loc(safe_pr_globalr++spc()++str"is not an inductive type.")leterror_nb_cons()=err(str"Not the right number of constructors.")leterror_module_clashmp1mp2=err(str"The Coq modules "++pr_long_mpmp1++str" and "++pr_long_mpmp2++str" have the same ML name.\n"++str"This is not supported yet. Please do some renaming first.")leterror_no_module_exprmp=err(str"The module "++pr_long_mpmp++str" has no body, it probably comes from\n"++str"some Declare Module outside any Module Type.\n"++str"This situation is currently unsupported by the extraction.")leterror_singleton_become_propidog=letloc=matchogwith|Someg->fnl()++str"in "++safe_pr_globalg++str" (or in its mutual block)"|None->mt()inerr(str"The informative inductive type "++Id.printid++str" has a Prop instance"++loc++str"."++fnl()++str"This happens when a sort-polymorphic singleton inductive type\n"++str"has logical parameters, such as (I,I) : (True * True) : Prop.\n"++str"The Ocaml extraction cannot handle this situation yet.\n"++str"Instead, use a sort-monomorphic type such as (True /\\ True)\n"++str"or extract to Haskell.")leterror_unknown_module?locm=err?loc(str"Module"++spc()++pr_qualidm++spc()++str"not found.")leterror_scheme()=err(str"No Scheme modular extraction available yet.")leterror_not_visibler=err(safe_pr_globalr++str" is not directly visible.\n"++str"For example, it may be inside an applied functor.\n"++str"Use Recursive Extraction to get the whole environment.")leterror_MPfile_as_modmpb=lets1=ifbthen"asked"else"required"inlets2=ifbthen"extract some objects of this module or\n"else""inerr(str("Extraction of file "^(raw_string_of_modfilemp)^".v as a module is "^s1^".\n"^"Monolithic Extraction cannot deal with this situation.\n"^"Please "^s2^"use (Recursive) Extraction Library instead.\n"))letargnames_of_globalr=letenv=Global.env()inlettyp,_=Typeops.type_of_global_in_contextenvrinletrels,_=decompose_prod(Reduction.whd_allenvtyp)inList.rev_map(funx->Context.binder_name(fstx))relsletmsg_of_implicit=function|Kimplicit(r,i)->letname=match(List.nth(argnames_of_globalr)(i-1))with|Anonymous->""|Nameid->"("^Id.to_stringid^") "in(String.ordinali)^" argument "^name^"of "^(string_of_globalr)|Ktype|Kprop->""leterror_remaining_implicitk=lets=msg_of_implicitkinerr(str("An implicit occurs after extraction : "^s^".")++fnl()++str"Please check your Extraction Implicit declarations."++fnl()++str"You might also try Unset Extraction SafeImplicits to force"++fnl()++str"the extraction of unsafe code and review it manually.")letwarn_extraction_remaining_implicit=CWarnings.create~name:"extraction-remaining-implicit"~category:"extraction"(funs->strbrk("At least an implicit occurs after extraction : "^s^".")++fnl()++strbrk"Extraction SafeImplicits is unset, extracting nonetheless,"++strbrk"but this code is potentially unsafe, please review it manually.")letwarning_remaining_implicitk=lets=msg_of_implicitkinwarn_extraction_remaining_implicitsletcheck_loaded_modfilemp=matchbase_mpmpwith|MPfiledp->ifnot(Library.library_is_loadeddp)thenbeginmatchbase_mp(Lib.current_mp())with|MPfiledp'whennot(DirPath.equaldpdp')->err(str"Please load library "++DirPath.printdp++str" first.")|_->()end|_->()letinfo_filef=Flags.if_verboseFeedback.msg_info(str("The file "^f^" has been created by extraction."))(*S The Extraction auxiliary commands *)(* The objects defined below should survive an arbitrary time,
so we register them to coq save/undo mechanism. *)letmy_bool_optionnamevalue=declare_bool_option_and_ref~depr:false~key:["Extraction";name]~value(*s Extraction AccessOpaque *)letaccess_opaque=my_bool_option"AccessOpaque"true(*s Extraction AutoInline *)letauto_inline=my_bool_option"AutoInline"false(*s Extraction TypeExpand *)lettype_expand=my_bool_option"TypeExpand"true(*s Extraction KeepSingleton *)letkeep_singleton=my_bool_option"KeepSingleton"false(*s Extraction Optimize *)typeopt_flag={opt_kill_dum:bool;(* 1 *)opt_fix_fun:bool;(* 2 *)opt_case_iot:bool;(* 4 *)opt_case_idr:bool;(* 8 *)opt_case_idg:bool;(* 16 *)opt_case_cst:bool;(* 32 *)opt_case_fun:bool;(* 64 *)opt_case_app:bool;(* 128 *)opt_let_app:bool;(* 256 *)opt_lin_let:bool;(* 512 *)opt_lin_beta:bool}(* 1024 *)letkth_digitnk=not(Int.equal(nland(1lslk))0)letflag_of_intn={opt_kill_dum=kth_digitn0;opt_fix_fun=kth_digitn1;opt_case_iot=kth_digitn2;opt_case_idr=kth_digitn3;opt_case_idg=kth_digitn4;opt_case_cst=kth_digitn5;opt_case_fun=kth_digitn6;opt_case_app=kth_digitn7;opt_let_app=kth_digitn8;opt_lin_let=kth_digitn9;opt_lin_beta=kth_digitn10}(* For the moment, we allow by default everything except :
- the type-unsafe optimization [opt_case_idg], which anyway
cannot be activated currently (cf [Mlutil.branch_as_fun])
- the linear let and beta reduction [opt_lin_let] and [opt_lin_beta]
(may lead to complexity blow-up, subsumed by finer reductions
when inlining recursors).
*)letint_flag_init=1+2+4+8(*+ 16*)+32+64+128+256(*+ 512 + 1024*)letint_flag_ref=refint_flag_initletopt_flag_ref=ref(flag_of_intint_flag_init)letchg_flagn=int_flag_ref:=n;opt_flag_ref:=flag_of_intnletoptims()=!opt_flag_reflet()=declare_bool_option{optdepr=false;optkey=["Extraction";"Optimize"];optread=(fun()->not(Int.equal!int_flag_ref0));optwrite=(funb->chg_flag(ifbthenint_flag_initelse0))}let()=declare_int_option{optdepr=false;optkey=["Extraction";"Flag"];optread=(fun_->Some!int_flag_ref);optwrite=(function|None->chg_flag0|Somei->chg_flag(maxi0))}(* This option controls whether "dummy lambda" are removed when a
toplevel constant is defined. *)letconservative_types=declare_bool_option_and_ref~depr:false~key:["Extraction";"Conservative";"Types"]~value:false(* Allows to print a comment at the beginning of the output files *)letfile_comment=declare_string_option_and_ref~depr:false~key:["Extraction";"File";"Comment"]~value:""(*s Extraction Lang *)typelang=Ocaml|Haskell|Scheme|JSONletlang_ref=Summary.refOcaml~name:"ExtrLang"letlang()=!lang_refletextr_lang:lang->obj=declare_object@@superglobal_object_nodischarge"Extraction Lang"~cache:(funl->lang_ref:=l)~subst:Noneletextraction_languagex=Lib.add_leaf(extr_langx)(*s Extraction Inline/NoInline *)letempty_inline_table=(Refset'.empty,Refset'.empty)letinline_table=Summary.refempty_inline_table~name:"ExtrInline"letto_inliner=Refset'.memr(fst!inline_table)letto_keepr=Refset'.memr(snd!inline_table)letadd_inline_entriesbl=letfb=ifbthenRefset'.addelseRefset'.removeinleti,k=!inline_tableininline_table:=(List.fold_right(fb)li),(List.fold_right(f(notb))lk)(* Registration of operations for rollback. *)letinline_extraction:bool*GlobRef.tlist->obj=declare_object@@superglobal_object"Extraction Inline"~cache:(fun(b,l)->add_inline_entriesbl)~subst:(Some(fun(s,(b,l))->(b,(List.map(funx->fst(subst_globalsx))l))))~discharge:(funx->Somex)(* Grammar entries. *)letextraction_inlinebl=letrefs=List.mapSmartlocate.global_with_aliaslinList.iter(funr->matchrwith|GlobRef.ConstRef_->()|_->error_constantr)refs;Lib.add_leaf(inline_extraction(b,refs))(* Printing part *)letprint_extraction_inline()=let(i,n)=!inline_tableinleti'=Refset'.filter(functionGlobRef.ConstRef_->true|_->false)iin(str"Extraction Inline:"++fnl()++Refset'.fold(funrp->(p++str" "++safe_pr_long_globalr++fnl()))i'(mt())++str"Extraction NoInline:"++fnl()++Refset'.fold(funrp->(p++str" "++safe_pr_long_globalr++fnl()))n(mt()))(* Reset part *)letreset_inline:unit->obj=declare_object@@superglobal_object_nodischarge"Reset Extraction Inline"~cache:(fun()->inline_table:=empty_inline_table)~subst:Noneletreset_extraction_inline()=Lib.add_leaf(reset_inline())(*s Extraction Implicit *)letsafe_implicit=my_bool_option"SafeImplicits"trueleterr_or_warn_remaining_implicitk=ifsafe_implicit()thenerror_remaining_implicitkelsewarning_remaining_implicitktypeint_or_id=ArgIntofint|ArgIdofId.tletimplicits_table=Summary.refRefmap'.empty~name:"ExtrImplicit"letimplicits_of_globalr=tryRefmap'.findr!implicits_tablewithNot_found->Int.Set.emptyletadd_implicitsrl=letnames=argnames_of_globalrinletn=List.lengthnamesinletadd_args=function|ArgInti->if1<=i&&i<=nthenInt.Set.addiselseerr(inti++str" is not a valid argument number for "++safe_pr_globalr)|ArgIdid->tryleti=List.indexName.equal(Nameid)namesinInt.Set.addiswithNot_found->err(str"No argument "++Id.printid++str" for "++safe_pr_globalr)inletints=List.fold_leftadd_argInt.Set.emptylinimplicits_table:=Refmap'.addrints!implicits_table(* Registration of operations for rollback. *)letimplicit_extraction:GlobRef.t*int_or_idlist->obj=declare_object@@superglobal_object_nodischarge"Extraction Implicit"~cache:(fun(r,l)->add_implicitsrl)~subst:(Some(fun(s,(r,l))->(fst(subst_globalsr),l)))(* Grammar entries. *)letextraction_implicitrl=check_inside_section();Lib.add_leaf(implicit_extraction(Smartlocate.global_with_aliasr,l))(*s Extraction Blacklist of filenames not to use while extracting *)letblacklist_table=Summary.refId.Set.empty~name:"ExtrBlacklist"letmodfile_ids=refId.Set.emptyletmodfile_mps=refMPmap.emptyletreset_modfile()=modfile_ids:=!blacklist_table;modfile_mps:=MPmap.emptyletstring_of_modfilemp=tryMPmap.findmp!modfile_mpswithNot_found->letid=Id.of_string(raw_string_of_modfilemp)inletid'=next_ident_awayid!modfile_idsinlets'=Id.to_stringid'inmodfile_ids:=Id.Set.addid'!modfile_ids;modfile_mps:=MPmap.addmps'!modfile_mps;s'(* same as [string_of_modfile], but preserves the capital/uncapital 1st char *)letfile_of_modfilemp=lets0=matchmpwith|MPfilef->Id.to_string(List.hd(DirPath.reprf))|_->assertfalseinString.mapi(funic->ifi=0thens0.[0]elsec)(string_of_modfilemp)letadd_blacklist_entriesl=blacklist_table:=List.fold_right(funs->Id.Set.add(Id.of_string(String.capitalize_asciis)))l!blacklist_table(* Registration of operations for rollback. *)letblacklist_extraction:stringlist->obj=declare_object@@superglobal_object_nodischarge"Extraction Blacklist"~cache:add_blacklist_entries~subst:None(* Grammar entries. *)letextraction_blacklistl=letl=List.revlinLib.add_leaf(blacklist_extractionl)(* Printing part *)letprint_extraction_blacklist()=prlist_with_sepfnlId.print(Id.Set.elements!blacklist_table)(* Reset part *)letreset_blacklist:unit->obj=declare_object@@superglobal_object_nodischarge"Reset Extraction Blacklist"~cache:(fun()->blacklist_table:=Id.Set.empty)~subst:Noneletreset_extraction_blacklist()=Lib.add_leaf(reset_blacklist())(*s Extract Constant/Inductive. *)(* UGLY HACK: to be defined in [extraction.ml] *)let(use_type_scheme_nb_args,type_scheme_nb_args_hook)=Hook.make()letcustoms=Summary.refRefmap'.empty~name:"ExtrCustom"letadd_customridss=customs:=Refmap'.addr(ids,s)!customsletis_customr=Refmap'.memr!customsletis_inline_customr=(is_customr)&&(to_inliner)letfind_customr=snd(Refmap'.findr!customs)letfind_type_customr=Refmap'.findr!customsletcustom_matchs=Summary.refRefmap'.empty~name:"ExtrCustomMatchs"letadd_custom_matchrs=custom_matchs:=Refmap'.addrs!custom_matchsletindref_of_matchpv=ifArray.is_emptypvthenraiseNot_found;let(_,pat,_)=pv.(0)inmatchpatwith|Pusual(GlobRef.ConstructRef(ip,_))->GlobRef.IndRefip|Pcons(GlobRef.ConstructRef(ip,_),_)->GlobRef.IndRefip|_->raiseNot_foundletis_custom_matchpv=tryRefmap'.mem(indref_of_matchpv)!custom_matchswithNot_found->falseletfind_custom_matchpv=Refmap'.find(indref_of_matchpv)!custom_matchs(* Registration of operations for rollback. *)letin_customs:GlobRef.t*stringlist*string->obj=declare_object@@superglobal_object_nodischarge"ML extractions"~cache:(fun(r,ids,s)->add_customridss)~subst:(Some(fun(s,(r,ids,str))->(fst(subst_globalsr),ids,str)))letin_custom_matchs:GlobRef.t*string->obj=declare_object@@superglobal_object_nodischarge"ML extractions custom matches"~cache:(fun(r,s)->add_custom_matchrs)~subst:(Some(fun(subs,(r,s))->(fst(subst_globalsubsr),s)))(* Grammar entries. *)letextract_constant_inlineinlineridss=check_inside_section();letg=Smartlocate.global_with_aliasrinmatchgwith|GlobRef.ConstRefkn->letenv=Global.env()inlettyp,_=Typeops.type_of_global_in_contextenv(GlobRef.ConstRefkn)inlettyp=Reduction.whd_allenvtypinifReduction.is_arityenvtypthenbeginletnargs=Hook.getuse_type_scheme_nb_argsenvtypinifnot(Int.equal(List.lengthids)nargs)thenerror_axiom_scheme?loc:r.CAst.locgnargsend;Lib.add_leaf(inline_extraction(inline,[g]));Lib.add_leaf(in_customs(g,ids,s))|_->error_constant?loc:r.CAst.locgletextract_inductiversloptstr=check_inside_section();letg=Smartlocate.global_with_aliasrinDumpglob.add_glob?loc:r.CAst.locg;matchgwith|GlobRef.IndRef((kn,i)asip)->letmib=Global.lookup_mindkninletn=Array.lengthmib.mind_packets.(i).mind_consnamesinifnot(Int.equaln(List.lengthl))thenerror_nb_cons();Lib.add_leaf(inline_extraction(true,[g]));Lib.add_leaf(in_customs(g,[],s));Option.iter(funs->Lib.add_leaf(in_custom_matchs(g,s)))optstr;List.iteri(funjs->letg=GlobRef.ConstructRef(ip,succj)inLib.add_leaf(inline_extraction(true,[g]));Lib.add_leaf(in_customs(g,[],s)))l|_->error_inductive?loc:r.CAst.locg(*s Tables synchronization. *)letreset_tables()=init_typedefs();init_cst_types();init_inductives();init_inductive_kinds();init_recursors();init_projs();init_axioms();init_opaques();reset_modfile()