aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pretyping/evarconv.ml28
-rw-r--r--pretyping/evarutil.ml28
-rw-r--r--pretyping/evarutil.mli2
-rw-r--r--pretyping/unification.ml2
-rw-r--r--test-suite/csdp.cachebin795146 -> 748 bytes
-rw-r--r--test-suite/failure/evar1.v3
6 files changed, 50 insertions, 13 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index bc4222175..f197f7a9a 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -66,6 +66,10 @@ let apprec_nohdbeta env evd c =
| (Case _ | Fix _) -> applist (evar_apprec env evd [] c)
| _ -> c
+let position_problem l2r = function
+ | CONV -> None
+ | CUMUL -> Some l2r
+
(* [check_conv_record (t1,l1) (t2,l2)] tries to decompose the problem
(t1 l1) = (t2 l2) into a problem
@@ -177,9 +181,11 @@ let rec evar_conv_x env evd pbty term1 term2 =
let term1 = apprec_nohdbeta env evd term1 in
let term2 = apprec_nohdbeta env evd term2 in
if is_undefined_evar evd term1 then
- solve_simple_eqn evar_conv_x env evd (pbty,destEvar term1,term2)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem true pbty,destEvar term1,term2)
else if is_undefined_evar evd term2 then
- solve_simple_eqn evar_conv_x env evd (pbty,destEvar term2,term1)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem false pbty,destEvar term2,term1)
else
evar_eqappr_x env evd pbty
(decompose_app term1) (decompose_app term2)
@@ -193,14 +199,14 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
let (deb1,rest1) = list_chop (List.length l1-List.length l2) l1 in
ise_and i
[(fun i -> solve_simple_eqn evar_conv_x env i
- (pbty,ev2,applist(term1,deb1)));
+ (position_problem false pbty,ev2,applist(term1,deb1)));
(fun i -> ise_list2 i
(fun i -> evar_conv_x env i CONV) rest1 l2)]
else
let (deb2,rest2) = list_chop (List.length l2-List.length l1) l2 in
ise_and i
[(fun i -> solve_simple_eqn evar_conv_x env i
- (pbty,ev1,applist(term2,deb2)));
+ (position_problem true pbty,ev1,applist(term2,deb2)));
(fun i -> ise_list2 i
(fun i -> evar_conv_x env i CONV) l1 rest2)]
and f2 i =
@@ -224,7 +230,8 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
(* Preserve generality (except that CCI has no eta-conversion) *)
let t2 = nf_evar evd (applist appr2) in
let t2 = solve_pattern_eqn env l1 t2 in
- solve_simple_eqn evar_conv_x env evd (pbty,ev1,t2)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem true pbty,ev1,t2)
else if
List.length l1 <= List.length l2
then
@@ -256,7 +263,8 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
(* Preserve generality (except that CCI has no eta-conversion) *)
let t1 = nf_evar evd (applist appr1) in
let t1 = solve_pattern_eqn env l2 t1 in
- solve_simple_eqn evar_conv_x env evd (pbty,ev2,t1)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem false pbty,ev2,t1)
else if
List.length l2 <= List.length l1
then
@@ -324,7 +332,8 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
(* Preserve generality (except that CCI has no eta-conversion) *)
let t2 = nf_evar evd (applist appr2) in
let t2 = solve_pattern_eqn env l1 t2 in
- solve_simple_eqn evar_conv_x env evd (pbty,ev1,t2)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem true pbty,ev1,t2)
else
(* Postpone the use of an heuristic *)
add_conv_pb (pbty,env,applist appr1,applist appr2) evd,
@@ -339,7 +348,8 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
(* Preserve generality (except that CCI has no eta-conversion) *)
let t1 = nf_evar evd (applist appr1) in
let t1 = solve_pattern_eqn env l2 t1 in
- solve_simple_eqn evar_conv_x env evd (pbty,ev2,t1)
+ solve_simple_eqn evar_conv_x env evd
+ (position_problem false pbty,ev2,t1)
else
(* Postpone the use of an heuristic *)
add_conv_pb (pbty,env,applist appr1,applist appr2) evd,
@@ -505,7 +515,7 @@ let first_order_unification env evd (ev1,l1) (term2,l2) =
if is_defined_evar i ev1 then
evar_conv_x env i CONV t2 (mkEvar ev1)
else
- solve_simple_eqn ~choose:true evar_conv_x env i (CONV,ev1,t2))]
+ solve_simple_eqn ~choose:true evar_conv_x env i (None,ev1,t2))]
let choose_less_dependent_instance evk evd term args =
let evi = Evd.find evd evk in
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index bc23fcec2..cd2dc5d20 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -1131,6 +1131,22 @@ let solve_refl conv_algo env evd evk argsv1 argsv2 =
let pb = (Reduction.CONV,env,mkEvar(evk,argsv1),mkEvar(evk,argsv2)) in
Evd.add_conv_pb pb evd
+(* Util *)
+
+let check_instance_type conv_algo env evd ev1 t2 =
+ let typ2 = Retyping.get_type_of env evd (refresh_universes t2) in
+ let typ1 = existential_type evd ev1 in
+ match kind_of_term (whd_evar evd typ2) with
+ | Evar _ ->
+ (* No firm constraints: don't want to commit to an equal
+ solution while only subtyping is requested *)
+ evd
+ | _ ->
+ let evd,b = conv_algo env evd Reduction.CUMUL typ2 typ1 in
+ if b then evd else
+ user_err_loc (fst (evar_source (fst ev1) evd),"",
+ str "Unable to find a well-typed instantiation")
+
(* Tries to solve problem t1 = t2.
* Precondition: t1 is an uninstantiated evar
* Returns an optional list of evars that were instantiated, or None
@@ -1145,10 +1161,18 @@ let solve_simple_eqn conv_algo ?(choose=false) env evd (pbty,(evk1,args1 as ev1)
if evk1 = evk2 then
solve_refl conv_algo env evd evk1 args1 args2
else
- if pbty = Reduction.CONV
+ if pbty = None
then solve_evar_evar evar_define env evd ev1 ev2
- else add_conv_pb (pbty,env,mkEvar ev1,t2) evd
+ else if pbty = Some true then
+ add_conv_pb (Reduction.CUMUL,env,mkEvar ev1,t2) evd
+ else
+ add_conv_pb (Reduction.CUMUL,env,t2,mkEvar ev1) evd
| _ ->
+ let evd =
+ if pbty = Some false then
+ check_instance_type conv_algo env evd ev1 t2
+ else
+ evd in
let evd = evar_define ~choose env ev1 t2 evd in
let evi = Evd.find evd evk1 in
if occur_existential evd evi.evar_concl then
diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli
index d35616ae2..8df301c66 100644
--- a/pretyping/evarutil.mli
+++ b/pretyping/evarutil.mli
@@ -80,7 +80,7 @@ val solve_refl :
evar_defs
val solve_simple_eqn :
(env -> evar_defs -> conv_pb -> constr -> constr -> evar_defs * bool)
- -> ?choose:bool -> env -> evar_defs -> conv_pb * existential * constr ->
+ -> ?choose:bool -> env -> evar_defs -> bool option * existential * constr ->
evar_defs * bool
(* [check_evars env initial_sigma extended_sigma c] fails if some
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index d48c002e2..92c176593 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -600,7 +600,7 @@ let order_metas metas =
(* Solve an equation ?n[x1=u1..xn=un] = t where ?n is an evar *)
let solve_simple_evar_eqn env evd ev rhs =
- let evd,b = solve_simple_eqn Evarconv.evar_conv_x env evd (CONV,ev,rhs) in
+ let evd,b = solve_simple_eqn Evarconv.evar_conv_x env evd (None,ev,rhs) in
if not b then error_cannot_unify env evd (mkEvar ev,rhs);
let (evd,b) = Evarconv.consider_remaining_unif_problems env evd in
if not b then error "Cannot solve unification constraints";
diff --git a/test-suite/csdp.cache b/test-suite/csdp.cache
index 0a971d56c..f6f068c04 100644
--- a/test-suite/csdp.cache
+++ b/test-suite/csdp.cache
Binary files differ
diff --git a/test-suite/failure/evar1.v b/test-suite/failure/evar1.v
new file mode 100644
index 000000000..1a4e42a89
--- /dev/null
+++ b/test-suite/failure/evar1.v
@@ -0,0 +1,3 @@
+(* This used to succeed by producing an ill-typed term in v8.2 *)
+
+Lemma u: forall A : Prop, (exist _ A A) = (exist _ A A).