123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286(************************************************************************)(* * The Rocq Prover / The Rocq 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) *)(************************************************************************)(*s Target language for extraction: a core ML called MiniML. *)openNamesmoduleInfvInst=structtypet=boolarray(* true if informative *)letempty=[||]letcomparei1i2=CArray.compareBool.comparei1i2letequali1i2=Int.equal(comparei1i2)0letgenerateactx=letnames=UVars.AbstractContext.namesactxinletquals=Array.lengthnames.UVars.qualsinletinitn=letans=Array.makequalstrueinletn=refninfori=0toquals-1doletb=!nmod2=0inans.(i)<-b;n:=!n/2done;ansinList.init(1lslquals)initletdefaultactx=letnames=UVars.AbstractContext.namesactxinletquals=Array.lengthnames.UVars.qualsinArray.makequalstrueletgroundinst=letqvars,_=UVars.Instance.to_arrayinstinletmapq=matchqwith|Sorts.Quality.QConstant(QProp|QSProp)->false|Sorts.Quality.QConstantQType->true|Sorts.Quality.QVarqv->matchSorts.QVar.reprqvwith|Var_->CErrors.anomaly(Pp.str"Non-ground instance")|Unif_|Global_->true(* informative by default *)inArray.mapmapqvarsletinstantiateactxinst=letu=UVars.make_abstract_instanceactxinletfll=linletfqq=matchSorts.QVar.var_indexqwith|None->assertfalse|Somei->ifinst.(i)thenSorts.Quality.qtypeelseSorts.Quality.qspropinUVars.Instance.subst_fn(fq,fl)uletencodeinst=ifArray.for_all(funb->b)instthenNoneelseletlen=Array.lengthinstinSome(String.initlen(funi->ifinst.(i)then'X'else'O'))endtypeglobal={glob:GlobRef.t;inst:InfvInst.t}(* The [signature] type is used to know how many arguments a CIC
object expects, and what these arguments will become in the ML
object. *)(* We eliminate from terms:
1) types
2) logical parts
3) user-declared implicit arguments of a constant of constructor
*)typekill_reason=|Ktype|Kprop|Kimplicitofglobal*int(* n-th arg of a cst or construct *)typesign=Keep|Killofkill_reason(* Convention: outmost lambda/product gives the head of the list. *)typesignature=signlist(*s ML type expressions. *)typeml_type=|Tarrofml_type*ml_type|Tglobofglobal*ml_typelist|Tvarofint|Tvar'ofint(* same as Tvar, used to avoid clash *)|Tmetaofml_meta(* used during ML type reconstruction *)|Tdummyofkill_reason|Tunknown|Taxiomandml_meta={id:int;mutablecontents:ml_typeoption}(* ML type schema.
The integer is the number of variable in the schema. *)typeml_schema=int*ml_type(*s ML inductive types. *)typeinductive_kind=|Singleton|Coinductive|Standard|Recordofglobaloptionlist(* None for anonymous field *)(* A [ml_ind_packet] is the miniml counterpart of a [one_inductive_body].
If the inductive is logical ([ip_logical = false]), then all other fields
are unused. Otherwise,
[ip_sign] is a signature concerning the arguments of the inductive,
[ip_vars] contains the names of the type variables surviving in ML,
[ip_types] contains the ML types of all constructors.
*)typeml_ind_packet={ip_typename:Id.t;ip_typename_ref:global;ip_consnames:Id.tarray;ip_consnames_ref:globalarray;ip_logical:bool;ip_sign:signature;ip_vars:Id.tlist;ip_types:(ml_typelist)array}(* [ip_nparams] contains the number of parameters. *)typeequiv=|NoEquiv|EquivofKerName.t|RenEquivofstringtypeml_ind={ind_kind:inductive_kind;ind_nparams:int;ind_packets:ml_ind_packetarray;ind_equiv:equiv}(*s ML terms. *)typeml_ident=|Dummy|IdofId.t|TmpofId.t(** We now store some typing information on constructors
and cases to avoid type-unsafe optimisations. This will be
either the type of the applied constructor or the type
of the head of the match.
*)(** Nota : the constructor [MLtuple] and the extension of [MLcase]
to general patterns have been proposed by P.N. Tollitte for
his Relation Extraction plugin. [MLtuple] is currently not
used by the main extraction, as well as deep patterns. *)typeml_branch=ml_identlist*ml_pattern*ml_astandml_ast=|MLrelofint|MLappofml_ast*ml_astlist|MLlamofml_ident*ml_ast|MLletinofml_ident*ml_ast*ml_ast|MLglobofglobal|MLconsofml_type*global*ml_astlist|MLtupleofml_astlist|MLcaseofml_type*ml_ast*ml_brancharray|MLfixofint*Id.tarray*ml_astarray|MLexnofstring|MLdummyofkill_reason|MLaxiomofstring|MLmagicofml_ast|MLuintofUint63.t|MLfloatofFloat64.t|MLstringofPstring.t|MLparrayofml_astarray*ml_astandml_pattern=|Pconsofglobal*ml_patternlist|Ptupleofml_patternlist|Prelofint(** Cf. the idents in the branch. [Prel 1] is the last one. *)|Pwild|Pusualofglobal(** Shortcut for Pcons (r,[Prel n;...;Prel 1]) **)(*s ML declarations. *)typeml_decl=|Dindofml_ind|Dtypeofglobal*Id.tlist*ml_type|Dtermofglobal*ml_ast*ml_type|Dfixofglobalarray*ml_astarray*ml_typearraytypeml_spec=|Sindofml_ind|Stypeofglobal*Id.tlist*ml_typeoption|Svalofglobal*ml_typetypeml_specif=|Specofml_spec|Smoduleofml_module_type|Smodtypeofml_module_typeandml_module_type=|MTidentofModPath.t|MTfunsigofMBId.t*ml_module_type*ml_module_type|MTsigofModPath.t*ml_module_sig|MTwithofml_module_type*ml_with_declarationandml_with_declaration=|ML_With_typeofInfvInst.t*Id.tlist*Id.tlist*ml_type|ML_With_moduleofId.tlist*ModPath.tandml_module_sig=(Label.t*ml_specif)listtypeml_structure_elem=|SEdeclofml_decl|SEmoduleofml_module|SEmodtypeofml_module_typeandml_module_expr=|MEidentofModPath.t|MEfunctorofMBId.t*ml_module_type*ml_module_expr|MEstructofModPath.t*ml_module_structure|MEapplyofml_module_expr*ml_module_exprandml_module_structure=(Label.t*ml_structure_elem)listandml_module={ml_mod_expr:ml_module_expr;ml_mod_type:ml_module_type}(* NB: we do not translate the [mod_equiv] field, since [mod_equiv = mp]
implies that [mod_expr = MEBident mp]. Same with [msb_equiv]. *)typeml_structure=(ModPath.t*ml_module_structure)listtypeml_signature=(ModPath.t*ml_module_sig)listtypeunsafe_needs={mldummy:bool;tdummy:bool;tunknown:bool;magic:bool}type'slanguage_descr={keywords:Id.Set.t;(* Concerning the source file *)file_suffix:string;file_naming:'s->ModPath.t->string;(* the second argument is a comment to add to the preamble *)preamble:'s->Id.t->Pp.toption->ModPath.tlist->unsafe_needs->Pp.t;pp_struct:'s->ml_structure->Pp.t;(* Concerning a possible interface file *)sig_suffix:stringoption;(* the second argument is a comment to add to the preamble *)sig_preamble:'s->Id.t->Pp.toption->ModPath.tlist->unsafe_needs->Pp.t;pp_sig:'s->ml_signature->Pp.t;(* for an isolated declaration print *)pp_decl:'s->ml_decl->Pp.t;}