aboutsummaryrefslogtreecommitdiffhomepage
path: root/pretyping
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/evarconv.ml154
-rw-r--r--pretyping/evarsolve.ml2
-rw-r--r--pretyping/reductionops.ml37
-rw-r--r--pretyping/unification.ml33
4 files changed, 102 insertions, 124 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index fe2e86a48..d37090a65 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -352,10 +352,13 @@ let exact_ise_stack2 env evd f sk1 sk2 =
ise_stack2 evd (List.rev sk1) (List.rev sk2)
else UnifFailure (evd, (* Dummy *) NotSameHead)
-let check_leq_inductives evd cumi u u' =
- let u = EConstr.EInstance.kind evd u in
- let u' = EConstr.EInstance.kind evd u' in
- Evd.add_constraints evd (Reduction.get_cumulativity_constraints CUMUL cumi u u')
+(* Add equality constraints for covariant/invariant positions. For
+ irrelevant positions, unify universes when flexible. *)
+let compare_cumulative_instances evd variances u u' =
+ match Evarutil.compare_cumulative_instances CONV variances u u' evd with
+ | Inl evd ->
+ Success evd
+ | Inr p -> UnifFailure (evd, UnifUnivInconsistency p)
let rec evar_conv_x ts env evd pbty term1 term2 =
let term1 = whd_head_evar evd term1 in
@@ -446,103 +449,56 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
else evar_eqappr_x ts env' evd CONV out2 out1
in
let rigids env evd sk term sk' term' =
- let check_strict () =
- let univs = EConstr.eq_constr_universes evd term term' in
- match univs with
- | Some univs ->
- begin
- let cstrs = Universes.to_constraints (Evd.universes evd) univs in
- try Success (Evd.add_constraints evd cstrs)
- with Univ.UniverseInconsistency p -> UnifFailure (evd, UnifUnivInconsistency p)
- end
- | None ->
- UnifFailure (evd, NotSameHead)
+ let check_strict evd u u' =
+ let cstrs = Univ.enforce_eq_instances u u' Univ.Constraint.empty in
+ try Success (Evd.add_constraints evd cstrs)
+ with Univ.UniverseInconsistency p -> UnifFailure (evd, UnifUnivInconsistency p)
in
- let first_try_strict_check cond u u' try_subtyping_constraints =
- if cond then
- let univs = EConstr.eq_constr_universes evd term term' in
- match univs with
- | Some univs ->
- begin
- let cstrs = Universes.to_constraints (Evd.universes evd) univs in
- try Success (Evd.add_constraints evd cstrs)
- with Univ.UniverseInconsistency p -> try_subtyping_constraints ()
- end
- | None ->
- UnifFailure (evd, NotSameHead)
- else
- UnifFailure (evd, NotSameHead)
- in
- let compare_heads evd =
+ let compare_heads evd =
match EConstr.kind evd term, EConstr.kind evd term' with
- | Const (c, u), Const (c', u') ->
- check_strict ()
- | Ind (ind, u), Ind (ind', u') ->
- let check_subtyping_constraints () =
- let nparamsaplied = Stack.args_size sk in
- let nparamsaplied' = Stack.args_size sk' in
- begin
- let mind = Environ.lookup_mind (fst ind) env in
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- UnifFailure (evd, NotSameHead)
- | Declarations.Cumulative_ind cumi ->
- begin
- let num_param_arity =
- mind.Declarations.mind_nparams +
- mind.Declarations.mind_packets.(snd ind).Declarations.mind_nrealargs
- in
- if not (num_param_arity = nparamsaplied
- && num_param_arity = nparamsaplied') then
- UnifFailure (evd, NotSameHead)
- else
- begin
- let evd' = check_leq_inductives evd cumi u u' in
- Success (check_leq_inductives evd' cumi u' u)
- end
- end
+ | Const (c, u), Const (c', u') when Constant.equal c c' ->
+ let u = EInstance.kind evd u and u' = EInstance.kind evd u' in
+ check_strict evd u u'
+ | Const _, Const _ -> UnifFailure (evd, NotSameHead)
+ | Ind ((mi,i) as ind , u), Ind (ind', u') when Names.eq_ind ind ind' ->
+ if EInstance.is_empty u && EInstance.is_empty u' then Success evd
+ else
+ let u = EInstance.kind evd u and u' = EInstance.kind evd u' in
+ let mind = Environ.lookup_mind mi env in
+ let open Declarations in
+ begin match mind.mind_universes with
+ | Monomorphic_ind _ -> assert false
+ | Polymorphic_ind _ -> check_strict evd u u'
+ | Cumulative_ind cumi ->
+ let nparamsaplied = Stack.args_size sk in
+ let nparamsaplied' = Stack.args_size sk' in
+ let needed = Reduction.inductive_cumulativity_arguments (mind,i) in
+ if not (Int.equal nparamsaplied needed && Int.equal nparamsaplied' needed)
+ then check_strict evd u u'
+ else
+ compare_cumulative_instances evd (Univ.ACumulativityInfo.variance cumi) u u'
end
- in
- first_try_strict_check (Names.eq_ind ind ind') u u' check_subtyping_constraints
- | Construct (cons, u), Construct (cons', u') ->
- let check_subtyping_constraints () =
- let ind, ind' = fst cons, fst cons' in
- let j, j' = snd cons, snd cons' in
- let nparamsaplied = Stack.args_size sk in
- let nparamsaplied' = Stack.args_size sk' in
- let mind = Environ.lookup_mind (fst ind) env in
- match mind.Declarations.mind_universes with
- | Declarations.Monomorphic_ind _ | Declarations.Polymorphic_ind _ ->
- UnifFailure (evd, NotSameHead)
- | Declarations.Cumulative_ind cumi ->
- begin
- let num_cnstr_args =
- let nparamsctxt =
- mind.Declarations.mind_nparams +
- mind.Declarations.mind_packets.(snd ind).Declarations.mind_nrealargs
- in
- nparamsctxt +
- mind.Declarations.mind_packets.(snd ind).
- Declarations.mind_consnrealargs.(j - 1)
- in
- if not (num_cnstr_args = nparamsaplied
- && num_cnstr_args = nparamsaplied') then
- UnifFailure (evd, NotSameHead)
+ | Ind _, Ind _ -> UnifFailure (evd, NotSameHead)
+ | Construct (((mi,ind),ctor as cons), u), Construct (cons', u')
+ when Names.eq_constructor cons cons' ->
+ if EInstance.is_empty u && EInstance.is_empty u' then Success evd
+ else
+ let u = EInstance.kind evd u and u' = EInstance.kind evd u' in
+ let mind = Environ.lookup_mind mi env in
+ let open Declarations in
+ begin match mind.mind_universes with
+ | Monomorphic_ind _ -> assert false
+ | Polymorphic_ind _ -> check_strict evd u u'
+ | Cumulative_ind cumi ->
+ let nparamsaplied = Stack.args_size sk in
+ let nparamsaplied' = Stack.args_size sk' in
+ let needed = Reduction.constructor_cumulativity_arguments (mind,ind,ctor) in
+ if not (Int.equal nparamsaplied needed && Int.equal nparamsaplied' needed)
+ then check_strict evd u u'
else
- begin
- (** Both constructors should be liftable to the same supertype
- at which we compare them, but we don't have access to that type in
- untyped unification. We hence try to enforce that one is lower
- than the other, also unifying more universes in the process.
- If this fails we just leave the universes as is, as in conversion. *)
- try Success (check_leq_inductives evd cumi u u')
- with Univ.UniverseInconsistency _ ->
- try Success (check_leq_inductives evd cumi u' u)
- with Univ.UniverseInconsistency e -> Success evd
- end
- end
- in
- first_try_strict_check (Names.eq_constructor cons cons') u u' check_subtyping_constraints
+ Success (compare_constructor_instances evd u u')
+ end
+ | Construct _, Construct _ -> UnifFailure (evd, NotSameHead)
| _, _ -> anomaly (Pp.str "")
in
ise_and evd [(fun i ->
@@ -789,7 +745,7 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
allow this identification (first-order unification of universes). Otherwise
fallback to unfolding.
*)
- let univs = EConstr.eq_constr_universes evd term1 term2 in
+ let univs = EConstr.eq_constr_universes env evd term1 term2 in
match univs with
| Some univs ->
ise_and i [(fun i ->
@@ -1096,7 +1052,7 @@ let apply_on_subterm env evdref f c t =
(* By using eq_constr, we make an approximation, for instance, we *)
(* could also be interested in finding a term u convertible to t *)
(* such that c occurs in u *)
- let eq_constr c1 c2 = match EConstr.eq_constr_universes !evdref c1 c2 with
+ let eq_constr c1 c2 = match EConstr.eq_constr_universes env !evdref c1 c2 with
| None -> false
| Some cstr ->
try ignore (Evd.add_universe_constraints !evdref cstr); true
diff --git a/pretyping/evarsolve.ml b/pretyping/evarsolve.ml
index c9030be2d..96d80741a 100644
--- a/pretyping/evarsolve.ml
+++ b/pretyping/evarsolve.ml
@@ -1337,7 +1337,7 @@ type conv_fun_bool =
let solve_refl ?(can_drop=false) conv_algo env evd pbty evk argsv1 argsv2 =
let evdref = ref evd in
- let eq_constr c1 c2 = match EConstr.eq_constr_universes !evdref c1 c2 with
+ let eq_constr c1 c2 = match EConstr.eq_constr_universes env !evdref c1 c2 with
| None -> false
| Some cstr ->
try ignore (Evd.add_universe_constraints !evdref cstr); true
diff --git a/pretyping/reductionops.ml b/pretyping/reductionops.ml
index 0e66ff0b6..9e3e68f05 100644
--- a/pretyping/reductionops.ml
+++ b/pretyping/reductionops.ml
@@ -29,6 +29,16 @@ exception Elimconst
their parameters in its stack.
*)
+let _ = Goptions.declare_bool_option {
+ Goptions.optdepr = false;
+ Goptions.optname =
+ "Generate weak constraints between Irrelevant universes";
+ Goptions.optkey = ["Cumulativity";"Weak";"Constraints"];
+ Goptions.optread = (fun () -> not !UState.drop_weak_constraints);
+ Goptions.optwrite = (fun a -> UState.drop_weak_constraints:=not a);
+}
+
+
(** Support for reduction effects *)
open Mod_subst
@@ -691,18 +701,25 @@ let reducible_mind_case sigma c = match EConstr.kind sigma c with
let magicaly_constant_of_fixbody env sigma reference bd = function
| Name.Anonymous -> bd
| Name.Name id ->
+ let open Universes in
try
let (cst_mod,cst_sect,_) = Constant.repr3 reference in
let cst = Constant.make3 cst_mod cst_sect (Label.of_id id) in
- let (cst, u), ctx = Universes.fresh_constant_instance env cst in
+ let (cst, u), ctx = fresh_constant_instance env cst in
match constant_opt_value_in env (cst,u) with
| None -> bd
| Some t ->
- let csts = EConstr.eq_constr_universes sigma (EConstr.of_constr t) bd in
+ let csts = EConstr.eq_constr_universes env sigma (EConstr.of_constr t) bd in
begin match csts with
| Some csts ->
- let subst = Universes.Constraints.fold (fun (l,d,r) acc ->
- Univ.LMap.add (Option.get (Universe.level l)) (Option.get (Universe.level r)) acc)
+ let subst = Constraints.fold (fun cst acc ->
+ let l, r = match cst with
+ | ULub (u, v) | UWeak (u, v) -> u, v
+ | UEq (u, v) | ULe (u, v) ->
+ let get u = Option.get (Universe.level u) in
+ get u, get v
+ in
+ Univ.LMap.add l r acc)
csts Univ.LMap.empty
in
let inst = Instance.subst_fn (fun u -> Univ.LMap.find u subst) u in
@@ -1315,10 +1332,10 @@ let sigma_compare_instances ~flex i0 i1 sigma =
| Univ.UniverseInconsistency _ ->
raise Reduction.NotConvertible
-let sigma_check_inductive_instances csts sigma =
- try Evd.add_constraints sigma csts
- with Evd.UniversesDiffer
- | Univ.UniverseInconsistency _ ->
+let sigma_check_inductive_instances cv_pb variance u1 u2 sigma =
+ match Evarutil.compare_cumulative_instances cv_pb variance u1 u2 sigma with
+ | Inl sigma -> sigma
+ | Inr _ ->
raise Reduction.NotConvertible
let sigma_univ_state =
@@ -1334,9 +1351,9 @@ let infer_conv_gen conv_fun ?(catch_incon=true) ?(pb=Reduction.CUMUL)
let b, sigma =
let ans =
if pb == Reduction.CUMUL then
- EConstr.leq_constr_universes sigma x y
+ EConstr.leq_constr_universes env sigma x y
else
- EConstr.eq_constr_universes sigma x y
+ EConstr.eq_constr_universes env sigma x y
in
let ans = match ans with
| None -> None
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index f4269a2c5..f2f922fd5 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -561,17 +561,22 @@ let is_rigid_head sigma flags t =
| Lambda (_, _, _) | LetIn (_, _, _, _) | App (_, _) | Case (_, _, _, _)
| Proj (_, _) -> false (* Why aren't Prod, Sort rigid heads ? *)
-let force_eqs c =
- Universes.Constraints.fold
- (fun ((l,d,r) as c) acc ->
- let c' = if d == Universes.ULub then (l,Universes.UEq,r) else c in
- Universes.Constraints.add c' acc)
- c Universes.Constraints.empty
-
-let constr_cmp pb sigma flags t u =
+let force_eqs c =
+ let open Universes in
+ Constraints.fold
+ (fun c acc ->
+ let c' = match c with
+ (* Should we be forcing weak constraints? *)
+ | ULub (l, r) | UWeak (l, r) -> UEq (Univ.Universe.make l,Univ.Universe.make r)
+ | ULe _ | UEq _ -> c
+ in
+ Constraints.add c' acc)
+ c Constraints.empty
+
+let constr_cmp pb env sigma flags t u =
let cstrs =
- if pb == Reduction.CONV then EConstr.eq_constr_universes sigma t u
- else EConstr.leq_constr_universes sigma t u
+ if pb == Reduction.CONV then EConstr.eq_constr_universes env sigma t u
+ else EConstr.leq_constr_universes env sigma t u
in
match cstrs with
| Some cstrs ->
@@ -579,7 +584,7 @@ let constr_cmp pb sigma flags t u =
with Univ.UniverseInconsistency _ -> sigma, false
| Evd.UniversesDiffer ->
if is_rigid_head sigma flags t then
- try Evd.add_universe_constraints sigma (force_eqs cstrs), true
+ try Evd.add_universe_constraints sigma (force_eqs cstrs), true
with Univ.UniverseInconsistency _ -> sigma, false
else sigma, false
end
@@ -736,7 +741,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
| Evar (evk,_ as ev), Evar (evk',_)
when not (Evar.Set.mem evk flags.frozen_evars)
&& Evar.equal evk evk' ->
- let sigma',b = constr_cmp cv_pb sigma flags cM cN in
+ let sigma',b = constr_cmp cv_pb env sigma flags cM cN in
if b then
sigma',metasubst,evarsubst
else
@@ -918,7 +923,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
and unify_not_same_head curenvnb pb opt (sigma, metas, evars as substn : subst0) cM cN =
try canonical_projections curenvnb pb opt cM cN substn
with ex when precatchable_exception ex ->
- let sigma', b = constr_cmp cv_pb sigma flags cM cN in
+ let sigma', b = constr_cmp cv_pb env sigma flags cM cN in
if b then (sigma', metas, evars)
else
try reduce curenvnb pb opt substn cM cN
@@ -1087,7 +1092,7 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst : subst0) conv_at_top e
else
let sigma, b = match flags.modulo_conv_on_closed_terms with
| Some convflags -> infer_conv ~pb:cv_pb ~ts:convflags env sigma m n
- | _ -> constr_cmp cv_pb sigma flags m n in
+ | _ -> constr_cmp cv_pb env sigma flags m n in
if b then Some sigma
else if (match flags.modulo_conv_on_closed_terms, flags.modulo_delta with
| Some (cv_id, cv_k), (dl_id, dl_k) ->