package coq
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=513e953b7183d478acb75fd6e80e4dc32ac1a918cf4343ac31a859cfb4e9aad2
doc/coq-core.kernel/Declarations/index.html
Module Declarations
Source
This module defines the internal representation of global declarations. This includes global constants/axioms, mutual inductive definitions, modules and module types
Representation of constants (Definition/Axiom)
Non-universe polymorphic mode polymorphism (Coq 8.2+): inductives and constants hiding inductives are implicitly polymorphic when applied to parameters, on the universes appearing in the whnf of their parameters and their conclusion, in a template style.
In truly universe polymorphic mode, we always use RegularArity.
type template_universes = {
template_param_levels : Univ.Level.t option list;
template_context : Univ.ContextSet.t;
}
Inlining level of parameters at functor applications. None means no inlining
A constant can have no body (axiom/parameter), or a transparent body, or an opaque one
type ('a, 'opaque) constant_def =
| Undef of inline
(*a global assumption
*)| Def of 'a
(*or a transparent global definition
*)| OpaqueDef of 'opaque
(*or an opaque global definition
*)| Primitive of CPrimitives.t
(*or a primitive operation
*)
type typing_flags = {
check_guarded : bool;
(*If
*)false
then fixed points and co-fixed points are assumed to be total.check_positive : bool;
(*If
*)false
then inductive types are assumed positive and co-inductive types are assumed productive.check_universes : bool;
(*If
*)false
universe constraints are not checkedconv_oracle : Conv_oracle.oracle;
(*Unfolding strategies for conversion
*)enable_VM : bool;
(*If
*)false
, all VM conversions fall back to interpreted onesenable_native_compiler : bool;
(*If
*)false
, all native conversions fall back to VM onesindices_matter : bool;
(*The universe of an inductive type must be above that of its indices.
*)impredicative_set : bool;
(*Predicativity of the
*)Set
universe.sprop_allowed : bool;
(*If
*)false
, error when encounteringSProp
.cumulative_sprop : bool;
(*SProp <= Type
*)allow_uip : bool;
(*Allow definitional UIP (breaks termination)
*)
}
The typing_flags
are instructions to the type-checker which modify its behaviour. The typing flags used in the type-checking of a constant are tracked in their constant_body
so that they can be displayed to the user.
type work_list =
(Univ.Instance.t * Names.Id.t array) Names.Cmap.t
* (Univ.Instance.t * Names.Id.t array) Names.Mindmap.t
type abstr_info = {
abstr_ctx : Constr.named_context;
(*Section variables of this prefix
*)abstr_subst : Univ.Instance.t;
(*Actual names of the abstracted variables
*)abstr_uctx : Univ.AbstractContext.t;
(*Universe quantification, same length as the substitution
*)
}
Data needed to abstract over the section variable and universe hypotheses
type 'opaque pconstant_body = {
const_hyps : Constr.named_context;
(*younger hyp at top
*)const_body : (Constr.t, 'opaque) constant_def;
const_type : Constr.types;
const_relevance : Sorts.relevance;
const_body_code : Vmemitcodes.body_code option;
const_universes : universes;
const_inline_code : bool;
const_typing_flags : typing_flags;
(*The typing options which were used for type-checking.
*)
}
Representation of mutual inductive types in the kernel
Inductive I1 (params) : U1 := c11 : T11 | ... | c1p1 : T1p1 ... with In (params) : Un := cn1 : Tn1 | ... | cnpn : Tnpn
Record information: If the type is not a record, then NotRecord If the type is a non-primitive record, then FakeRecord If it is a primitive record, for every type in the block, we get:
- The identifier for the binder name of the record in primitive projections.
- The constants associated to each projection.
- The projection types (under parameters).
The kernel does not exploit the difference between NotRecord
and FakeRecord
. It is mostly used by extraction, and should be extruded from the kernel at some point.
type record_info =
| NotRecord
| FakeRecord
| PrimRecord of (Names.Id.t * Names.Label.t array * Sorts.relevance array * Constr.types array) array
type one_inductive_body = {
mind_typename : Names.Id.t;
(*Name of the type:
*)Ii
mind_arity_ctxt : Constr.rel_context;
(*Arity context of
*)Ii
. It includes the context of parameters, that is, it has the formparamdecls, realdecls_i
such thatUi
(see above) isforall realdecls_i, si
for some sortsi
and such thatIi
has thus typeforall paramdecls, forall realdecls_i, si
. The context itself is represented internally as a list in reverse order[realdecl_i{r_i};...;realdecl_i1;paramdecl_m;...;paramdecl_1]
.mind_arity : inductive_arity;
(*Arity sort and original user arity
*)mind_consnames : Names.Id.t array;
(*Names of the constructors:
*)cij
mind_user_lc : Constr.types array;
(*Types of the constructors with parameters:
*)forall params, Tij
, where the recursive occurrences of the inductive types inTij
(i.e. in the type of the j-th constructor of the i-th types of the block a shown above) have the formInd ((mind,0),u)
, ...,Ind ((mind,n-1),u)
foru
the canonical abstract instance associated tomind_universes
andmind
the name to which the inductive block is bound in the environment.mind_nrealargs : int;
(*Number of expected real arguments of the type (no let, no params)
*)mind_nrealdecls : int;
(*Length of realargs context (with let, no params)
*)mind_kelim : Sorts.family;
(*Highest allowed elimination sort
*)mind_nf_lc : (Constr.rel_context * Constr.types) array;
(*Head normalized constructor types so that their conclusion exposes the inductive type. It includes the parameters, i.e. each component of the array has the form
*)(decls_ij, Ii params realargs_ij)
wheredecls_ij
is the concatenation of the context of parameters (possibly with let-ins) and of the arguments of the constructor (possibly with let-ins). This context is internally represented as a list[cstrdecl_ij{q_ij};...;cstrdecl_ij1;paramdecl_m;...;paramdecl_1]
such that the constructor in fine has typeforall paramdecls, forall cstrdecls_ij, Ii params realargs_ij
] withparams
referring to the assumptions ofparamdecls
andrealargs_ij
being the "indices" specific to the constructor.mind_consnrealargs : int array;
(*Number of expected proper arguments of the constructors (w/o params)
*)mind_consnrealdecls : int array;
(*Length of the signature of the constructors (with let, w/o params)
*)mind_recargs : wf_paths;
(*Signature of recursive arguments in the constructors
*)mind_relevance : Sorts.relevance;
mind_nb_constant : int;
(*number of constant constructor
*)mind_nb_args : int;
(*number of no constant constructor
*)mind_reloc_tbl : Vmvalues.reloc_table;
}
Datas specific to a single type of a block of mutually inductive type
Datas associated to a full block of mutually inductive types
type mutual_inductive_body = {
mind_packets : one_inductive_body array;
(*The component of the mutual inductive block
*)mind_record : record_info;
(*The record information
*)mind_finite : recursivity_kind;
(*Whether the type is inductive or coinductive
*)mind_ntypes : int;
(*Number of types in the block
*)mind_hyps : Constr.named_context;
(*Section hypotheses on which the block depends
*)mind_nparams : int;
(*Number of expected parameters including non-uniform ones (i.e. length of mind_params_ctxt w/o let-in)
*)mind_nparams_rec : int;
(*Number of recursively uniform (i.e. ordinary) parameters
*)mind_params_ctxt : Constr.rel_context;
(*The context of parameters (includes let-in declaration)
*)mind_universes : universes;
(*Information about monomorphic/polymorphic/cumulative inductives and their universes
*)mind_template : template_universes option;
mind_variance : Univ.Variance.t array option;
(*Variance info,
*)None
when non-cumulative.mind_sec_variance : Univ.Variance.t array option;
(*Variance info for section polymorphic universes.
*)None
outside sections. The final variance once all sections are discharged ismind_sec_variance ++ mind_variance
.mind_private : bool option;
(*allow pattern-matching: Some true ok, Some false blocked
*)mind_typing_flags : typing_flags;
(*typing flags at the time of the inductive creation
*)
}
Module declarations
Functor expressions are forced to be on top of other expressions
type ('ty, 'a) functorize =
| NoFunctor of 'a
| MoreFunctor of Names.MBId.t * 'ty * ('ty, 'a) functorize
The fully-algebraic module expressions : names, applications, 'with ...'. They correspond to the user entries of non-interactive modules. They will be later expanded into module structures in Mod_typing
, and won't play any role into the kernel after that : they are kept only for short module printing and for extraction.
type with_declaration =
| WithMod of Names.Id.t list * Names.ModPath.t
| WithDef of Names.Id.t list * Constr.constr * Univ.AbstractContext.t option
type module_alg_expr =
| MEident of Names.ModPath.t
| MEapply of module_alg_expr * Names.ModPath.t
| MEwith of module_alg_expr * with_declaration
A component of a module structure
type structure_field_body =
| SFBconst of constant_body
| SFBmind of mutual_inductive_body
| SFBmodule of module_body
| SFBmodtype of module_type_body
A module structure is a list of labeled components.
Note : we may encounter now (at most) twice the same label in a structure_body
, once for a module (SFBmodule
or SFBmodtype
) and once for an object (SFBconst
or SFBmind
)
A module signature is a structure, with possibly functors on top of it
A module expression is an algebraic expression, possibly functorized.
and module_implementation =
| Abstract
(*no accessible implementation
*)| Algebraic of module_expression
(*non-interactive algebraic expression
*)| Struct of module_signature
(*interactive body
*)| FullStruct
(*special case of
*)Struct
: the body is exactlymod_type
and 'a generic_module_body = {
mod_mp : Names.ModPath.t;
(*absolute path of the module
*)mod_expr : 'a;
(*implementation
*)mod_type : module_signature;
(*expanded type
*)mod_type_alg : module_expression option;
(*algebraic type
*)mod_delta : Mod_subst.delta_resolver;
(*quotiented set of equivalent constants and inductive names
*)mod_retroknowledge : 'a module_retroknowledge;
}
For a module, there are five possible situations:
Declare Module M : T
thenmod_expr = Abstract; mod_type_alg = Some T
Module M := E
thenmod_expr = Algebraic E; mod_type_alg = None
Module M : T := E
thenmod_expr = Algebraic E; mod_type_alg = Some T
Module M. ... End M
thenmod_expr = FullStruct; mod_type_alg = None
Module M : T. ... End M
thenmod_expr = Struct; mod_type_alg = Some T
And of course, all these situations may be functors or not.
A module_type_body
is just a module_body
with no implementation and also an empty mod_retroknowledge
. Its mod_type_alg
contains the algebraic definition of this module type, or None
if it has been built interactively.
and _ module_retroknowledge =
| ModBodyRK : Retroknowledge.action list -> module_implementation module_retroknowledge
| ModTypeRK : unit module_retroknowledge
Extra invariants :
- No
MEwith
inside amod_expr
implementation : the 'with' syntax is only supported for module types
- A module application is atomic, for instance ((M N) P) : * the head of
MEapply
can only be anotherMEapply
or aMEident
* the argument ofMEapply
is now directly forced to be aModPath.t
.