aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--API/API.mli29
-rw-r--r--checker/cic.mli4
-rw-r--r--checker/mod_checking.ml2
-rw-r--r--checker/values.ml6
-rw-r--r--dev/ci/user-overlays/01033-SkySkimmer-restrict-harder.sh9
-rw-r--r--doc/refman/RefMan-oth.tex7
-rw-r--r--engine/evd.ml13
-rw-r--r--engine/evd.mli33
-rw-r--r--engine/uState.ml168
-rw-r--r--engine/uState.mli41
-rw-r--r--engine/universes.ml53
-rw-r--r--engine/universes.mli15
-rw-r--r--engine/univops.ml94
-rw-r--r--interp/declare.ml23
-rw-r--r--interp/declare.mli6
-rw-r--r--interp/modintern.ml2
-rw-r--r--intf/vernacexpr.ml6
-rw-r--r--kernel/declarations.ml6
-rw-r--r--kernel/declareops.ml4
-rw-r--r--kernel/entries.ml10
-rw-r--r--kernel/indtypes.ml9
-rw-r--r--kernel/mod_typing.ml26
-rw-r--r--kernel/safe_typing.ml12
-rw-r--r--kernel/term_typing.ml46
-rw-r--r--kernel/term_typing.mli2
-rw-r--r--kernel/univ.ml1
-rw-r--r--kernel/univ.mli5
-rw-r--r--kernel/vconv.ml2
-rw-r--r--parsing/g_vernac.ml411
-rw-r--r--plugins/funind/functional_principles_types.ml7
-rw-r--r--plugins/funind/recdef.ml8
-rw-r--r--plugins/ltac/extratactics.ml46
-rw-r--r--plugins/ltac/rewrite.ml7
-rw-r--r--plugins/setoid_ring/newring.ml10
-rw-r--r--pretyping/pretyping.ml43
-rw-r--r--pretyping/pretyping.mli3
-rw-r--r--pretyping/univdecls.ml22
-rw-r--r--printing/ppvernac.ml13
-rw-r--r--printing/prettyp.ml99
-rw-r--r--printing/prettyp.mli10
-rw-r--r--printing/printer.ml11
-rw-r--r--printing/printer.mli2
-rw-r--r--printing/printmod.ml24
-rw-r--r--printing/printmod.mli4
-rw-r--r--proofs/proof_global.ml39
-rw-r--r--tactics/ind_tables.ml5
-rw-r--r--tactics/leminv.ml11
-rw-r--r--test-suite/Makefile3
-rw-r--r--test-suite/bugs/closed/3690.v75
-rw-r--r--test-suite/bugs/closed/5347.v10
-rw-r--r--test-suite/bugs/closed/5717.v5
-rw-r--r--test-suite/output/UnivBinders.out151
-rw-r--r--test-suite/output/UnivBinders.v92
-rw-r--r--test-suite/prerequisite/bind_univs.v5
-rw-r--r--test-suite/success/polymorphism.v38
-rw-r--r--vernac/class.ml4
-rw-r--r--vernac/classes.ml46
-rw-r--r--vernac/command.ml208
-rw-r--r--vernac/command.mli2
-rw-r--r--vernac/declareDef.ml4
-rw-r--r--vernac/declareDef.mli7
-rw-r--r--vernac/indschemes.ml6
-rw-r--r--vernac/lemmas.ml46
-rw-r--r--vernac/obligations.ml164
-rw-r--r--vernac/record.ml128
-rw-r--r--vernac/record.mli24
-rw-r--r--vernac/vernacentries.ml17
67 files changed, 1291 insertions, 713 deletions
diff --git a/API/API.mli b/API/API.mli
index 0270cfc12..830c0a0f6 100644
--- a/API/API.mli
+++ b/API/API.mli
@@ -1423,7 +1423,7 @@ sig
| TemplateArity of 'b
type constant_universes =
- | Monomorphic_const of Univ.UContext.t
+ | Monomorphic_const of Univ.ContextSet.t
| Polymorphic_const of Univ.AUContext.t
type projection_body = {
@@ -1490,7 +1490,7 @@ sig
| MEwith of module_alg_expr * with_declaration
type abstract_inductive_universes =
- | Monomorphic_ind of Univ.UContext.t
+ | Monomorphic_ind of Univ.ContextSet.t
| Polymorphic_ind of Univ.AUContext.t
| Cumulative_ind of Univ.ACumulativityInfo.t
@@ -1557,7 +1557,7 @@ sig
| LocalAssumEntry of constr
type inductive_universes =
- | Monomorphic_ind_entry of Univ.UContext.t
+ | Monomorphic_ind_entry of Univ.ContextSet.t
| Polymorphic_ind_entry of Univ.UContext.t
| Cumulative_ind_entry of Univ.CumulativityInfo.t
@@ -1586,8 +1586,9 @@ sig
type 'a proof_output = Constr.t Univ.in_universe_context_set * 'a
type 'a const_entry_body = 'a proof_output Future.computation
type constant_universes_entry =
- | Monomorphic_const_entry of Univ.UContext.t
+ | Monomorphic_const_entry of Univ.ContextSet.t
| Polymorphic_const_entry of Univ.UContext.t
+ type 'a in_constant_universes_entry = 'a * constant_universes_entry
type 'a definition_entry =
{ const_entry_body : 'a const_entry_body;
(* List of section variables *)
@@ -1598,7 +1599,7 @@ sig
const_entry_universes : constant_universes_entry;
const_entry_opaque : bool;
const_entry_inline_code : bool }
- type parameter_entry = Context.Named.t option * bool * Constr.types Univ.in_universe_context * inline
+ type parameter_entry = Context.Named.t option * Constr.types in_constant_universes_entry * inline
type projection_entry = {
proj_entry_ind : MutInd.t;
@@ -2769,6 +2770,9 @@ sig
val context_set : t -> Univ.ContextSet.t
val of_context_set : Univ.ContextSet.t -> t
+ val const_univ_entry : poly:bool -> t -> Entries.constant_universes_entry
+ val ind_univ_entry : poly:bool -> t -> Entries.inductive_universes
+
type rigid =
| UnivRigid
| UnivFlexible of bool
@@ -2878,7 +2882,7 @@ sig
val clear_metas : evar_map -> evar_map
(** Allocates a new evar that represents a {i sort}. *)
- val new_sort_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Sorts.t
+ val new_sort_variable : ?loc:Loc.t -> ?name:Names.Id.t -> rigid -> evar_map -> evar_map * Sorts.t
val remove : evar_map -> Evar.t -> evar_map
val fresh_global : ?loc:Loc.t -> ?rigid:rigid -> ?names:Univ.Instance.t -> Environ.env ->
@@ -2890,11 +2894,14 @@ sig
val universe_context_set : evar_map -> Univ.ContextSet.t
val evar_ident : Evar.t -> evar_map -> Names.Id.t option
val extract_all_conv_pbs : evar_map -> evar_map * evar_constraint list
- val universe_context : names:(Names.Id.t Loc.located) list -> extensible:bool -> evar_map ->
- (Names.Id.t * Univ.Level.t) list * Univ.UContext.t
+ val universe_binders : evar_map -> Universes.universe_binders
val nf_constraints : evar_map -> evar_map
val from_ctx : UState.t -> evar_map
+ val to_universe_context : evar_map -> Univ.UContext.t
+ val const_univ_entry : poly:bool -> evar_map -> Entries.constant_universes_entry
+ val ind_univ_entry : poly:bool -> evar_map -> Entries.inductive_universes
+
val meta_list : evar_map -> (Constr.metavariable * clbinding) list
val meta_defined : evar_map -> Constr.metavariable -> bool
@@ -4677,11 +4684,11 @@ sig
val declare_definition :
?internal:internal_flag -> ?opaque:bool -> ?kind:Decl_kinds.definition_object_kind ->
- ?local:bool -> ?poly:Decl_kinds.polymorphic -> Names.Id.t -> ?types:Constr.t ->
- Constr.t Univ.in_universe_context_set -> Names.Constant.t
+ ?local:bool -> Names.Id.t -> ?types:Constr.t ->
+ Constr.t Entries.in_constant_universes_entry -> Names.Constant.t
val definition_entry : ?fix_exn:Future.fix_exn ->
?opaque:bool -> ?inline:bool -> ?types:Constr.types ->
- ?poly:Decl_kinds.polymorphic -> ?univs:Univ.UContext.t ->
+ ?univs:Entries.constant_universes_entry ->
?eff:Safe_typing.private_constants -> Constr.t -> Safe_typing.private_constants Entries.definition_entry
val definition_message : Names.Id.t -> unit
val declare_variable : Names.Id.t -> variable_declaration -> Libnames.object_name
diff --git a/checker/cic.mli b/checker/cic.mli
index 354650964..4a0e706aa 100644
--- a/checker/cic.mli
+++ b/checker/cic.mli
@@ -208,7 +208,7 @@ type constant_def =
| OpaqueDef of lazy_constr
type constant_universes =
- | Monomorphic_const of Univ.universe_context
+ | Monomorphic_const of Univ.ContextSet.t
| Polymorphic_const of Univ.abstract_universe_context
(** The [typing_flags] are instructions to the type-checker which
@@ -303,7 +303,7 @@ type one_inductive_body = {
}
type abstract_inductive_universes =
- | Monomorphic_ind of Univ.universe_context
+ | Monomorphic_ind of Univ.ContextSet.t
| Polymorphic_ind of Univ.abstract_universe_context
| Cumulative_ind of Univ.abstract_cumulativity_info
diff --git a/checker/mod_checking.ml b/checker/mod_checking.ml
index 63e28448f..4357a690e 100644
--- a/checker/mod_checking.ml
+++ b/checker/mod_checking.ml
@@ -29,7 +29,7 @@ let check_constant_declaration env kn cb =
(** [env'] contains De Bruijn universe variables *)
let env' =
match cb.const_universes with
- | Monomorphic_const ctx -> push_context ~strict:true ctx env
+ | Monomorphic_const ctx -> push_context_set ~strict:true ctx env
| Polymorphic_const auctx ->
let ctx = Univ.AUContext.repr auctx in
push_context ~strict:false ctx env
diff --git a/checker/values.ml b/checker/values.ml
index 9e16c8435..5a371164c 100644
--- a/checker/values.ml
+++ b/checker/values.ml
@@ -13,7 +13,7 @@
To ensure this file is up-to-date, 'make' now compares the md5 of cic.mli
with a copy we maintain here:
-MD5 f4b00c567a972ae950b9ed10c533fda5 checker/cic.mli
+MD5 56ac4cade33eff3d26ed5cdadb580c7e checker/cic.mli
*)
@@ -215,7 +215,7 @@ let v_projbody =
let v_typing_flags =
v_tuple "typing_flags" [|v_bool; v_bool|]
-let v_const_univs = v_sum "constant_universes" 0 [|[|v_context|]; [|v_abs_context|]|]
+let v_const_univs = v_sum "constant_universes" 0 [|[|v_context_set|]; [|v_abs_context|]|]
let v_cb = v_tuple "constant_body"
[|v_section_ctxt;
@@ -265,7 +265,7 @@ let v_mind_record = Annot ("mind_record",
let v_ind_pack_univs =
v_sum "abstract_inductive_universes" 0
- [|[|v_context|]; [|v_abs_context|]; [|v_abs_cum_info|]|]
+ [|[|v_context_set|]; [|v_abs_context|]; [|v_abs_cum_info|]|]
let v_ind_pack = v_tuple "mutual_inductive_body"
[|Array v_one_ind;
diff --git a/dev/ci/user-overlays/01033-SkySkimmer-restrict-harder.sh b/dev/ci/user-overlays/01033-SkySkimmer-restrict-harder.sh
new file mode 100644
index 000000000..5c4dd1324
--- /dev/null
+++ b/dev/ci/user-overlays/01033-SkySkimmer-restrict-harder.sh
@@ -0,0 +1,9 @@
+if [ "$TRAVIS_PULL_REQUEST" = "1033" ] || [ "$TRAVIS_BRANCH" = "restrict-harder" ]; then
+ formal_topology_CI_BRANCH=ci
+ formal_topology_CI_GITURL=https://github.com/SkySkimmer/topology.git
+
+ HoTT_CI_BRANCH=coq-pr-1033
+ HoTT_CI_GITURL=https://github.com/SkySkimmer/HoTT.git
+
+ Equations_CI_GITURL=https://github.com/SkySkimmer/Coq-Equations.git
+fi
diff --git a/doc/refman/RefMan-oth.tex b/doc/refman/RefMan-oth.tex
index 60cd8b73a..3ebeba178 100644
--- a/doc/refman/RefMan-oth.tex
+++ b/doc/refman/RefMan-oth.tex
@@ -10,6 +10,8 @@ defined object referred by {\qualid}.
\begin{ErrMsgs}
\item {\qualid} \errindex{not a defined object}
+\item \errindex{Universe instance should have length} $n$.
+\item \errindex{This object does not support universe names.}
\end{ErrMsgs}
\begin{Variants}
@@ -27,6 +29,11 @@ constructor, abbreviation, \ldots), long name, type, implicit
arguments and argument scopes. It does not print the body of
definitions or proofs.
+\item {\tt Print {\qualid}@\{names\}.}\\
+This locally renames the polymorphic universes of {\qualid}.
+An underscore means the raw universe is printed.
+This form can be used with {\tt Print Term} and {\tt About}.
+
%\item {\tt Print Proof {\qualid}.}\comindex{Print Proof}\\
%In case \qualid\ denotes an opaque theorem defined in a section,
%it is stored on a special unprintable form and displayed as
diff --git a/engine/evd.ml b/engine/evd.ml
index ecef04204..d57ae89dd 100644
--- a/engine/evd.ml
+++ b/engine/evd.ml
@@ -756,10 +756,12 @@ let evar_universe_context d = d.universes
let universe_context_set d = UState.context_set d.universes
-let universe_context ~names ~extensible evd =
- UState.universe_context ~names ~extensible evd.universes
+let to_universe_context evd = UState.context evd.universes
-let check_univ_decl evd decl = UState.check_univ_decl evd.universes decl
+let const_univ_entry ~poly evd = UState.const_univ_entry ~poly evd.universes
+let ind_univ_entry ~poly evd = UState.ind_univ_entry ~poly evd.universes
+
+let check_univ_decl ~poly evd decl = UState.check_univ_decl ~poly evd.universes decl
let restrict_universe_context evd vars =
{ evd with universes = UState.restrict evd.universes vars }
@@ -802,7 +804,7 @@ let make_evar_universe_context e l =
| Some us ->
List.fold_left
(fun uctx (loc,id) ->
- fst (UState.new_univ_variable ?loc univ_rigid (Some (Id.to_string id)) uctx))
+ fst (UState.new_univ_variable ?loc univ_rigid (Some id) uctx))
uctx us
(****************************************)
@@ -933,8 +935,7 @@ let nf_constraints evd =
let universe_of_name evd s = UState.universe_of_name evd.universes s
-let add_universe_name evd s l =
- { evd with universes = UState.add_universe_name evd.universes s l }
+let universe_binders evd = UState.universe_binders evd.universes
let universes evd = UState.ugraph evd.universes
diff --git a/engine/evd.mli b/engine/evd.mli
index aed2d7083..fb5a6cd16 100644
--- a/engine/evd.mli
+++ b/engine/evd.mli
@@ -493,6 +493,8 @@ type 'a in_evar_universe_context = 'a * UState.t
val evar_universe_context_set : UState.t -> Univ.ContextSet.t
val evar_universe_context_constraints : UState.t -> Univ.constraints
val evar_context_universe_context : UState.t -> Univ.UContext.t
+[@@ocaml.deprecated "alias of UState.context"]
+
val evar_universe_context_of : Univ.ContextSet.t -> UState.t
val empty_evar_universe_context : UState.t
val union_evar_universe_context : UState.t -> UState.t ->
@@ -503,14 +505,14 @@ val constrain_variables : Univ.LSet.t -> UState.t -> UState.t
val evar_universe_context_of_binders :
Universes.universe_binders -> UState.t
-
+
val make_evar_universe_context : env -> (Id.t located) list option -> UState.t
-val restrict_universe_context : evar_map -> Univ.LSet.t -> evar_map
+val restrict_universe_context : evar_map -> Univ.LSet.t -> evar_map
(** Raises Not_found if not a name for a universe in this map. *)
-val universe_of_name : evar_map -> string -> Univ.Level.t
-val add_universe_name : evar_map -> string -> Univ.Level.t -> evar_map
+val universe_of_name : evar_map -> Id.t -> Univ.Level.t
-val add_constraints_context : UState.t ->
+val universe_binders : evar_map -> Universes.universe_binders
+val add_constraints_context : UState.t ->
Univ.constraints -> UState.t
@@ -520,9 +522,9 @@ val normalize_evar_universe_context_variables : UState.t ->
val normalize_evar_universe_context : UState.t ->
UState.t
-val new_univ_level_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Univ.Level.t
-val new_univ_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Univ.Universe.t
-val new_sort_variable : ?loc:Loc.t -> ?name:string -> rigid -> evar_map -> evar_map * Sorts.t
+val new_univ_level_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Level.t
+val new_univ_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Univ.Universe.t
+val new_sort_variable : ?loc:Loc.t -> ?name:Id.t -> rigid -> evar_map -> evar_map * Sorts.t
val add_global_univ : evar_map -> Univ.Level.t -> evar_map
@@ -552,13 +554,20 @@ val check_leq : evar_map -> Univ.Universe.t -> Univ.Universe.t -> bool
val evar_universe_context : evar_map -> UState.t
val universe_context_set : evar_map -> Univ.ContextSet.t
-val universe_context : names:(Id.t located) list -> extensible:bool -> evar_map ->
- (Id.t * Univ.Level.t) list * Univ.UContext.t
val universe_subst : evar_map -> Universes.universe_opt_subst
val universes : evar_map -> UGraph.t
-val check_univ_decl : evar_map -> UState.universe_decl ->
- Universes.universe_binders * Univ.UContext.t
+(** [to_universe_context evm] extracts the local universes and
+ constraints of [evm] and orders the universes the same as
+ [Univ.ContextSet.to_context]. *)
+val to_universe_context : evar_map -> Univ.UContext.t
+
+val const_univ_entry : poly:bool -> evar_map -> Entries.constant_universes_entry
+
+(** NB: [ind_univ_entry] cannot create cumulative entries. *)
+val ind_univ_entry : poly:bool -> evar_map -> Entries.inductive_universes
+
+val check_univ_decl : poly:bool -> evar_map -> UState.universe_decl -> Entries.constant_universes_entry
val merge_universe_context : evar_map -> UState.t -> evar_map
val set_universe_context : evar_map -> UState.t -> evar_map
diff --git a/engine/uState.ml b/engine/uState.ml
index 01a479821..4e30640e4 100644
--- a/engine/uState.ml
+++ b/engine/uState.ml
@@ -11,28 +11,16 @@ open CErrors
open Util
open Names
-module StringOrd = struct type t = string let compare = String.compare end
-module UNameMap = struct
+module UNameMap = Names.Id.Map
- include Map.Make(StringOrd)
-
- let union s t =
- if s == t then s
- else
- merge (fun k l r ->
- match l, r with
- | Some _, _ -> l
- | _, _ -> r) s t
-end
-
type uinfo = {
- uname : string option;
+ uname : Id.t option;
uloc : Loc.t option;
}
(* 2nd part used to check consistency on the fly. *)
type t =
- { uctx_names : Univ.Level.t UNameMap.t * uinfo Univ.LMap.t;
+ { uctx_names : Universes.universe_binders * uinfo Univ.LMap.t;
uctx_local : Univ.ContextSet.t; (** The local context of variables *)
uctx_univ_variables : Universes.universe_opt_subst;
(** The local universes that are unification variables *)
@@ -59,12 +47,20 @@ let is_empty ctx =
Univ.ContextSet.is_empty ctx.uctx_local &&
Univ.LMap.is_empty ctx.uctx_univ_variables
+let uname_union s t =
+ if s == t then s
+ else
+ UNameMap.merge (fun k l r ->
+ match l, r with
+ | Some _, _ -> l
+ | _, _ -> r) s t
+
let union ctx ctx' =
if ctx == ctx' then ctx
else if is_empty ctx' then ctx
else
let local = Univ.ContextSet.union ctx.uctx_local ctx'.uctx_local in
- let names = UNameMap.union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
+ let names = uname_union (fst ctx.uctx_names) (fst ctx'.uctx_names) in
let newus = Univ.LSet.diff (Univ.ContextSet.levels ctx'.uctx_local)
(Univ.ContextSet.levels ctx.uctx_local) in
let newus = Univ.LSet.diff newus (Univ.LMap.domain ctx.uctx_univ_variables) in
@@ -91,6 +87,17 @@ let constraints ctx = snd ctx.uctx_local
let context ctx = Univ.ContextSet.to_context ctx.uctx_local
+let const_univ_entry ~poly uctx =
+ let open Entries in
+ if poly then Polymorphic_const_entry (context uctx)
+ else Monomorphic_const_entry (context_set uctx)
+
+(* does not support cumulativity since you need more info *)
+let ind_univ_entry ~poly uctx =
+ let open Entries in
+ if poly then Polymorphic_ind_entry (context uctx)
+ else Monomorphic_ind_entry (context_set uctx)
+
let of_context_set ctx = { empty with uctx_local = ctx }
let subst ctx = ctx.uctx_univ_variables
@@ -102,6 +109,9 @@ let initial_graph ctx = ctx.uctx_initial_universes
let algebraics ctx = ctx.uctx_univ_algebraic
let add_uctx_names ?loc s l (names, names_rev) =
+ if UNameMap.mem s names
+ then user_err ?loc ~hdr:"add_uctx_names"
+ Pp.(str "Universe " ++ Names.Id.print s ++ str" already bound.");
(UNameMap.add s l names, Univ.LMap.add l { uname = Some s; uloc = loc } names_rev)
let add_uctx_loc l loc (names, names_rev) =
@@ -111,10 +121,14 @@ let add_uctx_loc l loc (names, names_rev) =
let of_binders b =
let ctx = empty in
- let names =
- List.fold_left (fun acc (id, l) -> add_uctx_names (Id.to_string id) l acc)
- ctx.uctx_names b
- in { ctx with uctx_names = names }
+ let rmap =
+ UNameMap.fold (fun id l rmap ->
+ Univ.LMap.add l { uname = Some id; uloc = None } rmap)
+ b Univ.LMap.empty
+ in
+ { ctx with uctx_names = b, rmap }
+
+let universe_binders ctx = fst ctx.uctx_names
let instantiate_variable l b v =
try v := Univ.LMap.update l (Some b) !v
@@ -253,69 +267,105 @@ let constrain_variables diff ctx =
let pr_uctx_level uctx =
let map, map_rev = uctx.uctx_names in
fun l ->
- try str (Option.get (Univ.LMap.find l map_rev).uname)
+ try Id.print (Option.get (Univ.LMap.find l map_rev).uname)
with Not_found | Option.IsNone ->
Universes.pr_with_global_universes l
type universe_decl =
(Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
-let universe_context ~names ~extensible ctx =
- let levels = Univ.ContextSet.levels ctx.uctx_local in
+let error_unbound_universes left uctx =
+ let open Univ in
+ let n = LSet.cardinal left in
+ let loc =
+ try
+ let info =
+ LMap.find (LSet.choose left) (snd uctx.uctx_names) in
+ info.uloc
+ with Not_found -> None
+ in
+ user_err ?loc ~hdr:"universe_context"
+ ((str(CString.plural n "Universe") ++ spc () ++
+ LSet.pr (pr_uctx_level uctx) left ++
+ spc () ++ str (CString.conjugate_verb_to_be n) ++
+ str" unbound."))
+
+let universe_context ~names ~extensible uctx =
+ let open Univ in
+ let levels = ContextSet.levels uctx.uctx_local in
let newinst, left =
List.fold_right
(fun (loc,id) (newinst, acc) ->
let l =
- try UNameMap.find (Id.to_string id) (fst ctx.uctx_names)
- with Not_found ->
- user_err ?loc ~hdr:"universe_context"
- (str"Universe " ++ Id.print id ++ str" is not bound anymore.")
- in (l :: newinst, Univ.LSet.remove l acc))
+ try UNameMap.find id (fst uctx.uctx_names)
+ with Not_found -> assert false
+ in (l :: newinst, LSet.remove l acc))
names ([], levels)
in
- if not extensible && not (Univ.LSet.is_empty left) then
- let n = Univ.LSet.cardinal left in
- let loc =
- try
- let info =
- Univ.LMap.find (Univ.LSet.choose left) (snd ctx.uctx_names) in
- info.uloc
- with Not_found -> None
- in
- user_err ?loc ~hdr:"universe_context"
- ((str(CString.plural n "Universe") ++ spc () ++
- Univ.LSet.pr (pr_uctx_level ctx) left ++
- spc () ++ str (CString.conjugate_verb_to_be n) ++
- str" unbound."))
+ if not extensible && not (LSet.is_empty left)
+ then error_unbound_universes left uctx
else
- let left = Univ.ContextSet.sort_levels (Array.of_list (Univ.LSet.elements left)) in
+ let left = ContextSet.sort_levels (Array.of_list (LSet.elements left)) in
let inst = Array.append (Array.of_list newinst) left in
- let inst = Univ.Instance.of_array inst in
- let map = List.map (fun (s,l) -> Id.of_string s, l) (UNameMap.bindings (fst ctx.uctx_names)) in
- let ctx = Univ.UContext.make (inst,
- Univ.ContextSet.constraints ctx.uctx_local) in
- map, ctx
+ let inst = Instance.of_array inst in
+ let ctx = UContext.make (inst, ContextSet.constraints uctx.uctx_local) in
+ ctx
+
+let check_universe_context_set ~names ~extensible uctx =
+ if extensible then ()
+ else
+ let open Univ in
+ let left = List.fold_left (fun left (loc,id) ->
+ let l =
+ try UNameMap.find id (fst uctx.uctx_names)
+ with Not_found -> assert false
+ in LSet.remove l left)
+ (ContextSet.levels uctx.uctx_local) names
+ in
+ if not (LSet.is_empty left)
+ then error_unbound_universes left uctx
-let check_implication uctx cstrs ctx =
+let check_implication uctx cstrs cstrs' =
let gr = initial_graph uctx in
let grext = UGraph.merge_constraints cstrs gr in
- let cstrs' = Univ.UContext.constraints ctx in
if UGraph.check_constraints cstrs' grext then ()
else CErrors.user_err ~hdr:"check_univ_decl"
(str "Universe constraints are not implied by the ones declared.")
-let check_univ_decl uctx decl =
+let check_mono_univ_decl uctx decl =
let open Misctypes in
- let pl, ctx = universe_context
- ~names:decl.univdecl_instance
- ~extensible:decl.univdecl_extensible_instance
- uctx
+ let () =
+ let names = decl.univdecl_instance in
+ let extensible = decl.univdecl_extensible_instance in
+ check_universe_context_set ~names ~extensible uctx
in
if not decl.univdecl_extensible_constraints then
- check_implication uctx decl.univdecl_constraints ctx;
- pl, ctx
+ check_implication uctx
+ decl.univdecl_constraints
+ (Univ.ContextSet.constraints uctx.uctx_local);
+ uctx.uctx_local
+
+let check_univ_decl ~poly uctx decl =
+ let open Misctypes in
+ let ctx =
+ let names = decl.univdecl_instance in
+ let extensible = decl.univdecl_extensible_instance in
+ if poly
+ then Entries.Polymorphic_const_entry (universe_context ~names ~extensible uctx)
+ else
+ let () = check_universe_context_set ~names ~extensible uctx in
+ Entries.Monomorphic_const_entry uctx.uctx_local
+ in
+ if not decl.univdecl_extensible_constraints then
+ check_implication uctx
+ decl.univdecl_constraints
+ (Univ.ContextSet.constraints uctx.uctx_local);
+ ctx
let restrict ctx vars =
+ let vars = Names.Id.Map.fold (fun na l vars -> Univ.LSet.add l vars)
+ (fst ctx.uctx_names) vars
+ in
let uctx' = Univops.restrict_universe_context ctx.uctx_local vars in
{ ctx with uctx_local = uctx' }
@@ -526,10 +576,6 @@ let normalize uctx =
let universe_of_name uctx s =
UNameMap.find s (fst uctx.uctx_names)
-let add_universe_name uctx s l =
- let names' = add_uctx_names s l uctx.uctx_names in
- { uctx with uctx_names = names' }
-
let update_sigma_env uctx env =
let univs = Environ.universes env in
let eunivs =
diff --git a/engine/uState.mli b/engine/uState.mli
index 1c906fcb2..16fba41e0 100644
--- a/engine/uState.mli
+++ b/engine/uState.mli
@@ -32,6 +32,8 @@ val of_context_set : Univ.ContextSet.t -> t
val of_binders : Universes.universe_binders -> t
+val universe_binders : t -> Universes.universe_binders
+
(** {5 Projections} *)
val context_set : t -> Univ.ContextSet.t
@@ -57,6 +59,13 @@ val constraints : t -> Univ.constraints
val context : t -> Univ.UContext.t
(** Shorthand for {!context_set} with {!Context_set.to_context}. *)
+val const_univ_entry : poly:bool -> t -> Entries.constant_universes_entry
+(** Pick from {!context} or {!context_set} based on [poly]. *)
+
+val ind_univ_entry : poly:bool -> t -> Entries.inductive_universes
+(** Pick from {!context} or {!context_set} based on [poly].
+ Cannot create cumulative entries. *)
+
(** {5 Constraints handling} *)
val add_constraints : t -> Univ.constraints -> t
@@ -71,10 +80,7 @@ val add_universe_constraints : t -> Universes.universe_constraints -> t
(** {5 Names} *)
-val add_universe_name : t -> string -> Univ.Level.t -> t
-(** Associate a human-readable name to a local variable. *)
-
-val universe_of_name : t -> string -> Univ.Level.t
+val universe_of_name : t -> Id.t -> Univ.Level.t
(** Retrieve the universe associated to the name. *)
(** {5 Unification} *)
@@ -93,7 +99,7 @@ val merge : ?loc:Loc.t -> bool -> rigid -> t -> Univ.ContextSet.t -> t
val merge_subst : t -> Universes.universe_opt_subst -> t
val emit_side_effects : Safe_typing.private_constants -> t -> t
-val new_univ_variable : ?loc:Loc.t -> rigid -> string option -> t -> t * Univ.Level.t
+val new_univ_variable : ?loc:Loc.t -> rigid -> Id.t option -> t -> t * Univ.Level.t
val add_global_univ : t -> Univ.Level.t -> t
(** [make_flexible_variable g algebraic l]
@@ -123,24 +129,23 @@ val refresh_undefined_univ_variables : t -> t * Univ.universe_level_subst
val normalize : t -> t
-(** [universe_context names extensible ctx]
+type universe_decl =
+ (Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
- Return a universe context containing the local universes of [ctx]
- and their constraints. The universes corresponding to [names] come
- first in the order defined by that list.
+(** [check_univ_decl ctx decl]
- If [extensible] is false, check that the universes of [names] are
- the only local universes.
+ If non extensible in [decl], check that the local universes (resp.
+ universe constraints) in [ctx] are implied by [decl].
- Also return the association list of universe names and universes
- (including those not in [names]). *)
-val universe_context : names:(Id.t Loc.located) list -> extensible:bool -> t ->
- (Id.t * Univ.Level.t) list * Univ.UContext.t
+ Return a [Entries.constant_universes_entry] containing the local
+ universes of [ctx] and their constraints.
-type universe_decl =
- (Names.Id.t Loc.located list, Univ.Constraint.t) Misctypes.gen_universe_decl
+ When polymorphic, the universes corresponding to
+ [decl.univdecl_instance] come first in the order defined by that
+ list. *)
+val check_univ_decl : poly:bool -> t -> universe_decl -> Entries.constant_universes_entry
-val check_univ_decl : t -> universe_decl -> Universes.universe_binders * Univ.UContext.t
+val check_mono_univ_decl : t -> universe_decl -> Univ.ContextSet.t
(** {5 TODO: Document me} *)
diff --git a/engine/universes.ml b/engine/universes.ml
index 6c1b64d74..5ac1bc685 100644
--- a/engine/universes.ml
+++ b/engine/universes.ml
@@ -21,18 +21,63 @@ let pr_with_global_universes l =
(** Local universe names of polymorphic references *)
-type universe_binders = (Id.t * Univ.Level.t) list
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+let empty_binders = Id.Map.empty
let universe_binders_table = Summary.ref Refmap.empty ~name:"universe binders"
-let universe_binders_of_global ref =
+let universe_binders_of_global ref : universe_binders =
try
let l = Refmap.find ref !universe_binders_table in l
- with Not_found -> []
+ with Not_found -> Names.Id.Map.empty
-let register_universe_binders ref l =
+let cache_ubinder (_,(ref,l)) =
universe_binders_table := Refmap.add ref l !universe_binders_table
+let subst_ubinder (subst,(ref,l as orig)) =
+ let ref' = fst (Globnames.subst_global subst ref) in
+ if ref == ref' then orig else ref', l
+
+let discharge_ubinder (_,(ref,l)) =
+ Some (Lib.discharge_global ref, l)
+
+let ubinder_obj : Globnames.global_reference * universe_binders -> Libobject.obj =
+ let open Libobject in
+ declare_object { (default_object "universe binder") with
+ cache_function = cache_ubinder;
+ load_function = (fun _ x -> cache_ubinder x);
+ classify_function = (fun x -> Substitute x);
+ subst_function = subst_ubinder;
+ discharge_function = discharge_ubinder;
+ rebuild_function = (fun x -> x); }
+
+let register_universe_binders ref ubinders =
+ (* Add the polymorphic (section) universes *)
+ let open Names in
+ let ubinders = Id.Map.fold (fun id (poly,lvl) ubinders ->
+ if poly then Id.Map.add id lvl ubinders
+ else ubinders)
+ (fst (Global.global_universe_names ())) ubinders
+ in
+ if not (Id.Map.is_empty ubinders)
+ then Lib.add_anonymous_leaf (ubinder_obj (ref,ubinders))
+
+type univ_name_list = Name.t Loc.located list
+
+let universe_binders_with_opt_names ref levels = function
+ | None -> universe_binders_of_global ref
+ | Some udecl ->
+ if Int.equal(List.length levels) (List.length udecl)
+ then
+ List.fold_left2 (fun acc (_,na) lvl -> match na with
+ | Anonymous -> acc
+ | Name na -> Names.Id.Map.add na lvl acc)
+ empty_binders udecl levels
+ else
+ CErrors.user_err ~hdr:"universe_binders_with_opt_names"
+ Pp.(str "Universe instance should have length " ++ int (List.length levels))
+
(* To disallow minimization to Set *)
let set_minimization = ref true
diff --git a/engine/universes.mli b/engine/universes.mli
index a960099ed..1401c4ee8 100644
--- a/engine/universes.mli
+++ b/engine/universes.mli
@@ -21,11 +21,24 @@ val pr_with_global_universes : Level.t -> Pp.t
(** Local universe name <-> level mapping *)
-type universe_binders = (Id.t * Univ.Level.t) list
+type universe_binders = Univ.Level.t Names.Id.Map.t
+
+val empty_binders : universe_binders
val register_universe_binders : Globnames.global_reference -> universe_binders -> unit
val universe_binders_of_global : Globnames.global_reference -> universe_binders
+type univ_name_list = Name.t Loc.located list
+
+(** [universe_binders_with_opt_names ref u l]
+
+ If [l] is [Some univs] return the universe binders naming the levels of [u] by [univs] (skipping Anonymous).
+ May error if the lengths mismatch.
+
+ Otherwise return [universe_binders_of_global ref]. *)
+val universe_binders_with_opt_names : Globnames.global_reference ->
+ Univ.Level.t list -> univ_name_list option -> universe_binders
+
(** The global universe counter *)
val set_remote_new_univ_level : Level.t RemoteCounter.installer
diff --git a/engine/univops.ml b/engine/univops.ml
index d498b2e0d..9a9ae12ca 100644
--- a/engine/univops.ml
+++ b/engine/univops.ml
@@ -20,21 +20,79 @@ let universes_of_constr c =
| _ -> Constr.fold aux s c
in aux LSet.empty c
-let restrict_universe_context (univs,csts) s =
- (* Universes that are not necessary to typecheck the term.
- E.g. univs introduced by tactics and not used in the proof term. *)
- let diff = LSet.diff univs s in
- let rec aux diff candid univs ness =
- let (diff', candid', univs', ness') =
- Constraint.fold
- (fun (l, d, r as c) (diff, candid, univs, csts) ->
- if not (LSet.mem l diff) then
- (LSet.remove r diff, candid, univs, Constraint.add c csts)
- else if not (LSet.mem r diff) then
- (LSet.remove l diff, candid, univs, Constraint.add c csts)
- else (diff, Constraint.add c candid, univs, csts))
- candid (diff, Constraint.empty, univs, ness)
- in
- if ness' == ness then (LSet.diff univs diff', ness)
- else aux diff' candid' univs' ness'
- in aux diff csts univs Constraint.empty
+type graphnode = {
+ mutable up : constraint_type LMap.t;
+ mutable visited : bool
+}
+
+let merge_types d d0 =
+ match d, d0 with
+ | _, Lt | Lt, _ -> Lt
+ | Le, _ | _, Le -> Le
+ | Eq, Eq -> Eq
+
+let merge_up d b up =
+ let find = try Some (LMap.find b up) with Not_found -> None in
+ match find with
+ | Some d0 ->
+ let d = merge_types d d0 in
+ if d == d0 then up else LMap.add b d up
+ | None -> LMap.add b d up
+
+let add_up a d b graph =
+ let node, graph =
+ try LMap.find a graph, graph
+ with Not_found ->
+ let node = { up = LMap.empty; visited = false } in
+ node, LMap.add a node graph
+ in
+ node.up <- merge_up d b node.up;
+ graph
+
+(* for each node transitive close until you find a non removable, discard the rest *)
+let transitive_close removable graph =
+ let rec do_node a node =
+ if not node.visited
+ then
+ let keepup =
+ LMap.fold (fun b d keepup ->
+ if not (LSet.mem b removable)
+ then merge_up d b keepup
+ else
+ begin
+ match LMap.find b graph with
+ | bnode ->
+ do_node b bnode;
+ LMap.fold (fun k d' keepup ->
+ merge_up (merge_types d d') k keepup)
+ bnode.up keepup
+ | exception Not_found -> keepup
+ end
+ )
+ node.up LMap.empty
+ in
+ node.up <- keepup;
+ node.visited <- true
+ in
+ LMap.iter do_node graph
+
+let restrict_universe_context (univs,csts) keep =
+ let removable = LSet.diff univs keep in
+ let (csts, rem) =
+ Constraint.fold (fun (a,d,b as cst) (csts, rem) ->
+ if LSet.mem a removable || LSet.mem b removable
+ then (csts, add_up a d b rem)
+ else (Constraint.add cst csts, rem))
+ csts (Constraint.empty, LMap.empty)
+ in
+ transitive_close removable rem;
+ let csts =
+ LMap.fold (fun a node csts ->
+ if LSet.mem a removable
+ then csts
+ else
+ LMap.fold (fun b d csts -> Constraint.add (a,d,b) csts)
+ node.up csts)
+ rem csts
+ in
+ (LSet.inter univs keep, csts)
diff --git a/interp/declare.ml b/interp/declare.ml
index 1a589897b..1b4645aff 100644
--- a/interp/declare.ml
+++ b/interp/declare.ml
@@ -203,12 +203,9 @@ let declare_constant_common id cst =
update_tables c;
c
+let default_univ_entry = Monomorphic_const_entry Univ.ContextSet.empty
let definition_entry ?fix_exn ?(opaque=false) ?(inline=false) ?types
- ?(poly=false) ?(univs=Univ.UContext.empty) ?(eff=Safe_typing.empty_private_constants) body =
- let univs =
- if poly then Polymorphic_const_entry univs
- else Monomorphic_const_entry univs
- in
+ ?(univs=default_univ_entry) ?(eff=Safe_typing.empty_private_constants) body =
{ const_entry_body = Future.from_val ?fix_exn ((body,Univ.ContextSet.empty), eff);
const_entry_secctx = None;
const_entry_type = types;
@@ -261,9 +258,9 @@ let declare_constant ?(internal = UserIndividualRequest) ?(local = false) id ?(e
let declare_definition ?(internal=UserIndividualRequest)
?(opaque=false) ?(kind=Decl_kinds.Definition) ?(local = false)
- ?(poly=false) id ?types (body,ctx) =
+ id ?types (body,univs) =
let cb =
- definition_entry ?types ~poly ~univs:(Univ.ContextSet.to_context ctx) ~opaque body
+ definition_entry ?types ~univs ~opaque body
in
declare_constant ~internal ~local id
(Entries.DefinitionEntry cb, Decl_kinds.IsDefinition kind)
@@ -340,7 +337,7 @@ let dummy_inductive_entry (_,m) = ([],{
mind_entry_record = None;
mind_entry_finite = Decl_kinds.BiFinite;
mind_entry_inds = List.map dummy_one_inductive_entry m.mind_entry_inds;
- mind_entry_universes = Monomorphic_ind_entry Univ.UContext.empty;
+ mind_entry_universes = Monomorphic_ind_entry Univ.ContextSet.empty;
mind_entry_private = None;
})
@@ -457,16 +454,16 @@ let declare_universe_context poly ctx =
Lib.add_anonymous_leaf (input_universe_context (poly, ctx))
(* Discharged or not *)
-type universe_decl = polymorphic * (Id.t * Univ.Level.t) list
+type universe_decl = polymorphic * Universes.universe_binders
let cache_universes (p, l) =
let glob = Global.global_universe_names () in
let glob', ctx =
- List.fold_left (fun ((idl,lid),ctx) (id, lev) ->
+ Id.Map.fold (fun id lev ((idl,lid),ctx) ->
((Id.Map.add id (p, lev) idl,
Univ.LMap.add lev id lid),
Univ.ContextSet.add_universe lev ctx))
- (glob, Univ.ContextSet.empty) l
+ l (glob, Univ.ContextSet.empty)
in
cache_universe_context (p, ctx);
Global.set_global_universe_names glob'
@@ -487,9 +484,9 @@ let do_universe poly l =
(str"Cannot declare polymorphic universes outside sections")
in
let l =
- List.map (fun (l, id) ->
+ List.fold_left (fun acc (l, id) ->
let lev = Universes.new_univ_level (Global.current_dirpath ()) in
- (id, lev)) l
+ Id.Map.add id lev acc) Id.Map.empty l
in
Lib.add_anonymous_leaf (input_universes (poly, l))
diff --git a/interp/declare.mli b/interp/declare.mli
index 9b3194dec..d50d37368 100644
--- a/interp/declare.mli
+++ b/interp/declare.mli
@@ -42,7 +42,7 @@ type internal_flag =
(* Defaut definition entries, transparent with no secctx or proj information *)
val definition_entry : ?fix_exn:Future.fix_exn ->
?opaque:bool -> ?inline:bool -> ?types:types ->
- ?poly:polymorphic -> ?univs:Univ.UContext.t ->
+ ?univs:Entries.constant_universes_entry ->
?eff:Safe_typing.private_constants -> constr -> Safe_typing.private_constants definition_entry
(** [declare_constant id cd] declares a global declaration
@@ -56,8 +56,8 @@ val declare_constant :
val declare_definition :
?internal:internal_flag -> ?opaque:bool -> ?kind:definition_object_kind ->
- ?local:bool -> ?poly:polymorphic -> Id.t -> ?types:constr ->
- constr Univ.in_universe_context_set -> Constant.t
+ ?local:bool -> Id.t -> ?types:constr ->
+ constr Entries.in_constant_universes_entry -> Constant.t
(** Since transparent constants' side effects are globally declared, we
* need that *)
diff --git a/interp/modintern.ml b/interp/modintern.ml
index 08657936e..3eb91d8cd 100644
--- a/interp/modintern.ml
+++ b/interp/modintern.ml
@@ -62,7 +62,7 @@ let transl_with_decl env = function
WithMod (fqid,lookup_module qid)
| CWith_Definition ((_,fqid),c) ->
let c, ectx = interp_constr env (Evd.from_env env) c in
- let ctx = Evd.evar_context_universe_context ectx in
+ let ctx = UState.context ectx in
WithDef (fqid,(c,ctx))
let loc_of_module l = l.CAst.loc
diff --git a/intf/vernacexpr.ml b/intf/vernacexpr.ml
index 9aef4b131..96bcba5e8 100644
--- a/intf/vernacexpr.ml
+++ b/intf/vernacexpr.ml
@@ -40,6 +40,8 @@ type goal_reference =
| NthGoal of int
| GoalId of Id.t
+type univ_name_list = Name.t Loc.located list
+
type printable =
| PrintTables
| PrintFullContext
@@ -54,7 +56,7 @@ type printable =
| PrintMLLoadPath
| PrintMLModules
| PrintDebugGC
- | PrintName of reference or_by_notation
+ | PrintName of reference or_by_notation * univ_name_list option
| PrintGraph
| PrintClasses
| PrintTypeClasses
@@ -70,7 +72,7 @@ type printable =
| PrintScopes
| PrintScope of string
| PrintVisibility of string option
- | PrintAbout of reference or_by_notation * goal_selector option
+ | PrintAbout of reference or_by_notation * univ_name_list option * goal_selector option
| PrintImplicit of reference or_by_notation
| PrintAssumptions of bool * bool * reference or_by_notation
| PrintStrategy of reference or_by_notation option
diff --git a/kernel/declarations.ml b/kernel/declarations.ml
index b95796fd8..d5312c500 100644
--- a/kernel/declarations.ml
+++ b/kernel/declarations.ml
@@ -63,7 +63,7 @@ type constant_def =
| OpaqueDef of Opaqueproof.opaque (** or an opaque global definition *)
type constant_universes =
- | Monomorphic_const of Univ.UContext.t
+ | Monomorphic_const of Univ.ContextSet.t
| Polymorphic_const of Univ.AUContext.t
(** The [typing_flags] are instructions to the type-checker which
@@ -168,9 +168,9 @@ type one_inductive_body = {
}
type abstract_inductive_universes =
- | Monomorphic_ind of Univ.UContext.t
+ | Monomorphic_ind of Univ.ContextSet.t
| Polymorphic_ind of Univ.AUContext.t
- | Cumulative_ind of Univ.ACumulativityInfo.t
+ | Cumulative_ind of Univ.ACumulativityInfo.t
type mutual_inductive_body = {
diff --git a/kernel/declareops.ml b/kernel/declareops.ml
index f5c26b33d..d8768a0fc 100644
--- a/kernel/declareops.ml
+++ b/kernel/declareops.ml
@@ -126,7 +126,7 @@ let hcons_const_def = function
let hcons_const_universes cbu =
match cbu with
| Monomorphic_const ctx ->
- Monomorphic_const (Univ.hcons_universe_context ctx)
+ Monomorphic_const (Univ.hcons_universe_context_set ctx)
| Polymorphic_const ctx ->
Polymorphic_const (Univ.hcons_abstract_universe_context ctx)
@@ -274,7 +274,7 @@ let hcons_mind_packet oib =
let hcons_mind_universes miu =
match miu with
- | Monomorphic_ind ctx -> Monomorphic_ind (Univ.hcons_universe_context ctx)
+ | Monomorphic_ind ctx -> Monomorphic_ind (Univ.hcons_universe_context_set ctx)
| Polymorphic_ind ctx -> Polymorphic_ind (Univ.hcons_abstract_universe_context ctx)
| Cumulative_ind cui -> Cumulative_ind (Univ.hcons_abstract_cumulativity_info cui)
diff --git a/kernel/entries.ml b/kernel/entries.ml
index 185dba409..c44a17df2 100644
--- a/kernel/entries.ml
+++ b/kernel/entries.ml
@@ -35,9 +35,9 @@ then, in i{^ th} block, [mind_entry_params] is [xn:Xn;...;x1:X1];
*)
type inductive_universes =
- | Monomorphic_ind_entry of Univ.UContext.t
+ | Monomorphic_ind_entry of Univ.ContextSet.t
| Polymorphic_ind_entry of Univ.UContext.t
- | Cumulative_ind_entry of Univ.CumulativityInfo.t
+ | Cumulative_ind_entry of Univ.CumulativityInfo.t
type one_inductive_entry = {
mind_entry_typename : Id.t;
@@ -65,9 +65,11 @@ type 'a proof_output = constr Univ.in_universe_context_set * 'a
type 'a const_entry_body = 'a proof_output Future.computation
type constant_universes_entry =
- | Monomorphic_const_entry of Univ.UContext.t
+ | Monomorphic_const_entry of Univ.ContextSet.t
| Polymorphic_const_entry of Univ.UContext.t
+type 'a in_constant_universes_entry = 'a * constant_universes_entry
+
type 'a definition_entry = {
const_entry_body : 'a const_entry_body;
(* List of section variables *)
@@ -82,7 +84,7 @@ type 'a definition_entry = {
type inline = int option (* inlining level, None for no inlining *)
type parameter_entry =
- Context.Named.t option * bool * types Univ.in_universe_context * inline
+ Context.Named.t option * types in_constant_universes_entry * inline
type projection_entry = {
proj_entry_ind : MutInd.t;
diff --git a/kernel/indtypes.ml b/kernel/indtypes.ml
index 083b0ae40..8e9b606a5 100644
--- a/kernel/indtypes.ml
+++ b/kernel/indtypes.ml
@@ -265,13 +265,12 @@ let typecheck_inductive env mie =
(* Check unicity of names *)
mind_check_names mie;
(* Params are typed-checked here *)
- let univctx =
+ let env' =
match mie.mind_entry_universes with
- | Monomorphic_ind_entry ctx -> ctx
- | Polymorphic_ind_entry ctx -> ctx
- | Cumulative_ind_entry cumi -> Univ.CumulativityInfo.univ_context cumi
+ | Monomorphic_ind_entry ctx -> push_context_set ctx env
+ | Polymorphic_ind_entry ctx -> push_context ctx env
+ | Cumulative_ind_entry cumi -> push_context (Univ.CumulativityInfo.univ_context cumi) env
in
- let env' = push_context univctx env in
let (env_params,paramsctxt) = infer_local_decls env' mie.mind_entry_params in
(* We first type arity of each inductive definition *)
(* This allows building the environment of arities and to share *)
diff --git a/kernel/mod_typing.ml b/kernel/mod_typing.ml
index 8568bf14b..f7e755f00 100644
--- a/kernel/mod_typing.ml
+++ b/kernel/mod_typing.ml
@@ -79,18 +79,20 @@ let rec check_with_def env struc (idl,(c,ctx)) mp equiv =
environment, because they do not appear in the type of the
definition. Any inconsistency will be raised at a later stage
when joining the environment. *)
- let env' = Environ.push_context ~strict:true ctx env' in
- let c',cst = match cb.const_body with
- | Undef _ | OpaqueDef _ ->
- let j = Typeops.infer env' c in
- let typ = cb.const_type in
- let cst' = Reduction.infer_conv_leq env' (Environ.universes env')
- j.uj_type typ in
- j.uj_val, cst'
- | Def cs ->
- let c' = Mod_subst.force_constr cs in
- c, Reduction.infer_conv env' (Environ.universes env') c c'
- in c', Monomorphic_const ctx, Univ.ContextSet.add_constraints cst (Univ.ContextSet.of_context ctx)
+ let env' = Environ.push_context ~strict:true ctx env' in
+ let c',cst = match cb.const_body with
+ | Undef _ | OpaqueDef _ ->
+ let j = Typeops.infer env' c in
+ let typ = cb.const_type in
+ let cst' = Reduction.infer_conv_leq env' (Environ.universes env')
+ j.uj_type typ in
+ j.uj_val, cst'
+ | Def cs ->
+ let c' = Mod_subst.force_constr cs in
+ c, Reduction.infer_conv env' (Environ.universes env') c c'
+ in
+ let ctx = Univ.ContextSet.of_context ctx in
+ c', Monomorphic_const ctx, Univ.ContextSet.add_constraints cst ctx
| Polymorphic_const uctx ->
let subst, ctx = Univ.abstract_universes ctx in
let c = Vars.subst_univs_level_constr subst c in
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 0e416b3e5..0e41bfc3c 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -249,14 +249,14 @@ let universes_of_private eff =
in
match cb.const_universes with
| Monomorphic_const ctx ->
- (Univ.ContextSet.of_context ctx) :: acc
+ ctx :: acc
| Polymorphic_const _ -> acc
)
acc l
| Entries.SEsubproof (c, cb, e) ->
match cb.const_universes with
| Monomorphic_const ctx ->
- (Univ.ContextSet.of_context ctx) :: acc
+ ctx :: acc
| Polymorphic_const _ -> acc
)
[] (Term_typing.uniq_seff eff)
@@ -389,7 +389,6 @@ let push_named_def (id,de) senv =
| Monomorphic_const_entry _ -> false
| Polymorphic_const_entry _ -> true
in
- let univs = Univ.ContextSet.of_context univs in
let c, univs = match c with
| Def c -> Mod_subst.force_constr c, univs
| OpaqueDef o ->
@@ -425,9 +424,8 @@ let labels_of_mib mib =
let globalize_constant_universes env cb =
match cb.const_universes with
- | Monomorphic_const ctx ->
- let cstrs = Univ.ContextSet.of_context ctx in
- Now (false, cstrs) ::
+ | Monomorphic_const cstrs ->
+ Now (false, cstrs) ::
(match cb.const_body with
| (Undef _ | Def _) -> []
| OpaqueDef lc ->
@@ -443,7 +441,7 @@ let globalize_constant_universes env cb =
let globalize_mind_universes mb =
match mb.mind_universes with
| Monomorphic_ind ctx ->
- [Now (false, Univ.ContextSet.of_context ctx)]
+ [Now (false, ctx)]
| Polymorphic_ind _ -> [Now (true, Univ.ContextSet.empty)]
| Cumulative_ind _ -> [Now (true, Univ.ContextSet.empty)]
diff --git a/kernel/term_typing.ml b/kernel/term_typing.ml
index 4617f2d5f..70dd6438d 100644
--- a/kernel/term_typing.ml
+++ b/kernel/term_typing.ml
@@ -125,11 +125,10 @@ let inline_side_effects env body ctx side_eff =
| _ -> assert false
in
match cb.const_universes with
- | Monomorphic_const cnstctx ->
+ | Monomorphic_const univs ->
(** Abstract over the term at the top of the proof *)
let ty = cb.const_type in
let subst = Cmap_env.add c (Inr var) subst in
- let univs = Univ.ContextSet.of_context cnstctx in
let ctx = Univ.ContextSet.union ctx univs in
(subst, var + 1, ctx, (cname c, b, ty, opaque) :: args)
| Polymorphic_const auctx ->
@@ -228,19 +227,25 @@ let feedback_completion_typecheck =
Option.iter (fun state_id ->
feedback ~id:state_id Feedback.Complete)
-let abstract_constant_universes abstract uctx =
- if not abstract then
+let abstract_constant_universes abstract = function
+ | Monomorphic_const_entry uctx ->
Univ.empty_level_subst, Monomorphic_const uctx
- else
- let sbst, auctx = Univ.abstract_universes uctx in
- sbst, Polymorphic_const auctx
+ | Polymorphic_const_entry uctx ->
+ if not abstract then
+ Univ.empty_level_subst, Monomorphic_const (Univ.ContextSet.of_context uctx)
+ else
+ let sbst, auctx = Univ.abstract_universes uctx in
+ sbst, Polymorphic_const auctx
let infer_declaration (type a) ~(trust : a trust) env kn (dcl : a constant_entry) =
match dcl with
- | ParameterEntry (ctx,poly,(t,uctx),nl) ->
- let env = push_context ~strict:(not poly) uctx env in
+ | ParameterEntry (ctx,(t,uctx),nl) ->
+ let env = match uctx with
+ | Monomorphic_const_entry uctx -> push_context_set ~strict:true uctx env
+ | Polymorphic_const_entry uctx -> push_context ~strict:false uctx env
+ in
let j = infer env t in
- let abstract = poly && not (Option.is_empty kn) in
+ let abstract = not (Option.is_empty kn) in
let usubst, univs =
abstract_constant_universes abstract uctx
in
@@ -262,7 +267,7 @@ let infer_declaration (type a) ~(trust : a trust) env kn (dcl : a constant_entry
| DefinitionEntry ({ const_entry_type = Some typ;
const_entry_opaque = true;
const_entry_universes = Monomorphic_const_entry univs } as c) ->
- let env = push_context ~strict:true univs env in
+ let env = push_context_set ~strict:true univs env in
let { const_entry_body = body; const_entry_feedback = feedback_id } = c in
let tyj = infer_type env typ in
let proofterm =
@@ -301,21 +306,22 @@ let infer_declaration (type a) ~(trust : a trust) env kn (dcl : a constant_entry
let { const_entry_type = typ; const_entry_opaque = opaque } = c in
let { const_entry_body = body; const_entry_feedback = feedback_id } = c in
let (body, ctx), side_eff = Future.join body in
- let poly, univs = match c.const_entry_universes with
+ let poly, univsctx = match c.const_entry_universes with
| Monomorphic_const_entry univs -> false, univs
- | Polymorphic_const_entry univs -> true, univs
+ | Polymorphic_const_entry univs -> true, Univ.ContextSet.of_context univs
in
- let univsctx = Univ.ContextSet.of_context univs in
let ctx = Univ.ContextSet.union univsctx ctx in
let body, ctx, _ = match trust with
| Pure -> body, ctx, []
| SideEffects _ -> inline_side_effects env body ctx side_eff
in
let env = push_context_set ~strict:(not poly) ctx env in
- let abstract = poly && not (Option.is_empty kn) in
- let usubst, univs =
- abstract_constant_universes abstract (Univ.ContextSet.to_context ctx)
- in
+ let abstract = not (Option.is_empty kn) in
+ let ctx = if poly
+ then Polymorphic_const_entry (Univ.ContextSet.to_context ctx)
+ else Monomorphic_const_entry ctx
+ in
+ let usubst, univs = abstract_constant_universes abstract ctx in
let j = infer env body in
let typ = match typ with
| None ->
@@ -556,7 +562,7 @@ let export_side_effects mb env ce =
let env = Environ.add_constant kn cb env in
match cb.const_universes with
| Monomorphic_const ctx ->
- Environ.push_context ~strict:true ctx env
+ Environ.push_context_set ~strict:true ctx env
| Polymorphic_const _ -> env
end
| kn, cb, `Opaque(_, ctx), _ ->
@@ -564,7 +570,7 @@ let export_side_effects mb env ce =
let env = Environ.add_constant kn cb env in
match cb.const_universes with
| Monomorphic_const cstctx ->
- let env = Environ.push_context ~strict:true cstctx env in
+ let env = Environ.push_context_set ~strict:true cstctx env in
Environ.push_context_set ~strict:true ctx env
| Polymorphic_const _ -> env
end
diff --git a/kernel/term_typing.mli b/kernel/term_typing.mli
index 9b35bfc6e..55da4197e 100644
--- a/kernel/term_typing.mli
+++ b/kernel/term_typing.mli
@@ -19,7 +19,7 @@ type _ trust =
| SideEffects : structure_body -> side_effects trust
val translate_local_def : 'a trust -> env -> Id.t -> 'a definition_entry ->
- constant_def * types * Univ.UContext.t
+ constant_def * types * Univ.ContextSet.t
val translate_local_assum : env -> types -> types
diff --git a/kernel/univ.ml b/kernel/univ.ml
index 7fe4f8274..64afb95d5 100644
--- a/kernel/univ.ml
+++ b/kernel/univ.ml
@@ -1053,6 +1053,7 @@ struct
let constraints (univs, cst) = cst
let levels (univs, cst) = univs
+ let size (univs,_) = LSet.cardinal univs
end
type universe_context_set = ContextSet.t
diff --git a/kernel/univ.mli b/kernel/univ.mli
index 8d46a8bee..c06ce2446 100644
--- a/kernel/univ.mli
+++ b/kernel/univ.mli
@@ -310,7 +310,7 @@ sig
(** Keeps the order of the instances *)
val union : t -> t -> t
- (* the number of universes in the context *)
+ (** the number of universes in the context *)
val size : t -> int
end
@@ -423,6 +423,9 @@ sig
val constraints : t -> constraints
val levels : t -> LSet.t
+
+ (** the number of universes in the context *)
+ val size : t -> int
end
(** A set of universes with universe constraints.
diff --git a/kernel/vconv.ml b/kernel/vconv.ml
index 0e452621c..578a89371 100644
--- a/kernel/vconv.ml
+++ b/kernel/vconv.ml
@@ -93,7 +93,7 @@ and conv_atom env pb k a1 stk1 a2 stk2 cu =
let mib = Environ.lookup_mind mi env in
let ulen =
match mib.Declarations.mind_universes with
- | Declarations.Monomorphic_ind ctx -> Univ.UContext.size ctx
+ | Declarations.Monomorphic_ind ctx -> Univ.ContextSet.size ctx
| Declarations.Polymorphic_ind auctx -> Univ.AUContext.size auctx
| Declarations.Cumulative_ind cumi ->
Univ.AUContext.size (Univ.ACumulativityInfo.univ_context cumi)
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index a01ea26af..0e585cff7 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -875,7 +875,7 @@ GEXTEND Gram
(* Printing (careful factorization of entries) *)
| IDENT "Print"; p = printable -> VernacPrint p
- | IDENT "Print"; qid = smart_global -> VernacPrint (PrintName qid)
+ | IDENT "Print"; qid = smart_global; l = OPT univ_name_list -> VernacPrint (PrintName (qid,l))
| IDENT "Print"; IDENT "Module"; "Type"; qid = global ->
VernacPrint (PrintModuleType qid)
| IDENT "Print"; IDENT "Module"; qid = global ->
@@ -940,8 +940,8 @@ GEXTEND Gram
| IDENT "Check"; c = lconstr; "." ->
fun g -> VernacCheckMayEval (None, g, c)
(* Searching the environment *)
- | IDENT "About"; qid = smart_global; "." ->
- fun g -> VernacPrint (PrintAbout (qid,g))
+ | IDENT "About"; qid = smart_global; l = OPT univ_name_list; "." ->
+ fun g -> VernacPrint (PrintAbout (qid,l,g))
| IDENT "SearchHead"; c = constr_pattern; l = in_or_out_modules; "." ->
fun g -> VernacSearch (SearchHead c,g, l)
| IDENT "SearchPattern"; c = constr_pattern; l = in_or_out_modules; "." ->
@@ -960,7 +960,7 @@ GEXTEND Gram
] ]
;
printable:
- [ [ IDENT "Term"; qid = smart_global -> PrintName qid
+ [ [ IDENT "Term"; qid = smart_global; l = OPT univ_name_list -> PrintName (qid,l)
| IDENT "All" -> PrintFullContext
| IDENT "Section"; s = global -> PrintSectionContext s
| IDENT "Grammar"; ent = IDENT ->
@@ -1060,6 +1060,9 @@ GEXTEND Gram
| -> ([],SearchOutside [])
] ]
;
+ univ_name_list:
+ [ [ "@{" ; l = LIST0 name; "}" -> l ] ]
+ ;
END;
GEXTEND Gram
diff --git a/plugins/funind/functional_principles_types.ml b/plugins/funind/functional_principles_types.ml
index 996e2b6af..7a9bbd92c 100644
--- a/plugins/funind/functional_principles_types.ml
+++ b/plugins/funind/functional_principles_types.ml
@@ -348,8 +348,11 @@ let generate_functional_principle (evd: Evd.evar_map ref)
let evd',value = change_property_sort evd' s new_principle_type new_princ_name in
let evd' = fst (Typing.type_of ~refresh:true (Global.env ()) evd' (EConstr.of_constr value)) in
(* Pp.msgnl (str "new principle := " ++ pr_lconstr value); *)
- let univs = (snd (Evd.universe_context ~names:[] ~extensible:true evd')) in
- let ce = Declare.definition_entry ~poly:(Flags.is_universe_polymorphism ()) ~univs value in
+ let univs =
+ let poly = Flags.is_universe_polymorphism () in
+ Evd.const_univ_entry ~poly evd'
+ in
+ let ce = Declare.definition_entry ~univs value in
ignore(
Declare.declare_constant
name
diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml
index 3089ec470..b0a76137b 100644
--- a/plugins/funind/recdef.ml
+++ b/plugins/funind/recdef.ml
@@ -66,8 +66,8 @@ let find_reference sl s =
let dp = Names.DirPath.make (List.rev_map Id.of_string sl) in
locate (make_qualid dp (Id.of_string s))
-let declare_fun f_id kind ?(ctx=Univ.UContext.empty) value =
- let ce = definition_entry ~univs:ctx value (*FIXME *) in
+let declare_fun f_id kind ?univs value =
+ let ce = definition_entry ?univs value (*FIXME *) in
ConstRef(declare_constant f_id (DefinitionEntry ce, kind));;
let defined () = Lemmas.save_proof (Vernacexpr.(Proved (Transparent,None)))
@@ -1556,8 +1556,8 @@ let recursive_definition is_mes function_name rec_impls type_of_f r rec_arg_num
let functional_id = add_suffix function_name "_F" in
let term_id = add_suffix function_name "_terminate" in
let functional_ref =
- let ctx = (snd (Evd.universe_context ~names:[] ~extensible:true evm)) in
- declare_fun functional_id (IsDefinition Decl_kinds.Definition) ~ctx res
+ let univs = Entries.Monomorphic_const_entry (Evd.universe_context_set evm) in
+ declare_fun functional_id (IsDefinition Decl_kinds.Definition) ~univs res
in
(* Refresh the global universes, now including those of _F *)
let evm = Evd.from_env (Global.env ()) in
diff --git a/plugins/ltac/extratactics.ml4 b/plugins/ltac/extratactics.ml4
index 790a9e435..982fc7cc3 100644
--- a/plugins/ltac/extratactics.ml4
+++ b/plugins/ltac/extratactics.ml4
@@ -313,10 +313,10 @@ let project_hint pri l2r r =
let id =
Nameops.add_suffix (Nametab.basename_of_global gr) ("_proj_" ^ (if l2r then "l2r" else "r2l"))
in
- let ctx = Evd.universe_context_set sigma in
- let c = EConstr.to_constr sigma c in
let poly = Flags.use_polymorphic_flag () in
- let c = Declare.declare_definition ~poly ~internal:Declare.InternalTacticRequest id (c,ctx) in
+ let ctx = Evd.const_univ_entry ~poly sigma in
+ let c = EConstr.to_constr sigma c in
+ let c = Declare.declare_definition ~internal:Declare.InternalTacticRequest id (c,ctx) in
let info = {Vernacexpr.hint_priority = pri; hint_pattern = None} in
(info,false,true,Hints.PathAny, Hints.IsGlobRef (Globnames.ConstRef c))
diff --git a/plugins/ltac/rewrite.ml b/plugins/ltac/rewrite.ml
index 14b0742a7..c0060c5a7 100644
--- a/plugins/ltac/rewrite.ml
+++ b/plugins/ltac/rewrite.ml
@@ -1884,11 +1884,11 @@ let declare_projection n instance_id r =
in it_mkProd_or_LetIn ccl ctx
in
let typ = it_mkProd_or_LetIn typ ctx in
- let pl, ctx = Evd.universe_context ~names:[] ~extensible:true sigma in
+ let univs = Evd.const_univ_entry ~poly sigma in
let typ = EConstr.to_constr sigma typ in
let term = EConstr.to_constr sigma term in
let cst =
- Declare.definition_entry ~types:typ ~poly ~univs:ctx term
+ Declare.definition_entry ~types:typ ~univs term
in
ignore(Declare.declare_constant n
(Entries.DefinitionEntry cst, Decl_kinds.IsDefinition Decl_kinds.Definition))
@@ -1972,9 +1972,10 @@ let add_morphism_infer glob m n =
let evd = Evd.from_env env in
let uctx, instance = build_morphism_signature env evd m in
if Lib.is_modtype () then
+ let uctx = UState.const_univ_entry ~poly uctx in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest instance_id
(Entries.ParameterEntry
- (None,poly,(instance,UState.context uctx),None),
+ (None,(instance,uctx),None),
Decl_kinds.IsAssumption Decl_kinds.Logical)
in
add_instance (Typeclasses.new_instance
diff --git a/plugins/setoid_ring/newring.ml b/plugins/setoid_ring/newring.ml
index 1c3bdb958..f22f00839 100644
--- a/plugins/setoid_ring/newring.ml
+++ b/plugins/setoid_ring/newring.ml
@@ -150,13 +150,13 @@ let ic_unsafe c = (*FIXME remove *)
let sigma = Evd.from_env env in
EConstr.of_constr (fst (Constrintern.interp_constr env sigma c))
-let decl_constant na ctx c =
+let decl_constant na univs c =
let open Constr in
let vars = Univops.universes_of_constr c in
- let ctx = Univops.restrict_universe_context (Univ.ContextSet.of_context ctx) vars in
+ let univs = Univops.restrict_universe_context univs vars in
+ let univs = Monomorphic_const_entry univs in
mkConst(declare_constant (Id.of_string na)
- (DefinitionEntry (definition_entry ~opaque:true
- ~univs:(Univ.ContextSet.to_context ctx) c),
+ (DefinitionEntry (definition_entry ~opaque:true ~univs c),
IsProof Lemma))
(* Calling a global tactic *)
@@ -220,7 +220,7 @@ let exec_tactic env evd n f args =
let gls = Proofview.V82.of_tactic (Tacinterp.eval_tactic_ist ist (ltac_call f (args@[getter]))) gl in
let evd, nf = Evarutil.nf_evars_and_universes (Refiner.project gls) in
let nf c = nf (constr_of c) in
- Array.map nf !tactic_res, snd (Evd.universe_context ~names:[] ~extensible:true evd)
+ Array.map nf !tactic_res, Evd.universe_context_set evd
let stdlib_modules =
[["Coq";"Setoids";"Setoid"];
diff --git a/pretyping/pretyping.ml b/pretyping/pretyping.ml
index eb90e5fe0..00c254dbe 100644
--- a/pretyping/pretyping.ml
+++ b/pretyping/pretyping.ml
@@ -177,13 +177,20 @@ let _ =
optwrite = (:=) Universes.set_minimization })
(** Miscellaneous interpretation functions *)
+let interp_known_universe_level evd id =
+ try
+ let level = Evd.universe_of_name evd id in
+ level
+ with Not_found ->
+ let names, _ = Global.global_universe_names () in
+ snd (Id.Map.find id names)
+
let interp_universe_level_name ~anon_rigidity evd (loc, s) =
match s with
| Anonymous ->
new_univ_level_variable ?loc anon_rigidity evd
- | Name s ->
- let s = Id.to_string s in
- let names, _ = Global.global_universe_names () in
+ | Name id ->
+ let s = Id.to_string id in
if CString.string_contains ~where:s ~what:"." then
match List.rev (CString.split '.' s) with
| [] -> anomaly (str"Invalid universe name " ++ str s ++ str".")
@@ -196,18 +203,12 @@ let interp_universe_level_name ~anon_rigidity evd (loc, s) =
with UGraph.AlreadyDeclared -> evd
in evd, level
else
- try
- let level = Evd.universe_of_name evd s in
- evd, level
+ try evd, interp_known_universe_level evd id
with Not_found ->
- try
- let id = try Id.of_string s with _ -> raise Not_found in
- evd, snd (Id.Map.find id names)
- with Not_found ->
- if not (is_strict_universe_declarations ()) then
- new_univ_level_variable ?loc ~name:s univ_rigid evd
- else user_err ?loc ~hdr:"interp_universe_level_name"
- (Pp.(str "Undeclared universe: " ++ str s))
+ if not (is_strict_universe_declarations ()) then
+ new_univ_level_variable ?loc ~name:id univ_rigid evd
+ else user_err ?loc ~hdr:"interp_universe_level_name"
+ (Pp.(str "Undeclared universe: " ++ str s))
let interp_universe ?loc evd = function
| [] -> let evd, l = new_univ_level_variable ?loc univ_rigid evd in
@@ -219,6 +220,15 @@ let interp_universe ?loc evd = function
(evd', Univ.sup u (Univ.Universe.make l)))
(evd, Univ.Universe.type0m) l
+let interp_known_level_info ?loc evd = function
+ | None | Some (_, Anonymous) ->
+ user_err ?loc ~hdr:"interp_known_level_info"
+ (str "Anonymous universes not allowed here.")
+ | Some (loc, Name id) ->
+ try interp_known_universe_level evd id
+ with Not_found ->
+ user_err ?loc ~hdr:"interp_known_level_info" (str "Undeclared universe " ++ Id.print id)
+
let interp_level_info ?loc evd : Misctypes.level_info -> _ = function
| None -> new_univ_level_variable ?loc univ_rigid evd
| Some (loc,s) -> interp_universe_level_name ~anon_rigidity:univ_flexible evd (Loc.tag ?loc s)
@@ -467,6 +477,11 @@ let pretype_id pretype k0 loc env evdref lvar id =
(*************************************************************************)
(* Main pretyping function *)
+let interp_known_glob_level ?loc evd = function
+ | GProp -> Univ.Level.prop
+ | GSet -> Univ.Level.set
+ | GType s -> interp_known_level_info ?loc evd s
+
let interp_glob_level ?loc evd : Misctypes.glob_level -> _ = function
| GProp -> evd, Univ.Level.prop
| GSet -> evd, Univ.Level.set
diff --git a/pretyping/pretyping.mli b/pretyping/pretyping.mli
index 838938524..fe10be9e7 100644
--- a/pretyping/pretyping.mli
+++ b/pretyping/pretyping.mli
@@ -20,6 +20,9 @@ open Glob_term
open Ltac_pretype
open Evardefine
+val interp_known_glob_level : ?loc:Loc.t -> Evd.evar_map ->
+ Misctypes.glob_level -> Univ.Level.t
+
(** An auxiliary function for searching for fixpoint guard indexes *)
val search_guard :
diff --git a/pretyping/univdecls.ml b/pretyping/univdecls.ml
index 5576e33f4..3cf32d7ff 100644
--- a/pretyping/univdecls.ml
+++ b/pretyping/univdecls.ml
@@ -6,9 +6,8 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-open Pp
-open CErrors
open Names
+open CErrors
(** Local universes and constraints declarations *)
type universe_decl =
@@ -22,27 +21,16 @@ let default_univ_decl =
univdecl_extensible_constraints = true }
let interp_univ_constraints env evd cstrs =
- let open Misctypes in
- let u_of_id x =
- match x with
- | Misctypes.GProp -> Loc.tag Univ.Level.prop
- | GSet -> Loc.tag Univ.Level.set
- | GType None | GType (Some (_, Anonymous)) ->
- user_err ~hdr:"interp_constraint"
- (str "Cannot declare constraints on anonymous universes")
- | GType (Some (loc, Name id)) ->
- try loc, Evd.universe_of_name evd (Id.to_string id)
- with Not_found ->
- user_err ?loc ~hdr:"interp_constraint" (str "Undeclared universe " ++ Id.print id)
- in
let interp (evd,cstrs) (u, d, u') =
- let lloc, ul = u_of_id u and rloc, u'l = u_of_id u' in
+ let ul = Pretyping.interp_known_glob_level evd u in
+ let u'l = Pretyping.interp_known_glob_level evd u' in
let cstr = (ul,d,u'l) in
let cstrs' = Univ.Constraint.add cstr cstrs in
try let evd = Evd.add_constraints evd (Univ.Constraint.singleton cstr) in
evd, cstrs'
with Univ.UniverseInconsistency e ->
- user_err ~hdr:"interp_constraint" (str "Universe inconsistency" (* TODO *))
+ user_err ~hdr:"interp_constraint"
+ (Univ.explain_universe_inconsistency (Termops.pr_evd_level evd) e)
in
List.fold_left interp (evd,Univ.Constraint.empty) cstrs
diff --git a/printing/ppvernac.ml b/printing/ppvernac.ml
index e897b1938..1a74538aa 100644
--- a/printing/ppvernac.ml
+++ b/printing/ppvernac.ml
@@ -41,6 +41,11 @@ open Decl_kinds
pr_glob_level l ++ spc () ++ Univ.pr_constraint_type d ++ spc () ++
pr_glob_level r
+ let pr_univ_name_list = function
+ | None -> mt ()
+ | Some l ->
+ str "@{" ++ prlist_with_sep spc pr_lname l ++ str"}"
+
let pr_univdecl_instance l extensible =
prlist_with_sep spc pr_lident l ++
(if extensible then str"+" else mt ())
@@ -488,8 +493,8 @@ open Decl_kinds
else "Print Universes"
in
keyword cmd ++ pr_opt str fopt
- | PrintName qid ->
- keyword "Print" ++ spc() ++ pr_smart_global qid
+ | PrintName (qid,udecl) ->
+ keyword "Print" ++ spc() ++ pr_smart_global qid ++ pr_univ_name_list udecl
| PrintModuleType qid ->
keyword "Print Module Type" ++ spc() ++ pr_reference qid
| PrintModule qid ->
@@ -502,9 +507,9 @@ open Decl_kinds
keyword "Print Scope" ++ spc() ++ str s
| PrintVisibility s ->
keyword "Print Visibility" ++ pr_opt str s
- | PrintAbout (qid,gopt) ->
+ | PrintAbout (qid,l,gopt) ->
pr_opt (fun g -> Proof_bullet.pr_goal_selector g ++ str ":"++ spc()) gopt
- ++ keyword "About" ++ spc() ++ pr_smart_global qid
+ ++ keyword "About" ++ spc() ++ pr_smart_global qid ++ pr_univ_name_list l
| PrintImplicit qid ->
keyword "Print Implicit" ++ spc() ++ pr_smart_global qid
(* spiwack: command printing all the axioms and section variables used in a
diff --git a/printing/prettyp.ml b/printing/prettyp.ml
index 8fc00ed96..602b7a496 100644
--- a/printing/prettyp.ml
+++ b/printing/prettyp.ml
@@ -32,8 +32,8 @@ open Context.Rel.Declaration
module NamedDecl = Context.Named.Declaration
type object_pr = {
- print_inductive : MutInd.t -> Pp.t;
- print_constant_with_infos : Constant.t -> Pp.t;
+ print_inductive : MutInd.t -> Universes.univ_name_list option -> Pp.t;
+ print_constant_with_infos : Constant.t -> Universes.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
@@ -68,7 +68,7 @@ let int_or_no n = if Int.equal n 0 then str "no" else int n
let print_basename sp = pr_global (ConstRef sp)
-let print_ref reduce ref =
+let print_ref reduce ref udecl =
let typ, ctx = Global.type_of_global_in_context (Global.env ()) ref in
let typ = Vars.subst_instance_constr (Univ.AUContext.instance ctx) typ in
let typ = EConstr.of_constr typ in
@@ -81,7 +81,8 @@ let print_ref reduce ref =
let inst = Univ.AUContext.instance univs in
let univs = Univ.UContext.make (inst, Univ.AUContext.instantiate inst univs) in
let env = Global.env () in
- let bl = Universes.universe_binders_of_global ref in
+ let bl = Universes.universe_binders_with_opt_names ref
+ (Array.to_list (Univ.Instance.to_array inst)) udecl in
let sigma = Evd.from_ctx (Evd.evar_universe_context_of_binders bl) in
let inst =
if Global.is_polymorphic ref then Printer.pr_universe_instance sigma univs
@@ -150,7 +151,7 @@ let print_impargs ref =
let has_impl = not (List.is_empty impl) in
(* Need to reduce since implicits are computed with products flattened *)
pr_infos_list
- ([ print_ref (need_expansion (select_impargs_size 0 impl) ref) ref;
+ ([ print_ref (need_expansion (select_impargs_size 0 impl) ref) ref None;
blankline ] @
(if has_impl then print_impargs_list (mt()) impl
else [str "No implicit arguments"]))
@@ -256,7 +257,7 @@ let print_name_infos ref =
if need_expansion (select_impargs_size 0 impls) ref then
(* Need to reduce since implicits are computed with products flattened *)
[str "Expanded type for implicit arguments";
- print_ref true ref; blankline]
+ print_ref true ref None; blankline]
else
[] in
print_polymorphism ref @
@@ -512,11 +513,11 @@ let assumptions_for_print lna =
(*********************)
(* *)
-let gallina_print_inductive sp =
+let gallina_print_inductive sp udecl =
let env = Global.env() in
let mib = Environ.lookup_mind sp env in
let mipv = mib.mind_packets in
- pr_mutual_inductive_body env sp mib ++
+ pr_mutual_inductive_body env sp mib udecl ++
with_line_skip
(print_primitive_record mib.mind_finite mipv mib.mind_record @
print_inductive_renames sp mipv @
@@ -545,7 +546,7 @@ let print_instance sigma cb =
pr_universe_instance sigma univs
else mt()
-let print_constant with_values sep sp =
+let print_constant with_values sep sp udecl =
let cb = Global.lookup_constant sp in
let val_0 = Global.body_of_constant_body cb in
let typ =
@@ -555,31 +556,34 @@ let print_constant with_values sep sp =
let inst = Univ.AUContext.instance univs in
Vars.subst_instance_constr inst cb.const_type
in
- let univs =
+ let univs, ulist =
+ let open Entries in
+ let open Univ in
let otab = Global.opaque_tables () in
match cb.const_body with
| Undef _ | Def _ ->
begin
match cb.const_universes with
- | Monomorphic_const ctx -> ctx
+ | Monomorphic_const ctx -> Monomorphic_const_entry ctx, []
| Polymorphic_const ctx ->
- let inst = Univ.AUContext.instance ctx in
- Univ.UContext.make (inst, Univ.AUContext.instantiate inst ctx)
+ let inst = AUContext.instance ctx in
+ Polymorphic_const_entry (UContext.make (inst, AUContext.instantiate inst ctx)),
+ Array.to_list (Instance.to_array inst)
end
| OpaqueDef o ->
let body_uctxs = Opaqueproof.force_constraints otab o in
match cb.const_universes with
| Monomorphic_const ctx ->
- let uctxs = Univ.ContextSet.of_context ctx in
- Univ.ContextSet.to_context (Univ.ContextSet.union body_uctxs uctxs)
+ Monomorphic_const_entry (ContextSet.union body_uctxs ctx), []
| Polymorphic_const ctx ->
- assert(Univ.ContextSet.is_empty body_uctxs);
- let inst = Univ.AUContext.instance ctx in
- Univ.UContext.make (inst, Univ.AUContext.instantiate inst ctx)
+ assert(ContextSet.is_empty body_uctxs);
+ let inst = AUContext.instance ctx in
+ Polymorphic_const_entry (UContext.make (inst, AUContext.instantiate inst ctx)),
+ Array.to_list (Instance.to_array inst)
in
let ctx =
Evd.evar_universe_context_of_binders
- (Universes.universe_binders_of_global (ConstRef sp))
+ (Universes.universe_binders_with_opt_names (ConstRef sp) ulist udecl)
in
let env = Global.env () and sigma = Evd.from_ctx ctx in
let pr_ltype = pr_ltype_env env sigma in
@@ -589,15 +593,15 @@ let print_constant with_values sep sp =
str"*** [ " ++
print_basename sp ++ print_instance sigma cb ++ str " : " ++ cut () ++ pr_ltype typ ++
str" ]" ++
- Printer.pr_universe_ctx sigma univs
+ Printer.pr_constant_universes sigma univs
| Some (c, ctx) ->
let c = Vars.subst_instance_constr (Univ.AUContext.instance ctx) c in
print_basename sp ++ print_instance sigma cb ++ str sep ++ cut () ++
(if with_values then print_typed_body env sigma (Some c,typ) else pr_ltype typ)++
- Printer.pr_universe_ctx sigma univs)
+ Printer.pr_constant_universes sigma univs)
-let gallina_print_constant_with_infos sp =
- print_constant true " = " sp ++
+let gallina_print_constant_with_infos sp udecl =
+ print_constant true " = " sp udecl ++
with_line_skip (print_name_infos (ConstRef sp))
let gallina_print_syntactic_def env kn =
@@ -622,9 +626,9 @@ let gallina_print_leaf_entry env sigma with_values ((sp,kn as oname),lobj) =
constraints *)
(try Some(print_named_decl env sigma (basename sp)) with Not_found -> None)
| (_,"CONSTANT") ->
- Some (print_constant with_values sep (Constant.make1 kn))
+ Some (print_constant with_values sep (Constant.make1 kn) None)
| (_,"INDUCTIVE") ->
- Some (gallina_print_inductive (MutInd.make1 kn))
+ Some (gallina_print_inductive (MutInd.make1 kn) None)
| (_,"MODULE") ->
let (mp,_,l) = KerName.repr kn in
Some (print_module with_values (MPdot (mp,l)))
@@ -745,7 +749,7 @@ let print_full_pure_context env sigma =
| "INDUCTIVE" ->
let mind = Global.mind_of_delta_kn kn in
let mib = Global.lookup_mind mind in
- pr_mutual_inductive_body (Global.env()) mind mib ++
+ pr_mutual_inductive_body (Global.env()) mind mib None ++
str "." ++ fnl () ++ fnl ()
| "MODULE" ->
(* TODO: make it reparsable *)
@@ -792,10 +796,19 @@ let print_sec_context env sigma sec =
let print_sec_context_typ env sigma sec =
print_context env sigma false None (read_sec_context sec)
-let print_any_name env sigma = function
- | Term (ConstRef sp) -> print_constant_with_infos sp
- | Term (IndRef (sp,_)) -> print_inductive sp
- | Term (ConstructRef ((sp,_),_)) -> print_inductive sp
+let maybe_error_reject_univ_decl na udecl =
+ match na, udecl with
+ | _, None | Term (ConstRef _ | IndRef _ | ConstructRef _), Some _ -> ()
+ | (Term (VarRef _) | Syntactic _ | Dir _ | ModuleType _ | Other _ | Undefined _), Some udecl ->
+ (* TODO Print na somehow *)
+ user_err ~hdr:"reject_univ_decl" (str "This object does not support universe names.")
+
+let print_any_name env sigma na udecl =
+ maybe_error_reject_univ_decl na udecl;
+ match na with
+ | Term (ConstRef sp) -> print_constant_with_infos sp udecl
+ | Term (IndRef (sp,_)) -> print_inductive sp udecl
+ | Term (ConstructRef ((sp,_),_)) -> print_inductive sp udecl
| Term (VarRef sp) -> print_section_variable env sigma sp
| Syntactic kn -> print_syntactic_def env kn
| Dir (DirModule(dirpath,(mp,_))) -> print_module (printable_body dirpath) mp
@@ -812,24 +825,26 @@ let print_any_name env sigma = function
user_err
~hdr:"print_name" (pr_qualid qid ++ spc () ++ str "not a defined object.")
-let print_name env sigma = function
+let print_name env sigma na udecl =
+ match na with
| ByNotation (loc,(ntn,sc)) ->
print_any_name env sigma
(Term (Notation.interp_notation_as_global_reference ?loc (fun _ -> true)
ntn sc))
+ udecl
| AN ref ->
- print_any_name env sigma (locate_any_name ref)
+ print_any_name env sigma (locate_any_name ref) udecl
let print_opaque_name env sigma qid =
match Nametab.global qid with
| ConstRef cst ->
let cb = Global.lookup_constant cst in
if Declareops.constant_has_body cb then
- print_constant_with_infos cst
+ print_constant_with_infos cst None
else
user_err Pp.(str "Not a defined constant.")
| IndRef (sp,_) ->
- print_inductive sp
+ print_inductive sp None
| ConstructRef cstr as gr ->
let ty, ctx = Global.type_of_global_in_context env gr in
let inst = Univ.AUContext.instance ctx in
@@ -840,13 +855,14 @@ let print_opaque_name env sigma qid =
| VarRef id ->
env |> lookup_named id |> print_named_decl env sigma
-let print_about_any ?loc env sigma k =
+let print_about_any ?loc env sigma k udecl =
+ maybe_error_reject_univ_decl k udecl;
match k with
| Term ref ->
let rb = Reductionops.ReductionBehaviour.print ref in
Dumpglob.add_glob ?loc ref;
pr_infos_list
- (print_ref false ref :: blankline ::
+ (print_ref false ref udecl :: blankline ::
print_name_infos ref @
(if Pp.ismt rb then [] else [rb]) @
print_opacity ref @
@@ -862,13 +878,14 @@ let print_about_any ?loc env sigma k =
hov 0 (pr_located_qualid k)
| Other (obj, info) -> hov 0 (info.about obj)
-let print_about env sigma = function
+let print_about env sigma na udecl =
+ match na with
| ByNotation (loc,(ntn,sc)) ->
print_about_any ?loc env sigma
(Term (Notation.interp_notation_as_global_reference ?loc (fun _ -> true)
- ntn sc))
+ ntn sc)) udecl
| AN ref ->
- print_about_any ?loc:(loc_of_reference ref) env sigma (locate_any_name ref)
+ print_about_any ?loc:(loc_of_reference ref) env sigma (locate_any_name ref) udecl
(* for debug *)
let inspect env sigma depth =
@@ -940,7 +957,7 @@ let print_canonical_projections env sigma =
open Typeclasses
let pr_typeclass env t =
- print_ref false t.cl_impl
+ print_ref false t.cl_impl None
let print_typeclasses () =
let env = Global.env () in
@@ -949,7 +966,7 @@ let print_typeclasses () =
let pr_instance env i =
(* gallina_print_constant_with_infos i.is_impl *)
(* lighter *)
- print_ref false (instance_impl i) ++
+ print_ref false (instance_impl i) None ++
begin match hint_priority i with
| None -> mt ()
| Some i -> spc () ++ str "|" ++ spc () ++ int i
diff --git a/printing/prettyp.mli b/printing/prettyp.mli
index 89099a043..8f3a6ddc4 100644
--- a/printing/prettyp.mli
+++ b/printing/prettyp.mli
@@ -31,9 +31,11 @@ val print_eval :
reduction_function -> env -> Evd.evar_map ->
Constrexpr.constr_expr -> EConstr.unsafe_judgment -> Pp.t
-val print_name : env -> Evd.evar_map -> reference or_by_notation -> Pp.t
+val print_name : env -> Evd.evar_map -> reference or_by_notation ->
+ Vernacexpr.univ_name_list option -> Pp.t
val print_opaque_name : env -> Evd.evar_map -> reference -> Pp.t
-val print_about : env -> Evd.evar_map -> reference or_by_notation -> Pp.t
+val print_about : env -> Evd.evar_map -> reference or_by_notation ->
+ Vernacexpr.univ_name_list option -> Pp.t
val print_impargs : reference or_by_notation -> Pp.t
(** Pretty-printing functions for classes and coercions *)
@@ -80,8 +82,8 @@ val print_located_module : reference -> Pp.t
val print_located_other : string -> reference -> Pp.t
type object_pr = {
- print_inductive : MutInd.t -> Pp.t;
- print_constant_with_infos : Constant.t -> Pp.t;
+ print_inductive : MutInd.t -> Universes.univ_name_list option -> Pp.t;
+ print_constant_with_infos : Constant.t -> Universes.univ_name_list option -> Pp.t;
print_section_variable : env -> Evd.evar_map -> variable -> Pp.t;
print_syntactic_def : env -> KerName.t -> Pp.t;
print_module : bool -> ModPath.t -> Pp.t;
diff --git a/printing/printer.ml b/printing/printer.ml
index 3d40c104e..6a0597860 100644
--- a/printing/printer.ml
+++ b/printing/printer.ml
@@ -256,6 +256,13 @@ let safe_pr_constr t =
let (sigma, env) = Pfedit.get_current_context () in
safe_pr_constr_env env sigma t
+let pr_universe_ctx_set sigma c =
+ if !Detyping.print_universes && not (Univ.ContextSet.is_empty c) then
+ fnl()++pr_in_comment (fun c -> v 0
+ (Univ.pr_universe_context_set (Termops.pr_evd_level sigma) c)) c
+ else
+ mt()
+
let pr_universe_ctx sigma c =
if !Detyping.print_universes && not (Univ.UContext.is_empty c) then
fnl()++pr_in_comment (fun c -> v 0
@@ -263,6 +270,10 @@ let pr_universe_ctx sigma c =
else
mt()
+let pr_constant_universes sigma = function
+ | Entries.Monomorphic_const_entry ctx -> pr_universe_ctx_set sigma ctx
+ | Entries.Polymorphic_const_entry ctx -> pr_universe_ctx sigma ctx
+
let pr_cumulativity_info sigma cumi =
if !Detyping.print_universes
&& not (Univ.UContext.is_empty (Univ.CumulativityInfo.univ_context cumi)) then
diff --git a/printing/printer.mli b/printing/printer.mli
index 5adc0e858..9e8622c6e 100644
--- a/printing/printer.mli
+++ b/printing/printer.mli
@@ -121,6 +121,8 @@ val pr_polymorphic : bool -> Pp.t
val pr_cumulative : bool -> bool -> Pp.t
val pr_universe_instance : evar_map -> Univ.UContext.t -> Pp.t
val pr_universe_ctx : evar_map -> Univ.UContext.t -> Pp.t
+val pr_universe_ctx_set : evar_map -> Univ.ContextSet.t -> Pp.t
+val pr_constant_universes : evar_map -> Entries.constant_universes_entry -> Pp.t
val pr_cumulativity_info : evar_map -> Univ.CumulativityInfo.t -> Pp.t
(** Printing global references using names as short as possible *)
diff --git a/printing/printmod.ml b/printing/printmod.ml
index 13a03e9b4..c34543bbd 100644
--- a/printing/printmod.ml
+++ b/printing/printmod.ml
@@ -121,7 +121,7 @@ let instantiate_cumulativity_info cumi =
in
CumulativityInfo.make (expose univs, expose subtyp)
-let print_mutual_inductive env mind mib =
+let print_mutual_inductive env mind mib udecl =
let inds = List.init (Array.length mib.mind_packets) (fun x -> (mind, x))
in
let keyword =
@@ -131,7 +131,14 @@ let print_mutual_inductive env mind mib =
| BiFinite -> "Variant"
| CoFinite -> "CoInductive"
in
- let bl = Universes.universe_binders_of_global (IndRef (mind, 0)) in
+ let univs =
+ let open Univ in
+ if Declareops.inductive_is_polymorphic mib then
+ Array.to_list (Instance.to_array
+ (AUContext.instance (Declareops.inductive_polymorphic_context mib)))
+ else []
+ in
+ let bl = Universes.universe_binders_with_opt_names (IndRef (mind, 0)) univs udecl in
let sigma = Evd.from_ctx (Evd.evar_universe_context_of_binders bl) in
hov 0 (Printer.pr_polymorphic (Declareops.inductive_is_polymorphic mib) ++
Printer.pr_cumulative
@@ -159,7 +166,7 @@ let get_fields =
in
prodec_rec [] []
-let print_record env mind mib =
+let print_record env mind mib udecl =
let u =
if Declareops.inductive_is_polymorphic mib then
Univ.AUContext.instance (Declareops.inductive_polymorphic_context mib)
@@ -173,7 +180,8 @@ let print_record env mind mib =
let cstrtype = hnf_prod_applist env cstrtypes.(0) args in
let fields = get_fields cstrtype in
let envpar = push_rel_context params env in
- let bl = Universes.universe_binders_of_global (IndRef (mind,0)) in
+ let bl = Universes.universe_binders_with_opt_names (IndRef (mind,0))
+ (Array.to_list (Univ.Instance.to_array u)) udecl in
let sigma = Evd.from_ctx (Evd.evar_universe_context_of_binders bl) in
let keyword =
let open Decl_kinds in
@@ -205,11 +213,11 @@ let print_record env mind mib =
sigma (instantiate_cumulativity_info cumi)
)
-let pr_mutual_inductive_body env mind mib =
+let pr_mutual_inductive_body env mind mib udecl =
if mib.mind_record <> None && not !Flags.raw_print then
- print_record env mind mib
+ print_record env mind mib udecl
else
- print_mutual_inductive env mind mib
+ print_mutual_inductive env mind mib udecl
(** Modpaths *)
@@ -335,7 +343,7 @@ let print_body is_impl env mp (l,body) =
| SFBmind mib ->
try
let env = Option.get env in
- pr_mutual_inductive_body env (MutInd.make2 mp l) mib
+ pr_mutual_inductive_body env (MutInd.make2 mp l) mib None
with e when CErrors.noncritical e ->
let keyword =
let open Decl_kinds in
diff --git a/printing/printmod.mli b/printing/printmod.mli
index b0bbb21e0..97ed063fe 100644
--- a/printing/printmod.mli
+++ b/printing/printmod.mli
@@ -11,6 +11,8 @@ open Names
(** false iff the module is an element of an open module type *)
val printable_body : DirPath.t -> bool
-val pr_mutual_inductive_body : Environ.env -> MutInd.t -> Declarations.mutual_inductive_body -> Pp.t
+val pr_mutual_inductive_body : Environ.env ->
+ MutInd.t -> Declarations.mutual_inductive_body ->
+ Vernacexpr.univ_name_list option -> Pp.t
val print_module : bool -> ModPath.t -> Pp.t
val print_modtype : ModPath.t -> Pp.t
diff --git a/proofs/proof_global.ml b/proofs/proof_global.ml
index fdc9a236b..aa5621770 100644
--- a/proofs/proof_global.ml
+++ b/proofs/proof_global.ml
@@ -316,10 +316,6 @@ let get_open_goals () =
(List.map (fun (l1,l2) -> List.length l1 + List.length l2) gll) +
List.length shelf
-let constrain_variables init uctx =
- let levels = Univ.Instance.levels (Univ.UContext.instance init) in
- UState.constrain_variables levels uctx
-
type closed_proof_output = (Constr.t * Safe_typing.private_constants) list * UState.t
let close_proof ~keep_body_ucst_separate ?feedback_id ~now
@@ -329,10 +325,12 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
let poly = pi2 strength (* Polymorphic *) in
let initial_goals = Proof.initial_goals proof in
let initial_euctx = Proof.initial_euctx proof in
+ let constrain_variables ctx =
+ UState.constrain_variables (fst (UState.context_set initial_euctx)) ctx
+ in
let fpl, univs = Future.split2 fpl in
let universes = if poly || now then Future.force univs else initial_euctx in
- let binders, univctx = Evd.check_univ_decl (Evd.from_ctx universes) universe_decl in
- let binders = if poly then Some binders else None in
+ let binders = if poly then Some (UState.universe_binders universes) else None in
(* Because of dependent subgoals at the beginning of proofs, we could
have existential variables in the initial types of goals, we need to
normalise them for the kernel. *)
@@ -348,20 +346,25 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
if not (keep_body_ucst_separate || not (Safe_typing.empty_private_constants = eff)) then
nf t
else t
- in
+ in
let used_univs_body = Univops.universes_of_constr body in
let used_univs_typ = Univops.universes_of_constr typ in
+ (* Universes for private constants are relevant to the body *)
+ let used_univs_body =
+ List.fold_left (fun acc (us,_) -> Univ.LSet.union acc us)
+ used_univs_body (Safe_typing.universes_of_private eff)
+ in
if keep_body_ucst_separate ||
not (Safe_typing.empty_private_constants = eff) then
- let initunivs = Evd.evar_context_universe_context initial_euctx in
- let ctx = constrain_variables initunivs universes in
+ let initunivs = UState.const_univ_entry ~poly initial_euctx in
+ let ctx = constrain_variables universes in
(* For vi2vo compilation proofs are computed now but we need to
complement the univ constraints of the typ with the ones of
the body. So we keep the two sets distinct. *)
let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
let ctx_body = UState.restrict ctx used_univs in
- let _, univs = Evd.check_univ_decl (Evd.from_ctx ctx_body) universe_decl in
- (initunivs, typ), ((body, Univ.ContextSet.of_context univs), eff)
+ let univs = UState.check_mono_univ_decl ctx_body universe_decl in
+ (initunivs, typ), ((body, univs), eff)
else
(* Since the proof is computed now, we can simply have 1 set of
constraints in which we merge the ones for the body and the ones
@@ -370,30 +373,28 @@ let close_proof ~keep_body_ucst_separate ?feedback_id ~now
TODO: check if restrict is really necessary now. *)
let used_univs = Univ.LSet.union used_univs_body used_univs_typ in
let ctx = UState.restrict universes used_univs in
- let _, univs = Evd.check_univ_decl (Evd.from_ctx ctx) universe_decl in
+ let univs = UState.check_univ_decl ~poly ctx universe_decl in
(univs, typ), ((body, Univ.ContextSet.empty), eff)
in
fun t p -> Future.split2 (Future.chain p (make_body t))
else
fun t p ->
+ (* Already checked the univ_decl for the type universes when starting the proof. *)
+ let univctx = Entries.Monomorphic_const_entry (UState.context_set universes) in
Future.from_val (univctx, nf t),
Future.chain p (fun (pt,eff) ->
(* Deferred proof, we already checked the universe declaration with
the initial universes, ensure that the final universes respect
the declaration as well. If the declaration is non-extensible,
this will prevent the body from adding universes and constraints. *)
- let bodyunivs = constrain_variables univctx (Future.force univs) in
- let _, univs = Evd.check_univ_decl (Evd.from_ctx bodyunivs) universe_decl in
- (pt,Univ.ContextSet.of_context univs),eff)
+ let bodyunivs = constrain_variables (Future.force univs) in
+ let univs = UState.check_mono_univ_decl bodyunivs universe_decl in
+ (pt,univs),eff)
in
let entry_fn p (_, t) =
let t = EConstr.Unsafe.to_constr t in
let univstyp, body = make_body t p in
let univs, typ = Future.force univstyp in
- let univs =
- if poly then Entries.Polymorphic_const_entry univs
- else Entries.Monomorphic_const_entry univs
- in
{Entries.
const_entry_body = body;
const_entry_secctx = section_vars;
diff --git a/tactics/ind_tables.ml b/tactics/ind_tables.ml
index e7fa555c2..e1bf32f3c 100644
--- a/tactics/ind_tables.ml
+++ b/tactics/ind_tables.ml
@@ -123,10 +123,9 @@ let define internal id c p univs =
let ctx = Evd.normalize_evar_universe_context univs in
let c = Vars.subst_univs_fn_constr
(Universes.make_opt_subst (Evd.evar_universe_context_subst ctx)) c in
- let univs = Evd.evar_context_universe_context ctx in
let univs =
- if p then Polymorphic_const_entry univs
- else Monomorphic_const_entry univs
+ if p then Polymorphic_const_entry (UState.context ctx)
+ else Monomorphic_const_entry (UState.context_set ctx)
in
let entry = {
const_entry_body =
diff --git a/tactics/leminv.ml b/tactics/leminv.ml
index 62f3866de..1ae3577ed 100644
--- a/tactics/leminv.ml
+++ b/tactics/leminv.ml
@@ -232,12 +232,15 @@ let inversion_scheme env sigma t sort dep_option inv_op =
let invProof = it_mkNamedLambda_or_LetIn c !ownSign in
let invProof = EConstr.Unsafe.to_constr invProof in
let p = Evarutil.nf_evars_universes sigma invProof in
- p, Evd.universe_context ~names:[] ~extensible:true sigma
+ p, sigma
let add_inversion_lemma name env sigma t sort dep inv_op =
- let invProof, ctx = inversion_scheme env sigma t sort dep inv_op in
- let entry = definition_entry ~poly:(Flags.use_polymorphic_flag ())
- ~univs:(snd ctx) invProof in
+ let invProof, sigma = inversion_scheme env sigma t sort dep inv_op in
+ let univs =
+ let poly = Flags.use_polymorphic_flag () in
+ Evd.const_univ_entry ~poly sigma
+ in
+ let entry = definition_entry ~univs invProof in
let _ = declare_constant name (DefinitionEntry entry, IsProof Lemma) in
()
diff --git a/test-suite/Makefile b/test-suite/Makefile
index f169f86e8..6865dcc76 100644
--- a/test-suite/Makefile
+++ b/test-suite/Makefile
@@ -95,7 +95,8 @@ VSUBSYSTEMS := prerequisite success failure $(BUGS) output \
SUBSYSTEMS := $(VSUBSYSTEMS) misc bugs ide vio coqchk coqwc coq-makefile
PREREQUISITELOG = prerequisite/admit.v.log \
- prerequisite/make_local.v.log prerequisite/make_notation.v.log
+ prerequisite/make_local.v.log prerequisite/make_notation.v.log \
+ prerequisite/bind_univs.v.log
#######################################################################
# Phony targets
diff --git a/test-suite/bugs/closed/3690.v b/test-suite/bugs/closed/3690.v
index fd9640b89..fa30132ab 100644
--- a/test-suite/bugs/closed/3690.v
+++ b/test-suite/bugs/closed/3690.v
@@ -3,49 +3,44 @@ Set Printing Universes.
Set Universe Polymorphism.
Definition foo (a := Type) (b := Type) (c := Type) := Type.
Print foo.
-(* foo =
-let a := Type@{Top.1} in
-let b := Type@{Top.2} in let c := Type@{Top.3} in Type@{Top.4}
- : Type@{Top.4+1}
-(* Top.1
- Top.2
- Top.3
- Top.4 |= *) *)
-Check @foo. (* foo@{Top.5 Top.6 Top.7
-Top.8}
- : Type@{Top.8+1}
-(* Top.5
- Top.6
- Top.7
- Top.8 |= *) *)
+(* foo@{Top.2 Top.3 Top.5 Top.6 Top.8 Top.9 Top.10} =
+let a := Type@{Top.2} in let b := Type@{Top.5} in let c := Type@{Top.8} in Type@{Top.10}
+ : Type@{Top.10+1}
+(* Top.2 Top.3 Top.5 Top.6 Top.8 Top.9 Top.10 |= Top.2 < Top.3
+ Top.5 < Top.6
+ Top.8 < Top.9
+ *)
+ *)
+Check @foo. (* foo@{Top.11 Top.12 Top.13 Top.14 Top.15 Top.16
+Top.17}
+ : Type@{Top.17+1}
+(* Top.11 Top.12 Top.13 Top.14 Top.15 Top.16 Top.17 |= Top.11 < Top.12
+ Top.13 < Top.14
+ Top.15 < Top.16
+ *)
+ *)
Definition bar := ltac:(let t := eval compute in foo in exact t).
-Check @bar. (* bar@{Top.13 Top.14 Top.15
-Top.16}
- : Type@{Top.16+1}
-(* Top.13
- Top.14
- Top.15
- Top.16 |= *) *)
-(* The following should fail, since [bar] should only need one universe. *)
-Check @bar@{i j}.
+Check @bar. (* bar@{Top.27}
+ : Type@{Top.27+1}
+(* Top.27 |= *) *)
+
+Check @bar@{i}.
Definition baz (a := Type) (b := Type : a) (c := Type : b) := a -> c.
Definition qux := Eval compute in baz.
-Check @qux. (* qux@{Top.24 Top.25
-Top.26}
- : Type@{max(Top.24+1, Top.26+1)}
-(* Top.24
- Top.25
- Top.26 |= Top.25 < Top.24
- Top.26 < Top.25
- *) *)
-Print qux. (* qux =
-Type@{Top.21} -> Type@{Top.23}
- : Type@{max(Top.21+1, Top.23+1)}
-(* Top.21
- Top.22
- Top.23 |= Top.22 < Top.21
- Top.23 < Top.22
- *) *)
+Check @qux. (* qux@{Top.38 Top.39 Top.40
+Top.41}
+ : Type@{max(Top.38+1, Top.41+1)}
+(* Top.38 Top.39 Top.40 Top.41 |= Top.38 < Top.39
+ Top.40 < Top.38
+ Top.41 < Top.40
+ *) *)
+Print qux. (* qux@{Top.34 Top.35 Top.36 Top.37} =
+Type@{Top.34} -> Type@{Top.37}
+ : Type@{max(Top.34+1, Top.37+1)}
+(* Top.34 Top.35 Top.36 Top.37 |= Top.34 < Top.35
+ Top.36 < Top.34
+ Top.37 < Top.36
+ *) *)
Fail Check @qux@{Set Set}.
Check @qux@{Type Type Type Type}.
(* [qux] should only need two universes *)
diff --git a/test-suite/bugs/closed/5347.v b/test-suite/bugs/closed/5347.v
new file mode 100644
index 000000000..9267b3eb6
--- /dev/null
+++ b/test-suite/bugs/closed/5347.v
@@ -0,0 +1,10 @@
+Set Universe Polymorphism.
+
+Axiom X : Type.
+(* Used to declare [x0@{u1 u2} : X@{u1}] and [x1@{} : X@{u2}] leaving
+ the type of x1 with undeclared universes. After PR #891 this should
+ error at declaration time. *)
+Axiom x₀ x₁ : X.
+Axiom Xᵢ : X -> Type.
+
+Check Xᵢ x₁. (* conversion test raised anomaly universe undefined *)
diff --git a/test-suite/bugs/closed/5717.v b/test-suite/bugs/closed/5717.v
new file mode 100644
index 000000000..1bfd917d2
--- /dev/null
+++ b/test-suite/bugs/closed/5717.v
@@ -0,0 +1,5 @@
+Definition foo@{i} (A : Type@{i}) (l : list A) :=
+ match l with
+ | nil => nil
+ | cons _ t => t
+ end.
diff --git a/test-suite/output/UnivBinders.out b/test-suite/output/UnivBinders.out
index 904ff68aa..f69379a57 100644
--- a/test-suite/output/UnivBinders.out
+++ b/test-suite/output/UnivBinders.out
@@ -1,12 +1,155 @@
+NonCumulative Inductive Empty@{u} : Type@{u} :=
+NonCumulative Record PWrap (A : Type@{u}) : Type@{u} := pwrap { punwrap : A }
+
+PWrap has primitive projections with eta conversion.
+For PWrap: Argument scope is [type_scope]
+For pwrap: Argument scopes are [type_scope _]
+punwrap@{u} =
+fun (A : Type@{u}) (p : PWrap@{u} A) => punwrap _ p
+ : forall A : Type@{u}, PWrap@{u} A -> A
+(* u |= *)
+
+punwrap is universe polymorphic
+Argument scopes are [type_scope _]
+NonCumulative Record RWrap (A : Type@{u}) : Type@{u} := rwrap { runwrap : A }
+
+For RWrap: Argument scope is [type_scope]
+For rwrap: Argument scopes are [type_scope _]
+runwrap@{u} =
+fun (A : Type@{u}) (r : RWrap@{u} A) => let (runwrap) := r in runwrap
+ : forall A : Type@{u}, RWrap@{u} A -> A
+(* u |= *)
+
+runwrap is universe polymorphic
+Argument scopes are [type_scope _]
+Wrap@{u} = fun A : Type@{u} => A
+ : Type@{u} -> Type@{u}
+(* u |= *)
+
+Wrap is universe polymorphic
+Argument scope is [type_scope]
+wrap@{u} =
+fun (A : Type@{u}) (Wrap : Wrap@{u} A) => Wrap
+ : forall A : Type@{u}, Wrap@{u} A -> A
+(* u |= *)
+
+wrap is universe polymorphic
+Arguments A, Wrap are implicit and maximally inserted
+Argument scopes are [type_scope _]
bar@{u} = nat
: Wrap@{u} Set
(* u |= Set < u
*)
bar is universe polymorphic
-foo@{u Top.8 v} =
-Type@{Top.8} -> Type@{v} -> Type@{u}
- : Type@{max(u+1, Top.8+1, v+1)}
-(* u Top.8 v |= *)
+foo@{u Top.17 v} =
+Type@{Top.17} -> Type@{v} -> Type@{u}
+ : Type@{max(u+1, Top.17+1, v+1)}
+(* u Top.17 v |= *)
foo is universe polymorphic
+Monomorphic mono = Type@{u}
+ : Type@{u+1}
+(* {u} |= *)
+
+mono is not universe polymorphic
+The command has indeed failed with message:
+Universe u already bound.
+foo@{E M N} =
+Type@{M} -> Type@{N} -> Type@{E}
+ : Type@{max(E+1, M+1, N+1)}
+(* E M N |= *)
+
+foo is universe polymorphic
+foo@{Top.16 Top.17 Top.18} =
+Type@{Top.17} -> Type@{Top.18} -> Type@{Top.16}
+ : Type@{max(Top.16+1, Top.17+1, Top.18+1)}
+(* Top.16 Top.17 Top.18 |= *)
+
+foo is universe polymorphic
+NonCumulative Inductive Empty@{E} : Type@{E} :=
+NonCumulative Record PWrap (A : Type@{E}) : Type@{E} := pwrap { punwrap : A }
+
+PWrap has primitive projections with eta conversion.
+For PWrap: Argument scope is [type_scope]
+For pwrap: Argument scopes are [type_scope _]
+punwrap@{K} : forall A : Type@{K}, PWrap@{K} A -> A
+(* K |= *)
+
+punwrap is universe polymorphic
+Argument scopes are [type_scope _]
+punwrap is transparent
+Expands to: Constant Top.punwrap
+The command has indeed failed with message:
+Universe instance should have length 3
+The command has indeed failed with message:
+Universe instance should have length 0
+The command has indeed failed with message:
+This object does not support universe names.
+The command has indeed failed with message:
+Cannot enforce v < u because u < gU < gV < v
+Monomorphic bind_univs.mono = Type@{u}
+ : Type@{u+1}
+(* {u} |= *)
+
+bind_univs.mono is not universe polymorphic
+bind_univs.poly@{u} = Type@{u}
+ : Type@{u+1}
+(* u |= *)
+
+bind_univs.poly is universe polymorphic
+insec@{v} = Type@{u} -> Type@{v}
+ : Type@{max(u+1, v+1)}
+(* v |= *)
+
+insec is universe polymorphic
+insec@{u v} = Type@{u} -> Type@{v}
+ : Type@{max(u+1, v+1)}
+(* u v |= *)
+
+insec is universe polymorphic
+inmod@{u} = Type@{u}
+ : Type@{u+1}
+(* u |= *)
+
+inmod is universe polymorphic
+SomeMod.inmod@{u} = Type@{u}
+ : Type@{u+1}
+(* u |= *)
+
+SomeMod.inmod is universe polymorphic
+inmod@{u} = Type@{u}
+ : Type@{u+1}
+(* u |= *)
+
+inmod is universe polymorphic
+Applied.infunct@{u v} =
+inmod@{u} -> Type@{v}
+ : Type@{max(u+1, v+1)}
+(* u v |= *)
+
+Applied.infunct is universe polymorphic
+axfoo@{i Top.33 Top.34} : Type@{Top.33} -> Type@{i}
+(* i Top.33 Top.34 |= *)
+
+axfoo is universe polymorphic
+Argument scope is [type_scope]
+Expands to: Constant Top.axfoo
+axbar@{i Top.33 Top.34} : Type@{Top.34} -> Type@{i}
+(* i Top.33 Top.34 |= *)
+
+axbar is universe polymorphic
+Argument scope is [type_scope]
+Expands to: Constant Top.axbar
+axfoo' : Type@{Top.36} -> Type@{i}
+
+axfoo' is not universe polymorphic
+Argument scope is [type_scope]
+Expands to: Constant Top.axfoo'
+axbar' : Type@{Top.36} -> Type@{i}
+
+axbar' is not universe polymorphic
+Argument scope is [type_scope]
+Expands to: Constant Top.axbar'
+The command has indeed failed with message:
+When declaring multiple axioms in one command, only the first is allowed a universe binder (which will be shared by the whole block).
diff --git a/test-suite/output/UnivBinders.v b/test-suite/output/UnivBinders.v
index 8656ff1a3..116d5e5e9 100644
--- a/test-suite/output/UnivBinders.v
+++ b/test-suite/output/UnivBinders.v
@@ -2,12 +2,100 @@ Set Universe Polymorphism.
Set Printing Universes.
Unset Strict Universe Declaration.
-Class Wrap A := wrap : A.
+(* universe binders on inductive types and record projections *)
+Inductive Empty@{u} : Type@{u} := .
+Print Empty.
-Instance bar@{u} : Wrap@{u} Set. Proof nat.
+Set Primitive Projections.
+Record PWrap@{u} (A:Type@{u}) := pwrap { punwrap : A }.
+Print PWrap.
+Print punwrap.
+
+Unset Primitive Projections.
+Record RWrap@{u} (A:Type@{u}) := rwrap { runwrap : A }.
+Print RWrap.
+Print runwrap.
+
+(* universe binders also go on the constants for operational typeclasses. *)
+Class Wrap@{u} (A:Type@{u}) := wrap : A.
+Print Wrap.
+Print wrap.
+
+(* Instance in lemma mode used to ignore the binders. *)
+Instance bar@{u} : Wrap@{u} Set. Proof. exact nat. Qed.
Print bar.
(* The universes in the binder come first, then the extra universes in
order of appearance. *)
Definition foo@{u +} := Type -> Type@{v} -> Type@{u}.
Print foo.
+
+(* Binders even work with monomorphic definitions! *)
+Monomorphic Definition mono@{u} := Type@{u}.
+Print mono.
+
+(* fun x x => foo is nonsense with local binders *)
+Fail Definition fo@{u u} := Type@{u}.
+
+(* Using local binders for printing. *)
+Print foo@{E M N}.
+(* Underscores discard the name if there's one. *)
+Print foo@{_ _ _}.
+
+(* Also works for inductives and records. *)
+Print Empty@{E}.
+Print PWrap@{E}.
+
+(* Also works for About. *)
+About punwrap@{K}.
+
+(* Instance length check. *)
+Fail Print foo@{E}.
+Fail Print mono@{E}.
+
+(* Not everything can be printed with custom universe names. *)
+Fail Print Coq.Init.Logic@{E}.
+
+(* Nice error when constraints are impossible. *)
+Monomorphic Universes gU gV. Monomorphic Constraint gU < gV.
+Fail Lemma foo@{u v|u < gU, gV < v, v < u} : nat.
+
+(* Universe binders survive through compilation, sections and modules. *)
+Require bind_univs.
+Print bind_univs.mono.
+Print bind_univs.poly.
+
+Section SomeSec.
+ Universe u.
+ Definition insec@{v} := Type@{u} -> Type@{v}.
+ Print insec.
+End SomeSec.
+Print insec.
+
+Module SomeMod.
+ Definition inmod@{u} := Type@{u}.
+ Print inmod.
+End SomeMod.
+Print SomeMod.inmod.
+Import SomeMod.
+Print inmod.
+
+Module Type SomeTyp. Definition inmod := Type. End SomeTyp.
+Module SomeFunct (In : SomeTyp).
+ Definition infunct@{u v} := In.inmod@{u} -> Type@{v}.
+End SomeFunct.
+Module Applied := SomeFunct(SomeMod).
+Print Applied.infunct.
+
+(* Multi-axiom declaration
+
+ In polymorphic mode the domain Type gets separate universes for the
+ different axioms, but all axioms have to declare all universes. In
+ polymorphic mode they get the same universes, ie the type is only
+ interpd once. *)
+Axiom axfoo@{i+} axbar : Type -> Type@{i}.
+Monomorphic Axiom axfoo'@{i+} axbar' : Type -> Type@{i}.
+
+About axfoo. About axbar. About axfoo'. About axbar'.
+
+Fail Axiom failfoo failbar@{i} : Type.
diff --git a/test-suite/prerequisite/bind_univs.v b/test-suite/prerequisite/bind_univs.v
new file mode 100644
index 000000000..f17c00e9d
--- /dev/null
+++ b/test-suite/prerequisite/bind_univs.v
@@ -0,0 +1,5 @@
+(* Used in output/UnivBinders.v *)
+
+Monomorphic Definition mono@{u} := Type@{u}.
+
+Polymorphic Definition poly@{u} := Type@{u}.
diff --git a/test-suite/success/polymorphism.v b/test-suite/success/polymorphism.v
index 7eaafc354..d76b30791 100644
--- a/test-suite/success/polymorphism.v
+++ b/test-suite/success/polymorphism.v
@@ -190,6 +190,8 @@ Module binders.
Fail Defined.
Abort.
+ Fail Lemma bar@{u v | } : let x := (fun x => x) : Type@{u} -> Type@{v} in nat.
+
Lemma bar@{i j| i < j} : Type@{j}.
Proof.
exact Type@{i}.
@@ -200,6 +202,10 @@ Module binders.
exact Type@{i}.
Qed.
+ Monomorphic Universe M.
+ Fail Definition with_mono@{u|} : Type@{M} := Type@{u}.
+ Definition with_mono@{u|u < M} : Type@{M} := Type@{u}.
+
End binders.
Section cats.
@@ -399,6 +405,31 @@ Module Anonymous.
End Anonymous.
+Module Restrict.
+ (* Universes which don't appear in the term should be pruned, unless they have names *)
+ Set Universe Polymorphism.
+
+ Ltac exact0 := let x := constr:(Type) in exact 0.
+ Definition dummy_pruned@{} : nat := ltac:(exact0).
+
+ Definition named_not_pruned@{u} : nat := 0.
+ Check named_not_pruned@{_}.
+
+ Definition named_not_pruned_nonstrict : nat := ltac:(let x := constr:(Type@{u}) in exact 0).
+ Check named_not_pruned_nonstrict@{_}.
+
+ Lemma lemma_restrict_poly@{} : nat.
+ Proof. exact0. Defined.
+
+ Unset Universe Polymorphism.
+ Lemma lemma_restrict_mono_qed@{} : nat.
+ Proof. exact0. Qed.
+
+ Lemma lemma_restrict_abstract@{} : nat.
+ Proof. abstract exact0. Qed.
+
+End Restrict.
+
Module F.
Context {A B : Type}.
Definition foo : Type := B.
@@ -430,3 +461,10 @@ Section test_letin_subtyping.
Qed.
End test_letin_subtyping.
+
+Module ObligationRegression.
+ (** Test for a regression encountered when fixing obligations for
+ stronger restriction of universe context. *)
+ Require Import CMorphisms.
+ Check trans_co_eq_inv_arrow_morphism@{_ _ _ _ _ _ _ _}.
+End ObligationRegression.
diff --git a/vernac/class.ml b/vernac/class.ml
index 44f20a088..943da8fa8 100644
--- a/vernac/class.ml
+++ b/vernac/class.ml
@@ -212,10 +212,10 @@ let build_id_coercion idf_opt source poly =
Id.of_string ("Id_"^(ident_key_of_class source)^"_"^
(ident_key_of_class cl))
in
- let univs = (snd (Evd.universe_context ~names:[] ~extensible:true sigma)) in
+ let univs = Evd.const_univ_entry ~poly sigma in
let constr_entry = (* Cast is necessary to express [val_f] is identity *)
DefinitionEntry
- (definition_entry ~types:typ_f ~poly ~univs
+ (definition_entry ~types:typ_f ~univs
~inline:true (mkCast (val_f, DEFAULTcast, typ_f)))
in
let decl = (constr_entry, IsDefinition IdentityCoercion) in
diff --git a/vernac/classes.ml b/vernac/classes.ml
index 20cb43b24..b80741269 100644
--- a/vernac/classes.ml
+++ b/vernac/classes.ml
@@ -119,14 +119,14 @@ let declare_instance_constant k info global imps ?hook id decl poly evm term ter
(Univops.universes_of_constr term) in
Evd.restrict_universe_context evm levels
in
- let pl, uctx = Evd.check_univ_decl evm decl in
+ let uctx = Evd.check_univ_decl ~poly evm decl in
let entry =
- Declare.definition_entry ~types:termtype ~poly ~univs:uctx term
+ Declare.definition_entry ~types:termtype ~univs:uctx term
in
let cdecl = (DefinitionEntry entry, kind) in
let kn = Declare.declare_constant id cdecl in
Declare.definition_message id;
- Universes.register_universe_binders (ConstRef kn) pl;
+ Universes.register_universe_binders (ConstRef kn) (Evd.universe_binders evm);
instance_hook k info global imps ?hook (ConstRef kn);
id
@@ -200,16 +200,16 @@ let new_instance ?(abstract=false) ?(global=false) ?(refine= !refine_instance)
let nf, subst = Evarutil.e_nf_evars_and_universes evars in
let termtype =
let t = it_mkProd_or_LetIn ty_constr (ctx' @ ctx) in
- nf t
- in
- Pretyping.check_evars env Evd.empty !evars (EConstr.of_constr termtype);
- let pl, ctx = Evd.check_univ_decl !evars decl in
- let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
- (ParameterEntry
- (None,poly,(termtype,ctx),None), Decl_kinds.IsAssumption Decl_kinds.Logical)
- in
- Universes.register_universe_binders (ConstRef cst) pl;
- instance_hook k pri global imps ?hook (ConstRef cst); id
+ nf t
+ in
+ Pretyping.check_evars env Evd.empty !evars (EConstr.of_constr termtype);
+ let univs = Evd.check_univ_decl ~poly !evars decl in
+ let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id
+ (ParameterEntry
+ (None,(termtype,univs),None), Decl_kinds.IsAssumption Decl_kinds.Logical)
+ in
+ Universes.register_universe_binders (ConstRef cst) (Evd.universe_binders !evars);
+ instance_hook k pri global imps ?hook (ConstRef cst); id
end
else (
let props =
@@ -384,14 +384,17 @@ let context poly l =
let uctx = ref (Evd.universe_context_set !evars) in
let fn status (id, b, t) =
if Lib.is_modtype () && not (Lib.sections_are_opened ()) then
- let ctx = Univ.ContextSet.to_context !uctx in
(* Declare the universe context once *)
+ let univs = if poly
+ then Polymorphic_const_entry (Univ.ContextSet.to_context !uctx)
+ else Monomorphic_const_entry !uctx
+ in
let () = uctx := Univ.ContextSet.empty in
let decl = match b with
| None ->
- (ParameterEntry (None,poly,(t,ctx),None), IsAssumption Logical)
+ (ParameterEntry (None,(t,univs),None), IsAssumption Logical)
| Some b ->
- let entry = Declare.definition_entry ~poly ~univs:ctx ~types:t b in
+ let entry = Declare.definition_entry ~univs ~types:t b in
(DefinitionEntry entry, IsAssumption Logical)
in
let cst = Declare.declare_constant ~internal:Declare.InternalTacticRequest id decl in
@@ -409,16 +412,19 @@ let context poly l =
in
let impl = List.exists test impls in
let decl = (Discharge, poly, Definitional) in
+ let univs = if poly
+ then Polymorphic_const_entry (Univ.ContextSet.to_context !uctx)
+ else Monomorphic_const_entry !uctx
+ in
let nstatus = match b with
| None ->
- pi3 (Command.declare_assumption false decl (t, !uctx) [] [] impl
+ pi3 (Command.declare_assumption false decl (t, univs) Universes.empty_binders [] impl
Vernacexpr.NoInline (Loc.tag id))
| Some b ->
- let ctx = Univ.ContextSet.to_context !uctx in
let decl = (Discharge, poly, Definition) in
- let entry = Declare.definition_entry ~poly ~univs:ctx ~types:t b in
+ let entry = Declare.definition_entry ~univs ~types:t b in
let hook = Lemmas.mk_hook (fun _ gr -> gr) in
- let _ = DeclareDef.declare_definition id decl entry [] [] hook in
+ let _ = DeclareDef.declare_definition id decl entry Universes.empty_binders [] hook in
Lib.sections_are_opened () || Lib.is_modtype_strict ()
in
status && nstatus
diff --git a/vernac/command.ml b/vernac/command.ml
index 257c003b5..373e5a1be 100644
--- a/vernac/command.ml
+++ b/vernac/command.ml
@@ -88,7 +88,7 @@ let warn_implicits_in_term =
strbrk "Implicit arguments declaration relies on type." ++ spc () ++
strbrk "The term declares more implicits than the type here.")
-let interp_definition pl bl p red_option c ctypopt =
+let interp_definition pl bl poly red_option c ctypopt =
let env = Global.env() in
let evd, decl = Univdecls.interp_univ_decl_opt env pl in
let evdref = ref evd in
@@ -105,14 +105,15 @@ let interp_definition pl bl p red_option c ctypopt =
let c = EConstr.Unsafe.to_constr c in
let nf,subst = Evarutil.e_nf_evars_and_universes evdref in
let body = nf (it_mkLambda_or_LetIn c ctx) in
- let vars = Univops.universes_of_constr body in
- let evd = Evd.restrict_universe_context !evdref vars in
- let pl, uctx = Evd.check_univ_decl evd decl in
- imps1@(Impargs.lift_implicits nb_args imps2), pl,
- definition_entry ~univs:uctx ~poly:p body
+ let vars = Univops.universes_of_constr body in
+ let evd = Evd.restrict_universe_context !evdref vars in
+ let uctx = Evd.check_univ_decl ~poly evd decl in
+ let binders = Evd.universe_binders evd in
+ imps1@(Impargs.lift_implicits nb_args imps2), binders,
+ definition_entry ~univs:uctx body
| Some ctyp ->
- let ty, impsty = interp_type_evars_impls ~impls env_bl evdref ctyp in
- let subst = evd_comb0 Evd.nf_univ_variables evdref in
+ let ty, impsty = interp_type_evars_impls ~impls env_bl evdref ctyp in
+ let subst = evd_comb0 Evd.nf_univ_variables evdref in
let ctx = Context.Rel.map (Vars.subst_univs_constr subst) ctx in
let env_bl = push_rel_context ctx env in
let c, imps2 = interp_casted_constr_evars_impls ~impls env_bl evdref c ty in
@@ -133,9 +134,10 @@ let interp_definition pl bl p red_option c ctypopt =
let vars = Univ.LSet.union (Univops.universes_of_constr body)
(Univops.universes_of_constr typ) in
let ctx = Evd.restrict_universe_context !evdref vars in
- let pl, uctx = Evd.check_univ_decl ctx decl in
- imps1@(Impargs.lift_implicits nb_args impsty), pl,
- definition_entry ~types:typ ~poly:p
+ let uctx = Evd.check_univ_decl ~poly ctx decl in
+ let binders = Evd.universe_binders evd in
+ imps1@(Impargs.lift_implicits nb_args impsty), binders,
+ definition_entry ~types:typ
~univs:uctx body
in
red_constant_entry (Context.Rel.length ctx) ce !evdref red_option, !evdref, decl, pl, imps
@@ -175,6 +177,10 @@ let do_definition ident k univdecl bl red_option c ctypopt hook =
let declare_assumption is_coe (local,p,kind) (c,ctx) pl imps impl nl (_,ident) =
match local with
| Discharge when Lib.sections_are_opened () ->
+ let ctx = match ctx with
+ | Monomorphic_const_entry ctx -> ctx
+ | Polymorphic_const_entry ctx -> Univ.ContextSet.of_context ctx
+ in
let decl = (Lib.cwd(), SectionLocalAssum ((c,ctx),p,impl), IsAssumption kind) in
let _ = declare_variable ident decl in
let () = assumption_message ident in
@@ -195,8 +201,7 @@ match local with
| DefaultInline -> Some (Flags.get_inline_level())
| InlineAt i -> Some i
in
- let ctx = Univ.ContextSet.to_context ctx in
- let decl = (ParameterEntry (None,p,(c,ctx),inl), IsAssumption kind) in
+ let decl = (ParameterEntry (None,(c,ctx),inl), IsAssumption kind) in
let kn = declare_constant ident ~local decl in
let gr = ConstRef kn in
let () = maybe_declare_manual_implicits false gr imps in
@@ -204,9 +209,9 @@ match local with
let () = assumption_message ident in
let () = Typeclasses.declare_instance None false gr in
let () = if is_coe then Class.try_add_new_coercion gr ~local p in
- let inst =
- if p (* polymorphic *) then Univ.UContext.instance ctx
- else Univ.Instance.empty
+ let inst = match ctx with
+ | Polymorphic_const_entry ctx -> Univ.UContext.instance ctx
+ | Monomorphic_const_entry _ -> Univ.Instance.empty
in
(gr,inst,Lib.is_modtype_strict ())
@@ -216,26 +221,63 @@ let interp_assumption evdref env impls bl c =
let ty = EConstr.Unsafe.to_constr ty in
(ty, impls)
-let declare_assumptions idl is_coe k (c,ctx) pl imps impl_is_on nl =
+(* When monomorphic the universe constraints are declared with the first declaration only. *)
+let next_uctx =
+ let empty_uctx = Monomorphic_const_entry Univ.ContextSet.empty in
+ function
+ | Polymorphic_const_entry _ as uctx -> uctx
+ | Monomorphic_const_entry _ -> empty_uctx
+
+let declare_assumptions idl is_coe k (c,uctx) pl imps nl =
let refs, status, _ =
- List.fold_left (fun (refs,status,ctx) id ->
+ List.fold_left (fun (refs,status,uctx) id ->
let ref',u',status' =
- declare_assumption is_coe k (c,ctx) pl imps impl_is_on nl id in
- (ref',u')::refs, status' && status, Univ.ContextSet.empty)
- ([],true,ctx) idl
+ declare_assumption is_coe k (c,uctx) pl imps false nl id in
+ (ref',u')::refs, status' && status, next_uctx uctx)
+ ([],true,uctx) idl
in
List.rev refs, status
-let do_assumptions_unbound_univs (_, poly, _ as kind) nl l =
+
+let maybe_error_many_udecls = function
+ | ((loc,id), Some _) ->
+ user_err ?loc ~hdr:"many_universe_declarations"
+ Pp.(str "When declaring multiple axioms in one command, " ++
+ str "only the first is allowed a universe binder " ++
+ str "(which will be shared by the whole block).")
+ | (_, None) -> ()
+
+let process_assumptions_udecls kind l =
+ let udecl, first_id = match l with
+ | (coe, ((id, udecl)::rest, c))::rest' ->
+ List.iter maybe_error_many_udecls rest;
+ List.iter (fun (coe, (idl, c)) -> List.iter maybe_error_many_udecls idl) rest';
+ udecl, id
+ | (_, ([], _))::_ | [] -> assert false
+ in
+ let () = match kind, udecl with
+ | (Discharge, _, _), Some _ when Lib.sections_are_opened () ->
+ let loc = fst first_id in
+ let msg = Pp.str "Section variables cannot be polymorphic." in
+ user_err ?loc msg
+ | _ -> ()
+ in
+ udecl, List.map (fun (coe, (idl, c)) -> coe, (List.map fst idl, c)) l
+
+let do_assumptions kind nl l =
let open Context.Named.Declaration in
let env = Global.env () in
- let evdref = ref (Evd.from_env env) in
- let l =
- if poly then
+ let udecl, l = process_assumptions_udecls kind l in
+ let evdref, udecl =
+ let evd, udecl = Univdecls.interp_univ_decl_opt env udecl in
+ ref evd, udecl
+ in
+ let l =
+ if pi2 kind (* poly *) then
(* Separate declarations so that A B : Type puts A and B in different levels. *)
List.fold_right (fun (is_coe,(idl,c)) acc ->
- List.fold_right (fun id acc ->
- (is_coe, ([id], c)) :: acc) idl acc)
+ List.fold_right (fun id acc ->
+ (is_coe, ([id], c)) :: acc) idl acc)
l []
else l
in
@@ -247,65 +289,31 @@ let do_assumptions_unbound_univs (_, poly, _ as kind) nl l =
let ienv = List.fold_right (fun (_,id) ienv ->
let impls = compute_internalization_data env Variable t imps in
Id.Map.add id impls ienv) idl ienv in
- ((env,ienv),((is_coe,idl),t,imps)))
+ ((env,ienv),((is_coe,idl),t,imps)))
(env,empty_internalization_env) l
in
let evd = solve_remaining_evars all_and_fail_flags env !evdref Evd.empty in
(* The universe constraints come from the whole telescope. *)
let evd = Evd.nf_constraints evd in
- let ctx = Evd.universe_context_set evd in
- let nf_evar c = EConstr.Unsafe.to_constr (nf_evar evd (EConstr.of_constr c)) in
- let l = List.map (on_pi2 nf_evar) l in
- pi2 (List.fold_left (fun (subst,status,ctx) ((is_coe,idl),t,imps) ->
- let t = replace_vars subst t in
- let (refs,status') = declare_assumptions idl is_coe kind (t,ctx) [] imps false nl in
- let subst' = List.map2
- (fun (_,id) (c,u) -> (id,Universes.constr_of_global_univ (c,u)))
- idl refs
- in
- (subst'@subst, status' && status,
- (* The universe constraints are declared with the first declaration only. *)
- Univ.ContextSet.empty)) ([],true,ctx) l)
-
-let do_assumptions_bound_univs coe kind nl id pl c =
- let env = Global.env () in
- let evd, decl = Univdecls.interp_univ_decl_opt env pl in
- let evdref = ref evd in
- let ty, impls = interp_type_evars_impls env evdref c in
- let nf, subst = Evarutil.e_nf_evars_and_universes evdref in
- let ty = EConstr.Unsafe.to_constr ty in
- let ty = nf ty in
- let vars = Univops.universes_of_constr ty in
- let evd = Evd.restrict_universe_context !evdref vars in
- let pl, uctx = Evd.check_univ_decl evd decl in
- let uctx = Univ.ContextSet.of_context uctx in
- let (_, _, st) = declare_assumption coe kind (ty, uctx) pl impls false nl id in
- st
-
-let do_assumptions kind nl l = match l with
-| [coe, ([id, Some pl], c)] ->
- let () = match kind with
- | (Discharge, _, _) when Lib.sections_are_opened () ->
- let loc = fst id in
- let msg = Pp.str "Section variables cannot be polymorphic." in
- user_err ?loc msg
- | _ -> ()
+ let nf_evar c = EConstr.to_constr evd (EConstr.of_constr c) in
+ let uvars, l = List.fold_left_map (fun uvars (coe,t,imps) ->
+ let t = nf_evar t in
+ let uvars = Univ.LSet.union uvars (Univops.universes_of_constr t) in
+ uvars, (coe,t,imps))
+ Univ.LSet.empty l
in
- do_assumptions_bound_univs coe kind nl id (Some pl) c
-| _ ->
- let map (coe, (idl, c)) =
- let map (id, univs) = match univs with
- | None -> id
- | Some _ ->
- let loc = fst id in
- let msg =
- Pp.str "Assumptions with bound universes can only be defined one at a time." in
- user_err ?loc msg
- in
- (coe, (List.map map idl, c))
- in
- let l = List.map map l in
- do_assumptions_unbound_univs kind nl l
+ let evd = Evd.restrict_universe_context evd uvars in
+ let uctx = Evd.check_univ_decl ~poly:(pi2 kind) evd udecl in
+ let ubinders = Evd.universe_binders evd in
+ pi2 (List.fold_left (fun (subst,status,uctx) ((is_coe,idl),t,imps) ->
+ let t = replace_vars subst t in
+ let refs, status' = declare_assumptions idl is_coe kind (t,uctx) ubinders imps nl in
+ let subst' = List.map2
+ (fun (_,id) (c,u) -> (id, Universes.constr_of_global_univ (c,u)))
+ idl refs
+ in
+ subst'@subst, status' && status, next_uctx uctx)
+ ([], true, uctx) l)
(* 3a| Elimination schemes for mutual inductive definitions *)
@@ -576,7 +584,7 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
let constructors = List.map (fun (idl,cl,impsl) -> (idl,List.map nf' cl,impsl)) constructors in
let ctx_params = Context.Rel.map nf ctx_params in
let evd = !evdref in
- let pl, uctx = Evd.check_univ_decl evd decl in
+ let uctx = Evd.check_univ_decl ~poly evd decl in
List.iter (fun c -> check_evars env_params Evd.empty evd (EConstr.of_constr c)) arities;
Context.Rel.iter (fun c -> check_evars env0 Evd.empty evd (EConstr.of_constr c)) ctx_params;
List.iter (fun (_,ctyps,_) ->
@@ -598,11 +606,12 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
userimpls @ (lift_implicits len impls)) cimpls) indimpls constructors
in
let univs =
- if poly then
+ match uctx with
+ | Polymorphic_const_entry uctx ->
if cum then
Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context uctx)
else Polymorphic_ind_entry uctx
- else
+ | Monomorphic_const_entry uctx ->
Monomorphic_ind_entry uctx
in
(* Build the mutual inductive entry *)
@@ -617,7 +626,7 @@ let interp_mutual_inductive (paramsl,indl) notations cum poly prv finite =
in
(if poly && cum then
Inductiveops.infer_inductive_subtyping env_ar evd mind_ent
- else mind_ent), pl, impls
+ else mind_ent), Evd.universe_binders evd, impls
(* Very syntactical equality *)
let eq_local_binders bl1 bl2 =
@@ -1019,23 +1028,22 @@ let build_wellfounded (recname,pl,n,bl,arityc,body) poly r measure notation =
let binders_rel = nf_evar_context !evdref binders_rel in
let binders = nf_evar_context !evdref binders in
let top_arity = Evarutil.nf_evar !evdref top_arity in
- let pl, plext = Option.cata
- (fun d -> d.univdecl_instance, d.univdecl_extensible_instance) ([],true) pl in
let hook, recname, typ =
if List.length binders_rel > 1 then
let name = add_suffix recname "_func" in
let hook l gr _ =
- let body = it_mkLambda_or_LetIn (mkApp (Evarutil.e_new_global evdref gr, [|make|])) binders_rel in
- let ty = it_mkProd_or_LetIn top_arity binders_rel in
- let ty = EConstr.Unsafe.to_constr ty in
- let pl, univs = Evd.universe_context ~names:pl ~extensible:plext !evdref in
- (*FIXME poly? *)
- let ce = definition_entry ~poly ~types:ty ~univs (EConstr.to_constr !evdref body) in
- (** FIXME: include locality *)
- let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
- let gr = ConstRef c in
- if Impargs.is_implicit_args () || not (List.is_empty impls) then
- Impargs.declare_manual_implicits false gr [impls]
+ let body = it_mkLambda_or_LetIn (mkApp (Evarutil.e_new_global evdref gr, [|make|])) binders_rel in
+ let ty = it_mkProd_or_LetIn top_arity binders_rel in
+ let ty = EConstr.Unsafe.to_constr ty in
+ let univs = Evd.check_univ_decl ~poly !evdref decl in
+ (*FIXME poly? *)
+ let ce = definition_entry ~types:ty ~univs (EConstr.to_constr !evdref body) in
+ (** FIXME: include locality *)
+ let c = Declare.declare_constant recname (DefinitionEntry ce, IsDefinition Definition) in
+ let gr = ConstRef c in
+ let () = Universes.register_universe_binders gr (Evd.universe_binders !evdref) in
+ if Impargs.is_implicit_args () || not (List.is_empty impls) then
+ Impargs.declare_manual_implicits false gr [impls]
in
let typ = it_mkProd_or_LetIn top_arity binders in
hook, name, typ
@@ -1168,7 +1176,8 @@ let declare_fixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) ind
List.map_i (fun i _ -> mkFix ((indexes,i),fixdecls)) 0 fixnames in
let evd = Evd.from_ctx ctx in
let evd = Evd.restrict_universe_context evd vars in
- let pl, ctx = Evd.check_univ_decl evd pl in
+ let ctx = Evd.check_univ_decl ~poly evd pl in
+ let pl = Evd.universe_binders evd in
let fixdecls = List.map Safe_typing.mk_pure_proof fixdecls in
ignore (List.map4 (DeclareDef.declare_fix (local, poly, Fixpoint) pl ctx)
fixnames fixdecls fixtypes fiximps);
@@ -1200,7 +1209,8 @@ let declare_cofixpoint local poly ((fixnames,fixdefs,fixtypes),pl,ctx,fiximps) n
let fiximps = List.map (fun (len,imps,idx) -> imps) fiximps in
let evd = Evd.from_ctx ctx in
let evd = Evd.restrict_universe_context evd vars in
- let pl, ctx = Evd.check_univ_decl evd pl in
+ let ctx = Evd.check_univ_decl ~poly evd pl in
+ let pl = Evd.universe_binders evd in
ignore (List.map4 (DeclareDef.declare_fix (local, poly, CoFixpoint) pl ctx)
fixnames fixdecls fixtypes fiximps);
(* Declare the recursive definitions *)
diff --git a/vernac/command.mli b/vernac/command.mli
index fb99a717b..070f3e112 100644
--- a/vernac/command.mli
+++ b/vernac/command.mli
@@ -43,7 +43,7 @@ val do_definition : Id.t -> definition_kind -> Vernacexpr.universe_decl_expr opt
(** returns [false] if the assumption is neither local to a section,
nor in a module type and meant to be instantiated. *)
val declare_assumption : coercion_flag -> assumption_kind ->
- types Univ.in_universe_context_set ->
+ types in_constant_universes_entry ->
Universes.universe_binders -> Impargs.manual_implicits ->
bool (** implicit *) -> Vernacexpr.inline -> variable Loc.located ->
global_reference * Univ.Instance.t * bool
diff --git a/vernac/declareDef.ml b/vernac/declareDef.ml
index c18744052..980db4109 100644
--- a/vernac/declareDef.ml
+++ b/vernac/declareDef.ml
@@ -57,7 +57,7 @@ let declare_definition ident (local, p, k) ce pl imps hook =
declare_global_definition ident ce local k pl imps in
Lemmas.call_hook fix_exn hook local r
-let declare_fix ?(opaque = false) (_,poly,_ as kind) pl ctx f ((def,_),eff) t imps =
- let ce = definition_entry ~opaque ~types:t ~poly ~univs:ctx ~eff def in
+let declare_fix ?(opaque = false) (_,poly,_ as kind) pl univs f ((def,_),eff) t imps =
+ let ce = definition_entry ~opaque ~types:t ~univs ~eff def in
declare_definition f kind ce pl imps (Lemmas.mk_hook (fun _ r -> r))
diff --git a/vernac/declareDef.mli b/vernac/declareDef.mli
index 01a87818a..55f7c7861 100644
--- a/vernac/declareDef.mli
+++ b/vernac/declareDef.mli
@@ -15,5 +15,8 @@ val declare_definition : Id.t -> definition_kind ->
Safe_typing.private_constants Entries.definition_entry -> Universes.universe_binders -> Impargs.manual_implicits ->
Globnames.global_reference Lemmas.declaration_hook -> Globnames.global_reference
-val declare_fix : ?opaque:bool -> definition_kind -> Universes.universe_binders -> Univ.UContext.t -> Id.t ->
- Safe_typing.private_constants Entries.proof_output -> Constr.types -> Impargs.manual_implicits -> Globnames.global_reference
+val declare_fix : ?opaque:bool -> definition_kind ->
+ Universes.universe_binders -> Entries.constant_universes_entry ->
+ Id.t -> Safe_typing.private_constants Entries.proof_output ->
+ Constr.types -> Impargs.manual_implicits ->
+ Globnames.global_reference
diff --git a/vernac/indschemes.ml b/vernac/indschemes.ml
index c0ddc7e2c..e4ca98749 100644
--- a/vernac/indschemes.ml
+++ b/vernac/indschemes.ml
@@ -109,10 +109,10 @@ let _ =
let define id internal ctx c t =
let f = declare_constant ~internal in
- let _, univs = Evd.universe_context ~names:[] ~extensible:true ctx in
let univs =
- if Flags.is_universe_polymorphism () then Polymorphic_const_entry univs
- else Monomorphic_const_entry univs
+ if Flags.is_universe_polymorphism ()
+ then Polymorphic_const_entry (Evd.to_universe_context ctx)
+ else Monomorphic_const_entry (Evd.universe_context_set ctx)
in
let kn = f id
(DefinitionEntry
diff --git a/vernac/lemmas.ml b/vernac/lemmas.ml
index a025bfff8..42631a15b 100644
--- a/vernac/lemmas.ml
+++ b/vernac/lemmas.ml
@@ -49,7 +49,8 @@ let retrieve_first_recthm uctx = function
(NamedDecl.get_value (Global.lookup_named id),variable_opacity id)
| ConstRef cst ->
let cb = Global.lookup_constant cst in
- let (_, uctx) = UState.universe_context ~names:[] ~extensible:true uctx in
+ (* we get the right order somehow but surely it could be enforced in a better way *)
+ let uctx = UState.context uctx in
let inst = Univ.UContext.instance uctx in
let map (c, ctx) = Vars.subst_instance_constr inst c in
(Option.map map (Global.body_of_constant_body cb), is_opaque cb)
@@ -203,7 +204,7 @@ let save ?export_seff id const cstrs pl do_guard (locality,poly,kind) hook =
(locality, ConstRef kn)
in
definition_message id;
- Option.iter (Universes.register_universe_binders r) pl;
+ Universes.register_universe_binders r (Option.default Universes.empty_binders pl);
call_hook (fun exn -> exn) hook l r
with e when CErrors.noncritical e ->
let e = CErrors.push e in
@@ -223,7 +224,7 @@ let compute_proof_name locality = function
let avoid = Id.Set.of_list (Proof_global.get_all_proof_names ()) in
next_global_ident_away default_thm_id avoid
-let save_remaining_recthms (locality,p,kind) norm ctx binders body opaq i (id,(t_i,(_,imps))) =
+let save_remaining_recthms (locality,p,kind) norm univs body opaq i (id,(t_i,(_,imps))) =
let t_i = norm t_i in
match body with
| None ->
@@ -231,7 +232,13 @@ let save_remaining_recthms (locality,p,kind) norm ctx binders body opaq i (id,(t
| Discharge ->
let impl = false in (* copy values from Vernacentries *)
let k = IsAssumption Conjectural in
- let c = SectionLocalAssum ((t_i,Univ.ContextSet.of_context ctx),p,impl) in
+ let univs = match univs with
+ | Polymorphic_const_entry univs ->
+ (* What is going on here? *)
+ Univ.ContextSet.of_context univs
+ | Monomorphic_const_entry univs -> univs
+ in
+ let c = SectionLocalAssum ((t_i, univs),p,impl) in
let _ = declare_variable id (Lib.cwd(),c,k) in
(Discharge, VarRef id,imps)
| Local | Global ->
@@ -241,7 +248,7 @@ let save_remaining_recthms (locality,p,kind) norm ctx binders body opaq i (id,(t
| Global -> false
| Discharge -> assert false
in
- let decl = (ParameterEntry (None,p,(t_i,ctx),None), k) in
+ let decl = (ParameterEntry (None,(t_i,univs),None), k) in
let kn = declare_constant id ~local decl in
(locality,ConstRef kn,imps))
| Some body ->
@@ -259,8 +266,7 @@ let save_remaining_recthms (locality,p,kind) norm ctx binders body opaq i (id,(t
let body_i = body_i body in
match locality with
| Discharge ->
- let const = definition_entry ~types:t_i ~opaque:opaq ~poly:p
- ~univs:ctx body_i in
+ let const = definition_entry ~types:t_i ~opaque:opaq ~univs body_i in
let c = SectionLocalDef const in
let _ = declare_variable id (Lib.cwd(), c, k) in
(Discharge,VarRef id,imps)
@@ -271,7 +277,7 @@ let save_remaining_recthms (locality,p,kind) norm ctx binders body opaq i (id,(t
| Discharge -> assert false
in
let const =
- Declare.definition_entry ~types:t_i ~poly:p ~univs:ctx ~opaque:opaq body_i
+ Declare.definition_entry ~types:t_i ~univs ~opaque:opaq body_i
in
let kn = declare_constant id ~local (DefinitionEntry const, k) in
(locality,ConstRef kn,imps)
@@ -306,7 +312,7 @@ let admit (id,k,e) pl hook () =
| Local, _, _ | Discharge, _, _ -> warn_let_as_axiom id
in
let () = assumption_message id in
- Option.iter (Universes.register_universe_binders (ConstRef kn)) pl;
+ Universes.register_universe_binders (ConstRef kn) (Option.default Universes.empty_binders pl);
call_hook (fun exn -> exn) hook Global (ConstRef kn)
(* Starting a goal *)
@@ -420,9 +426,9 @@ let start_proof_with_initialization kind ctx decl recguard thms snl hook =
let body,opaq = retrieve_first_recthm ctx ref in
let subst = Evd.evar_universe_context_subst ctx in
let norm c = Universes.subst_opt_univs_constr subst c in
- let binders, ctx = Evd.check_univ_decl (Evd.from_ctx ctx) decl in
- let body = Option.map norm body in
- List.map_i (save_remaining_recthms kind norm ctx binders body opaq) 1 other_thms in
+ let ctx = UState.check_univ_decl ~poly:(pi2 kind) ctx decl in
+ let body = Option.map norm body in
+ List.map_i (save_remaining_recthms kind norm ctx body opaq) 1 other_thms in
let thms_data = (strength,ref,imps)::other_thms_data in
List.iter (fun (strength,ref,imps) ->
maybe_declare_manual_implicits false ref imps;
@@ -453,9 +459,9 @@ let start_proof_com ?inference_hook kind thms hook =
let evd, nf = Evarutil.nf_evars_and_universes !evdref in
let thms = List.map (fun (n, (t, info)) -> (n, (nf t, info))) thms in
let () =
- if not decl.Misctypes.univdecl_extensible_instance then
- ignore (Evd.universe_context evd ~names:decl.Misctypes.univdecl_instance ~extensible:false)
- else ()
+ let open Misctypes in
+ if not (decl.univdecl_extensible_instance && decl.univdecl_extensible_constraints) then
+ ignore (Evd.check_univ_decl ~poly:(pi2 kind) evd decl)
in
let evd =
if pi2 kind then evd
@@ -490,9 +496,9 @@ let save_proof ?proof = function
if const_entry_type = None then
user_err Pp.(str "Admitted requires an explicit statement");
let typ = Option.get const_entry_type in
- let ctx = Evd.evar_context_universe_context (fst universes) in
+ let ctx = UState.const_univ_entry ~poly:(pi2 k) (fst universes) in
let sec_vars = if !keep_admitted_vars then const_entry_secctx else None in
- Admitted(id, k, (sec_vars, pi2 k, (typ, ctx), None), universes)
+ Admitted(id, k, (sec_vars, (typ, ctx), None), universes)
| None ->
let pftree = Proof_global.give_me_the_proof () in
let id, k, typ = Pfedit.current_proof_statement () in
@@ -513,10 +519,10 @@ let save_proof ?proof = function
| _ -> None in
let decl = Proof_global.get_universe_decl () in
let evd = Evd.from_ctx universes in
- let binders, ctx = Evd.check_univ_decl evd decl in
let poly = pi2 k in
- let binders = if poly then Some binders else None in
- Admitted(id,k,(sec_vars, poly, (typ, ctx), None),
+ let ctx = Evd.check_univ_decl ~poly evd decl in
+ let binders = if poly then Some (UState.universe_binders universes) else None in
+ Admitted(id,k,(sec_vars, (typ, ctx), None),
(universes, binders))
in
Proof_global.apply_terminator (Proof_global.get_terminator ()) pe
diff --git a/vernac/obligations.ml b/vernac/obligations.ml
index 700fd6045..1046d68f8 100644
--- a/vernac/obligations.ml
+++ b/vernac/obligations.ml
@@ -475,20 +475,17 @@ let declare_definition prg =
(Evd.evar_universe_context_subst prg.prg_ctx) in
let opaque = prg.prg_opaque in
let fix_exn = Hook.get get_fix_exn () in
- let pl, ctx = Evd.check_univ_decl (Evd.from_ctx prg.prg_ctx) prg.prg_univdecl in
- let ce =
- definition_entry ~fix_exn
- ~opaque ~types:(nf typ) ~poly:(pi2 prg.prg_kind)
- ~univs:(Evd.evar_context_universe_context prg.prg_ctx) (nf body)
- in
+ let typ = nf typ in
+ let body = nf body in
+ let uvars = Univ.LSet.union (Univops.universes_of_constr typ) (Univops.universes_of_constr body) in
+ let uctx = UState.restrict prg.prg_ctx uvars in
+ let univs = UState.check_univ_decl ~poly:(pi2 prg.prg_kind) uctx prg.prg_univdecl in
+ let ce = definition_entry ~fix_exn ~opaque ~types:typ ~univs body in
let () = progmap_remove prg in
- let cst =
- DeclareDef.declare_definition prg.prg_name
- prg.prg_kind ce [] prg.prg_implicits
- (Lemmas.mk_hook (fun l r -> Lemmas.call_hook fix_exn prg.prg_hook l r prg.prg_ctx; r))
- in
- Universes.register_universe_binders cst pl;
- cst
+ let ubinders = UState.universe_binders uctx in
+ DeclareDef.declare_definition prg.prg_name
+ prg.prg_kind ce ubinders prg.prg_implicits
+ (Lemmas.mk_hook (fun l r -> Lemmas.call_hook fix_exn prg.prg_hook l r uctx; r))
let rec lam_index n t acc =
match Constr.kind t with
@@ -552,9 +549,9 @@ let declare_mutual_definition l =
mk_proof (mkCoFix (i,fixdecls))) 0 l
in
(* Declare the recursive definitions *)
- let ctx = Evd.evar_context_universe_context first.prg_ctx in
+ let univs = UState.const_univ_entry ~poly first.prg_ctx in
let fix_exn = Hook.get get_fix_exn () in
- let kns = List.map4 (DeclareDef.declare_fix ~opaque (local, poly, kind) [] ctx)
+ let kns = List.map4 (DeclareDef.declare_fix ~opaque (local, poly, kind) Universes.empty_binders univs)
fixnames fixdecls fixtypes fiximps in
(* Declare notations *)
List.iter (Metasyntax.add_notation_interpretation (Global.env())) first.prg_notations;
@@ -636,12 +633,11 @@ let declare_obligation prg obl body ty uctx =
shrink_body body ty else [], body, ty, [||]
in
let body = ((body,Univ.ContextSet.empty),Safe_typing.empty_private_constants) in
- let univs = if poly then Polymorphic_const_entry uctx else Monomorphic_const_entry uctx in
let ce =
{ const_entry_body = Future.from_val ~fix_exn:(fun x -> x) body;
const_entry_secctx = None;
const_entry_type = ty;
- const_entry_universes = univs;
+ const_entry_universes = uctx;
const_entry_opaque = opaque;
const_entry_inline_code = false;
const_entry_feedback = None;
@@ -650,13 +646,15 @@ let declare_obligation prg obl body ty uctx =
let constant = Declare.declare_constant obl.obl_name ~local:true
(DefinitionEntry ce,IsProof Property)
in
- if not opaque then add_hint (Locality.make_section_locality None) prg constant;
- definition_message obl.obl_name;
- true, { obl with obl_body =
- if poly then
- Some (DefinedObl (constant, Univ.UContext.instance uctx))
- else
- Some (TermObl (it_mkLambda_or_LetIn_or_clean (mkApp (mkConst constant, args)) ctx)) }
+ if not opaque then add_hint (Locality.make_section_locality None) prg constant;
+ definition_message obl.obl_name;
+ let body = match uctx with
+ | Polymorphic_const_entry uctx ->
+ Some (DefinedObl (constant, Univ.UContext.instance uctx))
+ | Monomorphic_const_entry _ ->
+ Some (TermObl (it_mkLambda_or_LetIn_or_clean (mkApp (mkConst constant, args)) ctx))
+ in
+ true, { obl with obl_body = body }
let init_prog_info ?(opaque = false) sign n udecl b t ctx deps fixkind
notations obls impls kind reduce hook =
@@ -830,49 +828,63 @@ let obligation_terminator name num guard hook auto pf =
match pf with
| Admitted _ -> apply_terminator term pf
| Proved (opq, id, proof) ->
- if not !shrink_obligations then apply_terminator term pf
- else
- let (_, (entry, uctx, _)) = Pfedit.cook_this_proof proof in
- let env = Global.env () in
- let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in
- let ty = entry.Entries.const_entry_type in
- let (body, cstr), () = Future.force entry.Entries.const_entry_body in
- let sigma = Evd.from_ctx (fst uctx) in
- let sigma = Evd.merge_context_set ~sideff:true Evd.univ_rigid sigma cstr in
- Inductiveops.control_only_guard (Global.env ()) body;
- (** Declare the obligation ourselves and drop the hook *)
- let prg = get_info (ProgMap.find name !from_prg) in
- (** Ensure universes are substituted properly in body and type *)
- let body = EConstr.to_constr sigma (EConstr.of_constr body) in
- let ty = Option.map (fun x -> EConstr.to_constr sigma (EConstr.of_constr x)) ty in
- let ctx = Evd.evar_universe_context sigma in
- let prg = { prg with prg_ctx = ctx } in
- let obls, rem = prg.prg_obligations in
- let obl = obls.(num) in
- let status =
- match obl.obl_status, opq with
- | (_, Evar_kinds.Expand), Vernacexpr.Opaque -> err_not_transp ()
- | (true, _), Vernacexpr.Opaque -> err_not_transp ()
- | (false, _), Vernacexpr.Opaque -> Evar_kinds.Define true
- | (_, Evar_kinds.Define true), Vernacexpr.Transparent -> Evar_kinds.Define false
- | (_, status), Vernacexpr.Transparent -> status
- in
- let obl = { obl with obl_status = false, status } in
- let uctx = Evd.evar_context_universe_context ctx in
- let (_, obl) = declare_obligation prg obl body ty uctx in
- let obls = Array.copy obls in
- let _ = obls.(num) <- obl in
- try
+ let (_, (entry, uctx, _)) = Pfedit.cook_this_proof proof in
+ let env = Global.env () in
+ let entry = Safe_typing.inline_private_constants_in_definition_entry env entry in
+ let ty = entry.Entries.const_entry_type in
+ let (body, cstr), () = Future.force entry.Entries.const_entry_body in
+ let sigma = Evd.from_ctx (fst uctx) in
+ let sigma = Evd.merge_context_set ~sideff:true Evd.univ_rigid sigma cstr in
+ Inductiveops.control_only_guard (Global.env ()) body;
+ (** Declare the obligation ourselves and drop the hook *)
+ let prg = get_info (ProgMap.find name !from_prg) in
+ (** Ensure universes are substituted properly in body and type *)
+ let body = EConstr.to_constr sigma (EConstr.of_constr body) in
+ let ty = Option.map (fun x -> EConstr.to_constr sigma (EConstr.of_constr x)) ty in
+ let ctx = Evd.evar_universe_context sigma in
+ let obls, rem = prg.prg_obligations in
+ let obl = obls.(num) in
+ let status =
+ match obl.obl_status, opq with
+ | (_, Evar_kinds.Expand), Vernacexpr.Opaque -> err_not_transp ()
+ | (true, _), Vernacexpr.Opaque -> err_not_transp ()
+ | (false, _), Vernacexpr.Opaque -> Evar_kinds.Define true
+ | (_, Evar_kinds.Define true), Vernacexpr.Transparent ->
+ Evar_kinds.Define false
+ | (_, status), Vernacexpr.Transparent -> status
+ in
+ let obl = { obl with obl_status = false, status } in
+ let ctx =
+ if pi2 prg.prg_kind then ctx
+ else UState.union prg.prg_ctx ctx
+ in
+ let uctx = UState.const_univ_entry ~poly:(pi2 prg.prg_kind) ctx in
+ let (_, obl) = declare_obligation prg obl body ty uctx in
+ let obls = Array.copy obls in
+ let _ = obls.(num) <- obl in
+ let prg_ctx =
+ if pi2 (prg.prg_kind) then (* Polymorphic *)
+ (** We merge the new universes and constraints of the
+ polymorphic obligation with the existing ones *)
+ UState.union prg.prg_ctx ctx
+ else
+ (** The first obligation declares the univs of the constant,
+ each subsequent obligation declares its own additional
+ universes and constraints if any *)
+ UState.make (Global.universes ())
+ in
+ let prg = { prg with prg_ctx } in
+ try
ignore (update_obls prg obls (pred rem));
if pred rem > 0 then
begin
- let deps = dependencies obls num in
- if not (Int.Set.is_empty deps) then
- ignore (auto (Some name) None deps)
- end
- with e when CErrors.noncritical e ->
- let e = CErrors.push e in
- pperror (CErrors.iprint (ExplainErr.process_vernac_interp_error e))
+ let deps = dependencies obls num in
+ if not (Int.Set.is_empty deps) then
+ ignore (auto (Some name) None deps)
+ end
+ with e when CErrors.noncritical e ->
+ let e = CErrors.push e in
+ pperror (CErrors.iprint (ExplainErr.process_vernac_interp_error e))
let obligation_hook prg obl num auto ctx' _ gr =
let obls, rem = prg.prg_obligations in
@@ -893,7 +905,8 @@ in
let ctx' = Evd.merge_universe_subst evd (Evd.universe_subst (Evd.from_ctx ctx')) in
Univ.Instance.empty, Evd.evar_universe_context ctx'
else
- let (_, uctx) = UState.universe_context ~names:[] ~extensible:true ctx' in
+ (* We get the right order somehow, but surely it could be enforced in a clearer way. *)
+ let uctx = UState.context ctx' in
Univ.UContext.instance uctx, ctx'
in
let obl = { obl with obl_body = Some (DefinedObl (cst, inst)) } in
@@ -969,13 +982,16 @@ and solve_obligation_by_tac prg obls i tac =
let evd = Evd.from_ctx prg.prg_ctx in
let evd = Evd.update_sigma_env evd (Global.env ()) in
let t, ty, ctx =
- solve_by_tac obl.obl_name (evar_of_obligation obl) tac
- (pi2 prg.prg_kind) (Evd.evar_universe_context evd)
- in
- let uctx = Evd.evar_context_universe_context ctx in
- let prg = {prg with prg_ctx = ctx} in
- let def, obl' = declare_obligation prg obl t ty uctx in
- obls.(i) <- obl';
+ solve_by_tac obl.obl_name (evar_of_obligation obl) tac
+ (pi2 prg.prg_kind) (Evd.evar_universe_context evd)
+ in
+ let uctx = if pi2 prg.prg_kind
+ then Polymorphic_const_entry (UState.context ctx)
+ else Monomorphic_const_entry (UState.context_set ctx)
+ in
+ let prg = {prg with prg_ctx = ctx} in
+ let def, obl' = declare_obligation prg obl t ty uctx in
+ obls.(i) <- obl';
if def && not (pi2 prg.prg_kind) then (
(* Declare the term constraints with the first obligation only *)
let evd = Evd.from_env (Global.env ()) in
@@ -1123,9 +1139,9 @@ let admit_prog prg =
match x.obl_body with
| None ->
let x = subst_deps_obl obls x in
- let ctx = Evd.evar_context_universe_context prg.prg_ctx in
+ let ctx = Monomorphic_const_entry (UState.context_set prg.prg_ctx) in
let kn = Declare.declare_constant x.obl_name ~local:true
- (ParameterEntry (None,false,(x.obl_type,ctx),None), IsAssumption Conjectural)
+ (ParameterEntry (None,(x.obl_type,ctx),None), IsAssumption Conjectural)
in
assumption_message x.obl_name;
obls.(i) <- { x with obl_body = Some (DefinedObl (kn, Univ.Instance.empty)) }
diff --git a/vernac/record.ml b/vernac/record.ml
index f09b57048..1d255b08e 100644
--- a/vernac/record.ml
+++ b/vernac/record.ml
@@ -95,7 +95,7 @@ let binder_of_decl = function
let binders_of_decls = List.map binder_of_decl
-let typecheck_params_and_fields finite def id pl t ps nots fs =
+let typecheck_params_and_fields finite def id poly pl t ps nots fs =
let env0 = Global.env () in
let evd, decl = Univdecls.interp_univ_decl_opt env0 pl in
let evars = ref evd in
@@ -167,10 +167,11 @@ let typecheck_params_and_fields finite def id pl t ps nots fs =
let newps = List.map (EConstr.to_rel_decl evars) newps in
let typ = EConstr.to_constr evars typ in
let ce t = Pretyping.check_evars env0 Evd.empty evars (EConstr.of_constr t) in
- let univs = Evd.check_univ_decl evars decl in
+ let univs = Evd.check_univ_decl ~poly evars decl in
+ let ubinders = Evd.universe_binders evars in
List.iter (iter_constr ce) (List.rev newps);
List.iter (iter_constr ce) (List.rev newfs);
- univs, typ, template, imps, newps, impls, newfs
+ ubinders, univs, typ, template, imps, newps, impls, newfs
let degenerate_decl decl =
let id = match RelDecl.get_name decl with
@@ -265,12 +266,14 @@ let warn_non_primitive_record =
strbrk" could not be defined as a primitive record")))
(* We build projections *)
-let declare_projections indsp ?(kind=StructureComponent) binder_name coers fieldimpls fields =
+let declare_projections indsp ctx ?(kind=StructureComponent) binder_name coers ubinders fieldimpls fields =
let env = Global.env() in
let (mib,mip) = Global.lookup_inductive indsp in
let poly = Declareops.inductive_is_polymorphic mib in
- let ctx = Univ.AUContext.repr (Declareops.inductive_polymorphic_context mib) in
- let u = Univ.UContext.instance ctx in
+ let u = match ctx with
+ | Polymorphic_const_entry ctx -> Univ.UContext.instance ctx
+ | Monomorphic_const_entry ctx -> Univ.Instance.empty
+ in
let paramdecls = Inductive.inductive_paramdecls (mib, u) in
let indu = indsp, u in
let r = mkIndU (indsp,u) in
@@ -304,9 +307,11 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
let kn, term =
if is_local_assum decl && primitive then
(** Already defined in the kernel silently *)
- let kn = destConstRef (Nametab.locate (Libnames.qualid_of_ident fid)) in
- Declare.definition_message fid;
- kn, mkProj (Projection.make kn false,mkRel 1)
+ let gr = Nametab.locate (Libnames.qualid_of_ident fid) in
+ let kn = destConstRef gr in
+ Declare.definition_message fid;
+ Universes.register_universe_binders gr ubinders;
+ kn, mkProj (Projection.make kn false,mkRel 1)
else
let ccl = subst_projection fid subst ti in
let body = match decl with
@@ -325,16 +330,12 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
let projtyp =
it_mkProd_or_LetIn (mkProd (x,rp,ccl)) paramdecls in
try
- let univs =
- if poly then Polymorphic_const_entry ctx
- else Monomorphic_const_entry ctx
- in
let entry = {
const_entry_body =
Future.from_val (Safe_typing.mk_pure_proof proj);
const_entry_secctx = None;
const_entry_type = Some projtyp;
- const_entry_universes = univs;
+ const_entry_universes = ctx;
const_entry_opaque = false;
const_entry_inline_code = false;
const_entry_feedback = None } in
@@ -343,8 +344,9 @@ let declare_projections indsp ?(kind=StructureComponent) binder_name coers field
let constr_fip =
let proj_args = (*Rel 1 refers to "x"*) paramargs@[mkRel 1] in
applist (mkConstU (kn,u),proj_args)
- in
- Declare.definition_message fid;
+ in
+ Declare.definition_message fid;
+ Universes.register_universe_binders (ConstRef kn) ubinders;
kn, constr_fip
with Type_errors.TypeError (ctx,te) ->
raise (NotDefinable (BadTypedProj (fid,ctx,te)))
@@ -382,17 +384,20 @@ let structure_signature ctx =
open Typeclasses
-let declare_structure finite univs id idbuild paramimpls params arity template
+let declare_structure finite ubinders univs id idbuild paramimpls params arity template
fieldimpls fields ?(kind=StructureComponent) ?name is_coe coers sign =
let nparams = List.length params and nfields = List.length fields in
let args = Context.Rel.to_extended_list mkRel nfields params in
let ind = applist (mkRel (1+nparams+nfields), args) in
let type_constructor = it_mkProd_or_LetIn ind fields in
- let poly, ctx =
+ let template, ctx =
match univs with
- | Monomorphic_ind_entry ctx -> false, ctx
- | Polymorphic_ind_entry ctx -> true, ctx
- | Cumulative_ind_entry cumi -> true, (Univ.CumulativityInfo.univ_context cumi)
+ | Monomorphic_ind_entry ctx ->
+ template, Monomorphic_const_entry Univ.ContextSet.empty
+ | Polymorphic_ind_entry ctx ->
+ false, Polymorphic_const_entry ctx
+ | Cumulative_ind_entry cumi ->
+ false, Polymorphic_const_entry (Univ.CumulativityInfo.univ_context cumi)
in
let binder_name =
match name with
@@ -402,7 +407,7 @@ let declare_structure finite univs id idbuild paramimpls params arity template
let mie_ind =
{ mind_entry_typename = id;
mind_entry_arity = arity;
- mind_entry_template = not poly && template;
+ mind_entry_template = template;
mind_entry_consnames = [idbuild];
mind_entry_lc = [type_constructor] }
in
@@ -416,27 +421,21 @@ let declare_structure finite univs id idbuild paramimpls params arity template
}
in
let mie =
- if poly then
- begin
+ match ctx with
+ | Polymorphic_const_entry ctx ->
let env = Global.env () in
let env' = Environ.push_context ctx env in
let evd = Evd.from_env env' in
Inductiveops.infer_inductive_subtyping env' evd mie
- end
- else
+ | Monomorphic_const_entry _ ->
mie
in
- let kn = Command.declare_mutual_inductive_with_eliminations mie [] [(paramimpls,[])] in
+ let kn = Command.declare_mutual_inductive_with_eliminations mie ubinders [(paramimpls,[])] in
let rsp = (kn,0) in (* This is ind path of idstruc *)
let cstr = (rsp,1) in
- let fields =
- if poly then
- let subst, _ = Univ.abstract_universes ctx in
- Context.Rel.map (fun c -> Vars.subst_univs_level_constr subst c) fields
- else fields
- in
- let kinds,sp_projs = declare_projections rsp ~kind binder_name coers fieldimpls fields in
+ let kinds,sp_projs = declare_projections rsp ctx ~kind binder_name coers ubinders fieldimpls fields in
let build = ConstructRef cstr in
+ let poly = match ctx with | Polymorphic_const_entry _ -> true | Monomorphic_const_entry _ -> false in
let () = if is_coe then Class.try_add_new_coercion build ~local:false poly in
Recordops.declare_structure(rsp,cstr,List.rev kinds,List.rev sp_projs);
rsp
@@ -450,7 +449,7 @@ let implicits_of_context ctx =
in ExplByPos (i, explname), (true, true, true))
1 (List.rev (Anonymous :: (List.map RelDecl.get_name ctx)))
-let declare_class finite def cum poly ctx id idbuild paramimpls params arity
+let declare_class finite def cum ubinders univs id idbuild paramimpls params arity
template fieldimpls fields ?(kind=StructureComponent) is_coe coers priorities sign =
let fieldimpls =
(* Make the class implicit in the projections, and the params if applicable. *)
@@ -465,27 +464,29 @@ let declare_class finite def cum poly ctx id idbuild paramimpls params arity
let class_body = it_mkLambda_or_LetIn field params in
let class_type = it_mkProd_or_LetIn arity params in
let class_entry =
- Declare.definition_entry ~types:class_type ~poly ~univs:ctx class_body in
+ Declare.definition_entry ~types:class_type ~univs class_body in
let cst = Declare.declare_constant (snd id)
(DefinitionEntry class_entry, IsDefinition Definition)
in
- let cstu = (cst, if poly then Univ.UContext.instance ctx else Univ.Instance.empty) in
+ let cstu = (cst, match univs with
+ | Polymorphic_const_entry univs -> Univ.UContext.instance univs
+ | Monomorphic_const_entry _ -> Univ.Instance.empty)
+ in
let inst_type = appvectc (mkConstU cstu)
(Termops.rel_vect 0 (List.length params)) in
let proj_type =
it_mkProd_or_LetIn (mkProd(Name binder_name, inst_type, lift 1 field)) params in
let proj_body =
it_mkLambda_or_LetIn (mkLambda (Name binder_name, inst_type, mkRel 1)) params in
- let proj_entry =
- Declare.definition_entry ~types:proj_type ~poly
- ~univs:(if poly then ctx else Univ.UContext.empty) proj_body
- in
+ let proj_entry = Declare.definition_entry ~types:proj_type ~univs proj_body in
let proj_cst = Declare.declare_constant proj_name
(DefinitionEntry proj_entry, IsDefinition Definition)
in
let cref = ConstRef cst in
Impargs.declare_manual_implicits false cref [paramimpls];
+ Universes.register_universe_binders cref ubinders;
Impargs.declare_manual_implicits false (ConstRef proj_cst) [List.hd fieldimpls];
+ Universes.register_universe_binders (ConstRef proj_cst) ubinders;
Classes.set_typeclass_transparency (EvalConstRef cst) false false;
let sub = match List.hd coers with
| Some b -> Some ((if b then Backward else Forward), List.hd priorities)
@@ -494,15 +495,16 @@ let declare_class finite def cum poly ctx id idbuild paramimpls params arity
cref, [Name proj_name, sub, Some proj_cst]
| _ ->
let univs =
- if poly then
+ match univs with
+ | Polymorphic_const_entry univs ->
if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context ctx)
+ Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context univs)
else
- Polymorphic_ind_entry ctx
- else
- Monomorphic_ind_entry ctx
+ Polymorphic_ind_entry univs
+ | Monomorphic_const_entry univs ->
+ Monomorphic_ind_entry univs
in
- let ind = declare_structure BiFinite univs (snd id) idbuild paramimpls
+ let ind = declare_structure BiFinite ubinders univs (snd id) idbuild paramimpls
params arity template fieldimpls fields
~kind:Method ~name:binder_name false (List.map (fun _ -> false) fields) sign
in
@@ -523,13 +525,15 @@ let declare_class finite def cum poly ctx id idbuild paramimpls params arity
params, params
in
let univs, ctx_context, fields =
- if poly then
- let usubst, auctx = Univ.abstract_universes ctx in
+ match univs with
+ | Polymorphic_const_entry univs ->
+ let usubst, auctx = Univ.abstract_universes univs in
let map c = Vars.subst_univs_level_constr usubst c in
let fields = Context.Rel.map map fields in
let ctx_context = on_snd (fun d -> Context.Rel.map map d) ctx_context in
auctx, ctx_context, fields
- else Univ.AUContext.empty, ctx_context, fields
+ | Monomorphic_const_entry _ ->
+ Univ.AUContext.empty, ctx_context, fields
in
let k =
{ cl_univs = univs;
@@ -605,14 +609,14 @@ let definition_structure (kind,cum,poly,finite,(is_coe,((loc,idstruc),pl)),ps,cf
if isnot_class && List.exists (fun opt -> not (Option.is_empty opt)) priorities then
user_err Pp.(str "Priorities only allowed for type class substructures");
(* Now, younger decl in params and fields is on top *)
- let (pl, ctx), arity, template, implpars, params, implfs, fields =
+ let pl, univs, arity, template, implpars, params, implfs, fields =
States.with_state_protection (fun () ->
- typecheck_params_and_fields finite (kind = Class true) idstruc pl s ps notations fs) () in
+ typecheck_params_and_fields finite (kind = Class true) idstruc poly pl s ps notations fs) () in
let sign = structure_signature (fields@params) in
- let gr = match kind with
+ match kind with
| Class def ->
let priorities = List.map (fun id -> {hint_priority = id; hint_pattern = None}) priorities in
- let gr = declare_class finite def cum poly ctx (loc,idstruc) idbuild
+ let gr = declare_class finite def cum pl univs (loc,idstruc) idbuild
implpars params arity template implfs fields is_coe coers priorities sign in
gr
| _ ->
@@ -621,18 +625,16 @@ let definition_structure (kind,cum,poly,finite,(is_coe,((loc,idstruc),pl)),ps,cf
(succ (List.length params)) impls) implfs
in
let univs =
- if poly then
+ match univs with
+ | Polymorphic_const_entry univs ->
if cum then
- Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context ctx)
+ Cumulative_ind_entry (Universes.univ_inf_ind_from_universe_context univs)
else
- Polymorphic_ind_entry ctx
- else
- Monomorphic_ind_entry ctx
+ Polymorphic_ind_entry univs
+ | Monomorphic_const_entry univs ->
+ Monomorphic_ind_entry univs
in
- let ind = declare_structure finite univs idstruc
+ let ind = declare_structure finite pl univs idstruc
idbuild implpars params arity template implfs
fields is_coe (List.map (fun coe -> not (Option.is_empty coe)) coers) sign in
IndRef ind
- in
- Universes.register_universe_binders gr pl;
- gr
diff --git a/vernac/record.mli b/vernac/record.mli
index 33c2fba89..9fdd5e1c4 100644
--- a/vernac/record.mli
+++ b/vernac/record.mli
@@ -7,36 +7,12 @@
(************************************************************************)
open Names
-open Constr
open Vernacexpr
open Constrexpr
-open Impargs
open Globnames
val primitive_flag : bool ref
-(** [declare_projections ref name coers params fields] declare projections of
- record [ref] (if allowed) using the given [name] as argument, and put them
- as coercions accordingly to [coers]; it returns the absolute names of projections *)
-
-val declare_projections :
- inductive -> ?kind:Decl_kinds.definition_object_kind -> Id.t ->
- coercion_flag list -> manual_explicitation list list -> Context.Rel.t ->
- (Name.t * bool) list * Constant.t option list
-
-val declare_structure :
- Decl_kinds.recursivity_kind ->
- Entries.inductive_universes ->
- Id.t -> Id.t ->
- manual_explicitation list -> Context.Rel.t -> (** params *) constr -> (** arity *)
- bool (** template arity ? *) ->
- Impargs.manual_explicitation list list -> Context.Rel.t -> (** fields *)
- ?kind:Decl_kinds.definition_object_kind -> ?name:Id.t ->
- bool -> (** coercion? *)
- bool list -> (** field coercions *)
- Evd.evar_map ->
- inductive
-
val definition_structure :
inductive_kind * Decl_kinds.cumulative_inductive_flag * Decl_kinds.polymorphic *
Decl_kinds.recursivity_kind * ident_decl with_coercion * local_binder_expr list *
diff --git a/vernac/vernacentries.ml b/vernac/vernacentries.ml
index bdd351901..2f278ceb1 100644
--- a/vernac/vernacentries.ml
+++ b/vernac/vernacentries.ml
@@ -1555,8 +1555,8 @@ let vernac_check_may_eval ?loc redexp glopt rc =
let sigma' = Evarconv.solve_unif_constraints_with_heuristics env sigma' in
Evarconv.check_problems_are_solved env sigma';
let sigma',nf = Evarutil.nf_evars_and_universes sigma' in
- let pl, uctx = Evd.universe_context ~names:[] ~extensible:true sigma' in
- let env = Environ.push_context uctx (Evarutil.nf_env_evar sigma' env) in
+ let uctx = Evd.universe_context_set sigma' in
+ let env = Environ.push_context_set uctx (Evarutil.nf_env_evar sigma' env) in
let c = nf c in
let j =
if Evarutil.has_undefined_evars sigma' (EConstr.of_constr c) then
@@ -1572,7 +1572,7 @@ let vernac_check_may_eval ?loc redexp glopt rc =
let j = { j with Environ.uj_type = Reductionops.nf_betaiota sigma' j.Environ.uj_type } in
Feedback.msg_notice (print_judgment env sigma' j ++
pr_ne_evar_set (fnl () ++ str "where" ++ fnl ()) (mt ()) sigma' l ++
- Printer.pr_universe_ctx sigma uctx)
+ Printer.pr_universe_ctx_set sigma uctx)
| Some r ->
let (sigma',r_interp) = Hook.get f_interp_redexp env sigma' r in
let redfun env evm c =
@@ -1609,9 +1609,10 @@ exception NoHyp
(* Printing "About" information of a hypothesis of the current goal.
We only print the type and a small statement to this comes from the
goal. Precondition: there must be at least one current goal. *)
-let print_about_hyp_globs ?loc ref_or_by_not glopt =
+let print_about_hyp_globs ?loc ref_or_by_not udecl glopt =
let open Context.Named.Declaration in
try
+ (* FIXME error on non None udecl if we find the hyp. *)
let glnumopt = query_command_selector ?loc glopt in
let gl,id =
match glnumopt,ref_or_by_not with
@@ -1634,7 +1635,7 @@ let print_about_hyp_globs ?loc ref_or_by_not glopt =
with (* fallback to globals *)
| NoHyp | Not_found ->
let sigma, env = Pfedit.get_current_context () in
- print_about env sigma ref_or_by_not
+ print_about env sigma ref_or_by_not udecl
let vernac_print ?loc env sigma = let open Feedback in function
@@ -1651,7 +1652,7 @@ let vernac_print ?loc env sigma = let open Feedback in function
| PrintMLLoadPath -> msg_notice (Mltop.print_ml_path ())
| PrintMLModules -> msg_notice (Mltop.print_ml_modules ())
| PrintDebugGC -> msg_notice (Mltop.print_gc ())
- | PrintName qid -> dump_global qid; msg_notice (print_name env sigma qid)
+ | PrintName (qid,udecl) -> dump_global qid; msg_notice (print_name env sigma qid udecl)
| PrintGraph -> msg_notice (Prettyp.print_graph())
| PrintClasses -> msg_notice (Prettyp.print_classes())
| PrintTypeClasses -> msg_notice (Prettyp.print_typeclasses())
@@ -1681,8 +1682,8 @@ let vernac_print ?loc env sigma = let open Feedback in function
msg_notice (Notation.pr_scope (Constrextern.without_symbols (pr_lglob_constr_env env)) s)
| PrintVisibility s ->
msg_notice (Notation.pr_visibility (Constrextern.without_symbols (pr_lglob_constr_env env)) s)
- | PrintAbout (ref_or_by_not,glnumopt) ->
- msg_notice (print_about_hyp_globs ?loc ref_or_by_not glnumopt)
+ | PrintAbout (ref_or_by_not,udecl,glnumopt) ->
+ msg_notice (print_about_hyp_globs ?loc ref_or_by_not udecl glnumopt)
| PrintImplicit qid ->
dump_global qid; msg_notice (print_impargs qid)
| PrintAssumptions (o,t,r) ->