ConstrThis file defines the most important datatype of Rocq, namely kernel terms, as well as a handful of generic manipulation functions.
type pconstant = Names.Constant.t UVars.puniversesSimply type aliases
type pinductive = Names.inductive UVars.puniversestype pconstructor = Names.constructor UVars.puniversestype case_info = {ci_ind : Names.inductive;ci_npar : int;ci_cstr_ndecls : int array;ci_cstr_nargs : int array;ci_pp_info : case_printing;}type constr = ttypes is the same as constr but is intended to be used for documentation to indicate that such or such function specifically works with types (i.e. terms of type a sort). (Rem:plurial form since type is a reserved ML keyword)
type types = constrThe following functions are intended to simplify and to uniform the manipulation of terms. Some of these functions may be overlapped with previous ones.
val mkRel : int -> constrConstructs a de Bruijn index (DB indices begin at 1)
val mkVar : Names.Id.t -> constrConstructs a Variable
val mkArray : (UVars.Instance.t * constr array * constr * types) -> constrConstructs an array
val mkMeta : metavariable -> constrConstructs an patvar named "?n"
val mkEvar : existential -> constrval mkSProp : typesval mkProp : typesval mkSet : typesval mkType : Univ.Universe.t -> typesThis defines the strategy to use for verifiying a Cast
Constructs the term t1::t2, i.e. the term t1 casted with the type t2 (that means t2 is declared as the type of t1).
type 'a binder_annot = ('a, Sorts.relevance) Context.pbinder_annotval mkProd : (Names.Name.t binder_annot * types * types) -> typesConstructs the product (x:t1)t2
val mkLambda : (Names.Name.t binder_annot * types * constr) -> constrConstructs the abstraction [x:t1]t2
val mkLetIn : (Names.Name.t binder_annot * constr * types * constr) -> constrConstructs the product let x = t1 : t2 in t3
mkApp (f, [|t1; ...; tN|] constructs the application (f t1 ... tn) .
val map_puniverses : ('a -> 'b) -> 'a UVars.puniverses -> 'b UVars.puniversesval mkProj : (Names.Projection.t * Sorts.relevance * constr) -> constrConstructs a projection application
Inductive types
val mkIndU : pinductive -> constrConstructs the ith (co)inductive type of the block named kn
val mkConstructU : pconstructor -> constrConstructs the jth constructor of the ith (co)inductive type of the block named kn.
val mkConstructUi : (pinductive * int) -> constrval mkRef : Names.GlobRef.t UVars.puniverses -> constrMake a constant, inductive, constructor or variable.
module UnsafeMonomorphic : sig ... endConstructs a destructor of inductive type.
mkCase ci params p c ac stand for match c as x in I args return p with ac presented as describe in ci.
p structure is args x |- "return clause"
acith element is ith constructor case presented as construct_args |- case_term
type ('constr, 'r) pcase_branch =
(Names.Name.t, 'r) Context.pbinder_annot array * 'constrNames bound by matching the constructor for this branch.
type ('types, 'r) pcase_return =
((Names.Name.t, 'r) Context.pbinder_annot array * 'types) * 'rNames of the indices + name of self
type ('constr, 'types, 'univs, 'r) pcase =
case_info
* 'univs
* 'constr array
* ('types, 'r) pcase_return
* 'constr pcase_invert
* 'constr
* ('constr, 'r) pcase_branch arraytype case_invert = constr pcase_inverttype case_return = (types, Sorts.relevance) pcase_returntype case_branch = (constr, Sorts.relevance) pcase_branchtype case = (constr, types, UVars.Instance.t, Sorts.relevance) pcasetype ('constr, 'types, 'r) prec_declaration =
(Names.Name.t, 'r) Context.pbinder_annot array * 'types array * 'constr arrayIf recindxs = [|i1,...in|] funnames = [|f1,.....fn|] typarray = [|t1,...tn|] bodies = [|b1,.....bn|] then mkFix ((recindxs,i), funnames, typarray, bodies) constructs the $ i $ th function of the block (counting from 0)
Fixpoint f1 [ctx1] = b1 with f2 [ctx2] = b2 ... with fn [ctxn] = bn.
where the length of the $ j $ th context is $ ij $ .
type ('constr, 'types, 'r) pfixpoint =
(int array * int) * ('constr, 'types, 'r) prec_declarationThe array of int's tells for each component of the array of mutual fixpoints the number of lambdas to skip before finding the recursive argument (e.g., value is 2 in "fix f (x:A) (y:=t) (z:B) (v:=u) (w:I) struct w"), telling to skip x and z and that w is the recursive argument); The second component int tells which component of the block is returned
type ('constr, 'types, 'r) pcofixpoint =
int * ('constr, 'types, 'r) prec_declarationThe component int tells which component of the block of cofixpoint is returned
type rec_declaration = (constr, types, Sorts.relevance) prec_declarationtype fixpoint = (constr, types, Sorts.relevance) pfixpointtype cofixpoint = (constr, types, Sorts.relevance) pcofixpointIf funnames = [|f1,.....fn|] typarray = [|t1,...tn|] bodies = [b1,.....bn] then mkCoFix (i, (funnames, typarray, bodies)) constructs the ith function of the block
CoFixpoint f1 = b1 with f2 = b2 ... with fn = bn.
val mkCoFix : cofixpoint -> constrconstr list is an instance matching definitional named_context in the same order (i.e. last argument first)
type ('constr, 'types, 'sort, 'univs, 'r) kind_of_term = | Rel of intGallina-variable introduced by forall, fun, let-in, fix, or cofix.
| Var of Names.Id.tGallina-variable that was introduced by Vernacular-command that extends the local context of the currently open section (i.e. Variable or Let).
| Meta of metavariable| Evar of 'constr pexistential| Sort of 'sort| Cast of 'constr * cast_kind * 'types| Prod of (Names.Name.t, 'r) Context.pbinder_annot * 'types * 'typesConcrete syntax "forall A:B,C" is represented as Prod (A,B,C).
| Lambda of (Names.Name.t, 'r) Context.pbinder_annot * 'types * 'constrConcrete syntax "fun A:B => C" is represented as Lambda (A,B,C).
| LetIn of (Names.Name.t, 'r) Context.pbinder_annot * 'constr * 'types * 'constrConcrete syntax "let A:C := B in D" is represented as LetIn (A,B,C,D).
| App of 'constr * 'constr array| Const of Names.Constant.t * 'univsGallina-variable that was introduced by Vernacular-command that extends the global environment (i.e. Parameter, or Axiom, or Definition, or Theorem, or Symbol etc.)
| Ind of Names.inductive * 'univsA name of an inductive type defined by Variant, Inductive or Record Vernacular-commands.
| Construct of Names.constructor * 'univsA constructor of an inductive type defined by Variant, Inductive or Record Vernacular-commands.
| Case of case_info
* 'univs
* 'constr array
* ('types, 'r) pcase_return
* 'constr pcase_invert
* 'constr
* ('constr, 'r) pcase_branch arrayCase (ci,u,params,p,iv,c,brs) is a match c return p with brs expression. c lives in inductive ci.ci_ind at universe instance u and parameters params. If this match has case inversion (ie match on a 1 constructor SProp inductive with proof relevant return type) the indices are in iv.
The names in p are the names of the bound indices and inductive value (ie the in and as clauses).
The names in the brs are the names of the variables bound in the respective branch.
| Fix of ('constr, 'types, 'r) pfixpoint| CoFix of ('constr, 'types, 'r) pcofixpoint| Proj of Names.Projection.t * 'r * 'constrThe relevance is the relevance of the whole term
*)| Int of Uint63.t| Float of Float64.t| String of Pstring.t| Array of 'univs * 'constr array * 'constr * 'typesArray (u,vals,def,t) is an array of vals in type t with default value def. u is a universe containing t.
User view of constr. For App, it is ensured there is at least one argument and the function is not itself an applicative term
val kind :
constr ->
(constr, types, Sorts.t, UVars.Instance.t, Sorts.relevance) kind_of_termval of_kind :
(constr, types, Sorts.t, UVars.Instance.t, Sorts.relevance) kind_of_term ->
constrval kind_nocast_gen :
('v -> ('v, 'v, 'sort, 'univs, 'r) kind_of_term) ->
'v ->
('v, 'v, 'sort, 'univs, 'r) kind_of_termval kind_nocast :
constr ->
(constr, types, Sorts.t, UVars.Instance.t, Sorts.relevance) kind_of_termval isRel : constr -> boolSimple case analysis
val isRelN : int -> constr -> boolval isVar : constr -> boolval isVarId : Names.Id.t -> constr -> boolval isRef : constr -> boolval isInd : constr -> boolval isEvar : constr -> boolval isMeta : constr -> boolval isEvar_or_Meta : constr -> boolval isSort : constr -> boolval isCast : constr -> boolval isApp : constr -> boolval isLambda : constr -> boolval isLetIn : constr -> boolval isProd : constr -> boolval isConst : constr -> boolval isConstruct : constr -> boolval isFix : constr -> boolval isCoFix : constr -> boolval isCase : constr -> boolval isProj : constr -> boolval is_Prop : constr -> boolval is_Set : constr -> boolval isprop : constr -> boolval is_Type : constr -> boolval iskind : constr -> boolDestructor operations are partial functions and
val destRel : constr -> intDestructs a de Bruijn index
val destMeta : constr -> metavariableDestructs an existential variable
val destVar : constr -> Names.Id.tDestructs a variable
Destructs a sort. is_Prop recognizes the sort Prop, whether isprop recognizes both Prop and Set.
val destProd : types -> Names.Name.t binder_annot * types * typesDestructs the product $ (x:t_1)t_2 $
val destLambda : constr -> Names.Name.t binder_annot * types * constrDestructs the abstraction $ x:t_1t_2 $
val destLetIn : constr -> Names.Name.t binder_annot * constr * types * constrDestructs the let $ x:=b:t_1t_2 $
Decompose any term as an applicative term; the list of args can be empty
val destConst : constr -> Names.Constant.t UVars.puniversesDestructs a constant
val destEvar : constr -> existentialDestructs an existential variable
val destInd : constr -> Names.inductive UVars.puniversesDestructs a (co)inductive type
val destConstruct : constr -> Names.constructor UVars.puniversesDestructs a constructor
Destructs a match c as x in I args return P with ... | Ci(...yij...) => ti | ... end (or let (..y1i..) := c as x in I args return P in t1, or if c then t1 else t2)
val destProj : constr -> Names.Projection.t * Sorts.relevance * constrDestructs a projection
Destructs the $ i $ th function of the block Fixpoint f{_ 1} ctx{_ 1} = b{_ 1} with f{_ 2} ctx{_ 2} = b{_ 2} ... with f{_ n} ctx{_ n} = b{_ n}, where the length of the $ j $ th context is $ ij $ .
val destCoFix : constr -> cofixpointval destRef : constr -> Names.GlobRef.t UVars.puniversesequal a b is true if a equals b modulo alpha, casts, and application grouping
eq_constr_univs u a b is true if a equals b modulo alpha, casts, application grouping and the universe equalities in u.
leq_constr_univs u a b is true if a is convertible to b modulo alpha, casts, application grouping and the universe inequalities in u.
eq_constr_univs a b true, c if a equals b modulo alpha, casts, application grouping and ignoring universe instances.
type rel_declaration =
(constr, types, Sorts.relevance) Context.Rel.Declaration.pttype named_declaration =
(constr, types, Sorts.relevance) Context.Named.Declaration.pttype rel_context = rel_declaration listtype named_context = named_declaration listval exliftn : Esubst.lift -> constr -> constrexliftn el c lifts c with lifting el
map_branches f br maps f on the immediate subterms of an array of "match" branches br in canonical eta-let-expanded form; it is not recursive and the order with which subterms are processed is not specified; it preserves sharing; the immediate subterms are the types and possibly terms occurring in the context of each branch as well as the body of each branch
val map_branches : (constr -> constr) -> case_branch array -> case_branch arraymap_return_predicate f p maps f on the immediate subterms of a return predicate of a "match" in canonical eta-let-expanded form; it is not recursive and the order with which subterms are processed is not specified; it preserves sharing; the immediate subterms are the types and possibly terms occurring in the context of each branch as well as the body of the predicate
val map_return_predicate : (constr -> constr) -> case_return -> case_returnmap_branches_with_binders f br maps f on the immediate subterms of an array of "match" branches br in canonical eta-let-expanded form; it carries an extra data n (typically a lift index) which is processed by g (which typically adds 1 to n) at each binder traversal; it is not recursive and the order with which subterms are processed is not specified; it preserves sharing; the immediate subterms are the types and possibly terms occurring in the context of the branch as well as the body of the branch
val map_branches_with_binders :
('a -> 'a) ->
('a -> constr -> constr) ->
'a ->
case_branch array ->
case_branch arraymap_return_predicate_with_binders f p maps f on the immediate subterms of a return predicate of a "match" in canonical eta-let-expanded form; it carries an extra data n (typically a lift index) which is processed by g (which typically adds 1 to n) at each binder traversal; it is not recursive and the order with which subterms are processed is not specified; it preserves sharing; the immediate subterms are the types and possibly terms occurring in the context of each branch as well as the body of the predicate
val map_return_predicate_with_binders :
('a -> 'a) ->
('a -> constr -> constr) ->
'a ->
case_return ->
case_returnfold f acc c folds f on the immediate subterms of c starting from acc and proceeding from left to right according to the usual representation of the constructions; it is not recursive
val fold_invert : ('a -> 'b -> 'a) -> 'a -> 'b pcase_invert -> 'amap f c maps f on the immediate subterms of c; it is not recursive and the order with which subterms are processed is not specified
val map_invert : ('a -> 'a) -> 'a pcase_invert -> 'a pcase_invertLike map, but also has an additional accumulator.
val fold_map_invert :
('a -> 'b -> 'a * 'b) ->
'a ->
'b pcase_invert ->
'a * 'b pcase_invertmap_with_binders g f n c maps f n on the immediate subterms of c; it carries an extra data n (typically a lift index) which is processed by g (which typically add 1 to n) at each binder traversal; it is not recursive and the order with which subterms are processed is not specified
iter f c iters f on the immediate subterms of c; it is not recursive and the order with which subterms are processed is not specified
val iter_invert : ('a -> unit) -> 'a pcase_invert -> unititer_with_binders g f n c iters f n on the immediate subterms of c; it carries an extra data n (typically a lift index) which is processed by g (which typically add 1 to n) at each binder traversal; it is not recursive and the order with which subterms are processed is not specified
iter_with_binders g f n c iters f n on the immediate subterms of c; it carries an extra data n (typically a lift index) which is processed by g (which typically add 1 to n) at each binder traversal; it is not recursive and the order with which subterms are processed is not specified
compare_head f c1 c2 compare c1 and c2 using f to compare the immediate subterms of c1 of c2 if needed; Cast's, binders name and Cases annotations are not taken into account
val compare_head :
(existential -> existential -> bool) ->
constr constr_compare_fn ->
constr constr_compare_fntype 'univs instance_compare_fn =
(Names.GlobRef.t * int) option ->
'univs ->
'univs ->
boolConvert a global reference applied to 2 instances. The int says how many arguments are given (as we can only use cumulativity for fully applied inductives/constructors) .
compare_head_gen u s f c1 c2 compare c1 and c2 using f to compare the immediate subterms of c1 of c2 if needed, u to compare universe instances, s to compare sorts; Cast's, binders name and Cases annotations are not taken into account
val compare_head_gen :
UVars.Instance.t instance_compare_fn ->
(Sorts.t -> Sorts.t -> bool) ->
(existential -> existential -> bool) ->
constr constr_compare_fn ->
constr constr_compare_fnval compare_head_gen_leq_with :
('v -> ('v, 'v, 'sort, 'univs, 'r) kind_of_term) ->
('v -> ('v, 'v, 'sort, 'univs, 'r) kind_of_term) ->
'univs instance_compare_fn ->
('sort -> 'sort -> bool) ->
('v pexistential -> 'v pexistential -> bool) ->
'v constr_compare_fn ->
'v constr_compare_fn ->
'v constr_compare_fnval compare_head_gen_with :
('v -> ('v, 'v, 'sort, 'univs, 'r) kind_of_term) ->
('v -> ('v, 'v, 'sort, 'univs, 'r) kind_of_term) ->
'univs instance_compare_fn ->
('sort -> 'sort -> bool) ->
('v pexistential -> 'v pexistential -> bool) ->
'v constr_compare_fn ->
'v constr_compare_fncompare_head_gen_with k1 k2 u s f c1 c2 compares c1 and c2 like compare_head_gen u s f c1 c2, except that k1 (resp. k2) is used,rather than kind, to expose the immediate subterms of c1 (resp. c2).
compare_head_gen_leq u s f fle c1 c2 compare c1 and c2 using f to compare the immediate subterms of c1 of c2 for conversion, fle for cumulativity, u to compare universe instances (the first boolean tells if they belong to a Constant.t), s to compare sorts for for subtyping; Cast's, binders name and Cases annotations are not taken into account
val compare_head_gen_leq :
UVars.Instance.t instance_compare_fn ->
(Sorts.t -> Sorts.t -> bool) ->
(existential -> existential -> bool) ->
constr constr_compare_fn ->
constr constr_compare_fn ->
constr constr_compare_fnval eq_invert :
('a -> 'a -> bool) ->
'a pcase_invert ->
'a pcase_invert ->
boolval hcons : constr Hashcons.fval hasheq_kind : ((_, _, _, _, _) kind_of_term as 'k) -> 'k -> boolChecks physical equality of every immediate element (goes inside tuples and arrays)
val mkConst : Names.Constant.t -> constrval mkInd : Names.inductive -> constrval mkConstruct : Names.constructor -> constrval hcons_annot : Names.Name.t binder_annot Hashcons.fval hcons_caseinfo : case_info Hashcons.fval hash_cast_kind : cast_kind -> int