aboutsummaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
Diffstat (limited to 'library')
-rw-r--r--library/declare.ml25
-rw-r--r--library/global.ml8
-rw-r--r--library/global.mli8
-rw-r--r--library/lib.ml1
-rw-r--r--library/universes.ml68
5 files changed, 77 insertions, 33 deletions
diff --git a/library/declare.ml b/library/declare.ml
index 8438380c9c..16803b3bfa 100644
--- a/library/declare.ml
+++ b/library/declare.ml
@@ -42,7 +42,7 @@ type variable_declaration = DirPath.t * section_variable_entry * logical_kind
let cache_variable ((sp,_),o) =
match o with
- | Inl ctx -> Global.push_context_set ctx
+ | Inl ctx -> Global.push_context_set false ctx
| Inr (id,(p,d,mk)) ->
(* Constr raisonne sur les noms courts *)
if variable_exists id then
@@ -50,13 +50,13 @@ let cache_variable ((sp,_),o) =
let impl,opaq,poly,ctx = match d with (* Fails if not well-typed *)
| SectionLocalAssum ((ty,ctx),poly,impl) ->
- let () = Global.push_named_assum ((id,ty),ctx) in
+ let () = Global.push_named_assum ((id,ty,poly),ctx) in
let impl = if impl then Implicit else Explicit in
impl, true, poly, ctx
| SectionLocalDef (de) ->
- let () = Global.push_named_def (id,de) in
- Explicit, de.const_entry_opaque, de.const_entry_polymorphic,
- (Univ.ContextSet.of_context de.const_entry_universes) in
+ let univs = Global.push_named_def (id,de) in
+ Explicit, de.const_entry_opaque,
+ de.const_entry_polymorphic, univs in
Nametab.push (Nametab.Until 1) (restrict_path 0 sp) (VarRef id);
add_section_variable id impl poly ctx;
Dischargedhypsmap.set_discharged_hyps sp [];
@@ -116,8 +116,9 @@ let open_constant i ((sp,kn), obj) =
match (Global.lookup_constant con).const_body with
| (Def _ | Undef _) -> ()
| OpaqueDef lc ->
- match Opaqueproof.get_constraints (Global.opaque_tables ())lc with
- | Some f when Future.is_val f -> Global.push_context_set (Future.force f)
+ match Opaqueproof.get_constraints (Global.opaque_tables ()) lc with
+ | Some f when Future.is_val f ->
+ Global.push_context_set false (Future.force f)
| _ -> ()
let exists_name id =
@@ -455,12 +456,14 @@ let input_universes : universe_names -> Libobject.obj =
let do_universe l =
let glob = Universes.global_universe_names () in
- let glob' =
- List.fold_left (fun (idl,lid) (l, id) ->
+ let glob', ctx =
+ List.fold_left (fun ((idl,lid),ctx) (l, id) ->
let lev = Universes.new_univ_level (Global.current_dirpath ()) in
- (Idmap.add id lev idl, Univ.LMap.add lev id lid))
- glob l
+ ((Idmap.add id lev idl, Univ.LMap.add lev id lid),
+ Univ.ContextSet.add_universe lev ctx))
+ (glob, Univ.ContextSet.empty) l
in
+ Global.push_context_set false ctx;
Lib.add_anonymous_leaf (input_universes glob')
diff --git a/library/global.ml b/library/global.ml
index 0419799b67..6002382c1f 100644
--- a/library/global.ml
+++ b/library/global.ml
@@ -78,10 +78,10 @@ let globalize_with_summary fs f =
let i2l = Label.of_id
let push_named_assum a = globalize0 (Safe_typing.push_named_assum a)
-let push_named_def d = globalize0 (Safe_typing.push_named_def d)
+let push_named_def d = globalize (Safe_typing.push_named_def d)
let add_constraints c = globalize0 (Safe_typing.add_constraints c)
-let push_context_set c = globalize0 (Safe_typing.push_context_set c)
-let push_context c = globalize0 (Safe_typing.push_context c)
+let push_context_set b c = globalize0 (Safe_typing.push_context_set b c)
+let push_context b c = globalize0 (Safe_typing.push_context b c)
let set_engagement c = globalize0 (Safe_typing.set_engagement c)
let add_constant dir id d = globalize (Safe_typing.add_constant dir (i2l id) d)
@@ -249,7 +249,7 @@ let current_dirpath () =
let with_global f =
let (a, ctx) = f (env ()) (current_dirpath ()) in
- push_context_set ctx; a
+ push_context_set false ctx; a
(* spiwack: register/unregister functions for retroknowledge *)
let register field value by_clause =
diff --git a/library/global.mli b/library/global.mli
index 363bb57890..ac231f7fd8 100644
--- a/library/global.mli
+++ b/library/global.mli
@@ -30,8 +30,8 @@ val set_engagement : Declarations.engagement -> unit
(** Variables, Local definitions, constants, inductive types *)
-val push_named_assum : (Id.t * Constr.types) Univ.in_universe_context_set -> unit
-val push_named_def : (Id.t * Entries.definition_entry) -> unit
+val push_named_assum : (Id.t * Constr.types * bool) Univ.in_universe_context_set -> unit
+val push_named_def : (Id.t * Entries.definition_entry) -> Univ.universe_context_set
val add_constant :
DirPath.t -> Id.t -> Safe_typing.global_declaration -> constant
@@ -41,8 +41,8 @@ val add_mind :
(** Extra universe constraints *)
val add_constraints : Univ.constraints -> unit
-val push_context : Univ.universe_context -> unit
-val push_context_set : Univ.universe_context_set -> unit
+val push_context : bool -> Univ.universe_context -> unit
+val push_context_set : bool -> Univ.universe_context_set -> unit
(** Non-interactive modules and module types *)
diff --git a/library/lib.ml b/library/lib.ml
index 81db547efd..f4f52db53b 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -420,6 +420,7 @@ let extract_hyps (secs,ohyps) =
in aux (secs,ohyps)
let instance_from_variable_context sign =
+
let rec inst_rec = function
| (id,b,None,_) :: sign -> id :: inst_rec sign
| _ :: sign -> inst_rec sign
diff --git a/library/universes.ml b/library/universes.ml
index 1c8a5ad77d..bc42cc044c 100644
--- a/library/universes.ml
+++ b/library/universes.ml
@@ -182,10 +182,13 @@ let leq_constr_univs_infer univs m n =
if Sorts.equal s1 s2 then true
else
let u1 = Sorts.univ_of_sort s1 and u2 = Sorts.univ_of_sort s2 in
- if Univ.check_leq univs u1 u2 then true
- else
- (cstrs := Constraints.add (u1, ULe, u2) !cstrs;
- true)
+ if Univ.check_leq univs u1 u2 then
+ ((if Univ.is_small_univ u1 then
+ cstrs := Constraints.add (u1, ULe, u2) !cstrs);
+ true)
+ else
+ (cstrs := Constraints.add (u1, ULe, u2) !cstrs;
+ true)
in
let rec eq_constr' m n =
m == n || Constr.compare_head_gen eq_universes eq_sorts eq_constr' m n
@@ -820,22 +823,59 @@ let minimize_univ_variables ctx us algs left right cstrs =
if v == None then fst (aux acc u)
else LSet.remove u ctx', us, LSet.remove u algs, seen, cstrs)
us (ctx, us, algs, lbounds, cstrs)
-
+
let normalize_context_set ctx us algs =
let (ctx, csts) = ContextSet.levels ctx, ContextSet.constraints ctx in
let uf = UF.create () in
+ (** Keep the Prop/Set <= i constraints separate for minimization *)
+ let smallles, csts =
+ Constraint.fold (fun (l,d,r as cstr) (smallles, noneqs) ->
+ if d == Le then
+ if Univ.Level.is_small l then
+ (Constraint.add cstr smallles, noneqs)
+ else if Level.is_small r then
+ if Level.is_prop r then
+ raise (Univ.UniverseInconsistency
+ (Le,Universe.make l,Universe.make r,None))
+ else (smallles, Constraint.add (l,Eq,r) noneqs)
+ else (smallles, Constraint.add cstr noneqs)
+ else (smallles, Constraint.add cstr noneqs))
+ csts (Constraint.empty, Constraint.empty)
+ in
let csts =
(* We first put constraints in a normal-form: all self-loops are collapsed
to equalities. *)
- let g = Univ.merge_constraints csts Univ.empty_universes in
+ let g = Univ.LSet.fold (fun v g -> Univ.add_universe v false g)
+ ctx Univ.empty_universes
+ in
+ let g =
+ Univ.Constraint.fold
+ (fun (l, d, r) g ->
+ let g =
+ if not (Level.is_small l || LSet.mem l ctx) then
+ try Univ.add_universe l false g
+ with Univ.AlreadyDeclared -> g
+ else g
+ in
+ let g =
+ if not (Level.is_small r || LSet.mem r ctx) then
+ try Univ.add_universe r false g
+ with Univ.AlreadyDeclared -> g
+ else g
+ in g) csts g
+ in
+ let g = Univ.Constraint.fold Univ.enforce_constraint csts g in
Univ.constraints_of_universes g
in
let noneqs =
- Constraint.fold (fun (l,d,r) noneqs ->
- if d == Eq then (UF.union l r uf; noneqs)
- else Constraint.add (l,d,r) noneqs)
- csts Constraint.empty
+ Constraint.fold (fun (l,d,r as cstr) noneqs ->
+ if d == Eq then (UF.union l r uf; noneqs)
+ else (* We ignore the trivial Prop/Set <= i constraints. *)
+ if d == Le && Univ.Level.is_small l then noneqs
+ else Constraint.add cstr noneqs)
+ csts Constraint.empty
in
+ let noneqs = Constraint.union noneqs smallles in
let partition = UF.partition uf in
let flex x = LMap.mem x us in
let ctx, subst, eqs = List.fold_left (fun (ctx, subst, cstrs) s ->
@@ -941,12 +981,12 @@ let simplify_universe_context (univs,csts) =
let csts' = subst_univs_level_constraints subst csts' in
(univs', csts'), subst
-let is_small_leq (l,d,r) =
- Level.is_small l && d == Univ.Le
+let is_trivial_leq (l,d,r) =
+ Univ.Level.is_prop l && (d == Univ.Le || (d == Univ.Lt && Univ.Level.is_set r))
(* Prop < i <-> Set+1 <= i <-> Set < i *)
let translate_cstr (l,d,r as cstr) =
- if Level.equal Level.prop l && d == Univ.Lt then
+ if Level.equal Level.prop l && d == Univ.Lt && not (Level.equal Level.set r) then
(Level.set, d, r)
else cstr
@@ -954,7 +994,7 @@ let refresh_constraints univs (ctx, cstrs) =
let cstrs', univs' =
Univ.Constraint.fold (fun c (cstrs', univs as acc) ->
let c = translate_cstr c in
- if Univ.check_constraint univs c && not (is_small_leq c) then acc
+ if is_trivial_leq c then acc
else (Univ.Constraint.add c cstrs', Univ.enforce_constraint c univs))
cstrs (Univ.Constraint.empty, univs)
in ((ctx, cstrs'), univs')