diff options
author | Gaëtan Gilbert <gaetan.gilbert@skyskimmer.net> | 2018-02-20 00:27:40 +0100 |
---|---|---|
committer | Gaëtan Gilbert <gaetan.gilbert@skyskimmer.net> | 2018-03-09 16:29:06 +0100 |
commit | db0918bfa5089f9ab44374504cbd0ddc758ea1e5 (patch) | |
tree | 5b68a2bd48fc961987a193f4361c46f7b9940b33 /engine/evarutil.ml | |
parent | 17a0dccfe91d6f837ce285e62b8d843720f8c1a1 (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.ml | 28 |
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 |