aboutsummaryrefslogtreecommitdiffhomepage
path: root/engine/evarutil.ml
diff options
context:
space:
mode:
authorGravatar Gaëtan Gilbert <gaetan.gilbert@skyskimmer.net>2018-02-20 00:27:40 +0100
committerGravatar Gaëtan Gilbert <gaetan.gilbert@skyskimmer.net>2018-03-09 16:29:06 +0100
commitdb0918bfa5089f9ab44374504cbd0ddc758ea1e5 (patch)
tree5b68a2bd48fc961987a193f4361c46f7b9940b33 /engine/evarutil.ml
parent17a0dccfe91d6f837ce285e62b8d843720f8c1a1 (diff)
Cumulativity: improve treatment of irrelevant universes.
In Reductionops.infer_conv we did not have enough information to properly try to unify irrelevant universes. This requires changing the Reduction.universe_compare type a bit.
Diffstat (limited to 'engine/evarutil.ml')
-rw-r--r--engine/evarutil.ml28
1 files changed, 28 insertions, 0 deletions
diff --git a/engine/evarutil.ml b/engine/evarutil.ml
index 6b3ce048f..8db603715 100644
--- a/engine/evarutil.ml
+++ b/engine/evarutil.ml
@@ -813,6 +813,34 @@ let subterm_source evk (loc,k) =
| _ -> evk in
(loc,Evar_kinds.SubEvar evk)
+let try_soft evd u u' =
+ let open Universes in
+ let make = Univ.Universe.make in
+ try Evd.add_universe_constraints evd (Constraints.singleton (make u,ULub,make u'))
+ with UState.UniversesDiffer | Univ.UniverseInconsistency _ -> evd
+
+(* Add equality constraints for covariant/invariant positions. For
+ irrelevant positions, unify universes when flexible. *)
+let compare_cumulative_instances cv_pb variances u u' sigma =
+ let cstrs = Univ.Constraint.empty in
+ let soft = [] in
+ let cstrs, soft = Array.fold_left3 (fun (cstrs, soft) v u u' ->
+ let open Univ.Variance in
+ match v with
+ | Irrelevant -> cstrs, (u,u')::soft
+ | Covariant when cv_pb == Reduction.CUMUL ->
+ Univ.Constraint.add (u,Univ.Le,u') cstrs, soft
+ | Covariant | Invariant -> Univ.Constraint.add (u,Univ.Eq,u') cstrs, soft)
+ (cstrs,soft) variances (Univ.Instance.to_array u) (Univ.Instance.to_array u')
+ in
+ match Evd.add_constraints sigma cstrs with
+ | sigma ->
+ Inl (List.fold_left (fun sigma (u,u') -> try_soft sigma u u') sigma soft)
+ | exception Univ.UniverseInconsistency p -> Inr p
+
+let compare_constructor_instances evd u u' =
+ Array.fold_left2 try_soft
+ evd (Univ.Instance.to_array u) (Univ.Instance.to_array u')
(** [eq_constr_univs_test sigma1 sigma2 t u] tests equality of [t] and
[u] up to existential variable instantiation and equalisable