aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Matthieu Sozeau <matthieu.sozeau@inria.fr>2014-10-15 13:31:46 +0200
committerGravatar Matthieu Sozeau <matthieu.sozeau@inria.fr>2014-10-15 13:34:02 +0200
commit6bca54599ab2b8ab928bfc92b8ddfb0aeba4345f (patch)
tree9730a7ee84044a8ee5062cc6340cc982b31f7722
parent5e1713d8fe9032a3f5c783cce288b409b6fdf816 (diff)
Reenable FO unification of primitive projections and their eta-expanded
forms in evarconv and unification, as well as fallback to first-order unification when eta for constructors fail. Update test-suite file 3484 to test for the FO case in evarconv as well.
-rw-r--r--pretyping/evarconv.ml24
-rw-r--r--pretyping/unification.ml42
-rw-r--r--test-suite/bugs/closed/3484.v5
3 files changed, 59 insertions, 12 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 21629553d..799ca2523 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -572,7 +572,29 @@ and evar_eqappr_x ?(rhs_is_already_stuck = false) ts env evd pbty
in evar_eqappr_x ts env i pbty out1 out2
in
ise_try evd [f1; f2]
-
+
+ (* Catch the p.c ~= p c' cases *)
+ | Proj (p,c), Const (p',u) when eq_constant (Projection.constant p) p' ->
+ let res =
+ try Some (destApp (Retyping.expand_projection env evd p c []))
+ with Retyping.RetypeError _ -> None
+ in
+ (match res with
+ | Some (f1,args1) ->
+ evar_eqappr_x ts env evd pbty ((f1,Stack.append_app args1 sk1),csts1)
+ (appr2,csts2)
+ | None -> UnifFailure (evd,NotSameHead))
+
+ | Const (p,u), Proj (p',c') when eq_constant p (Projection.constant p') ->
+ let res =
+ try Some (destApp (Retyping.expand_projection env evd p' c' []))
+ with Retyping.RetypeError _ -> None
+ in
+ (match res with
+ | Some (f2,args2) ->
+ evar_eqappr_x ts env evd pbty (appr1,csts1) ((f2,Stack.append_app args2 sk2),csts2)
+ | None -> UnifFailure (evd,NotSameHead))
+
| _, _ ->
let f1 i =
(* Gather the universe constraints that would make term1 and term2 equal.
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 2b6c3921e..527199e3b 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -678,17 +678,31 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
(* For records *)
| App (f1, l1), _ when flags.modulo_eta &&
+ (* This ensures cN is an evar, meta or irreducible constant/variable
+ and not a constructor. *)
is_eta_constructor_app curenv flags.modulo_delta f1 l1 cN ->
- let l1', l2' = eta_constructor_app curenv f1 l1 cN in
- let opt' = {opt with at_top = true; with_cs = false} in
- Array.fold_left2 (unirec_rec curenvnb CONV opt') substn l1' l2'
+ (try
+ let l1', l2' = eta_constructor_app curenv f1 l1 cN in
+ let opt' = {opt with at_top = true; with_cs = false} in
+ Array.fold_left2 (unirec_rec curenvnb CONV opt') substn l1' l2'
+ with ex when precatchable_exception ex ->
+ match kind_of_term cN with
+ | App(f2,l2) when isMeta f2 || isEvar f2 ->
+ unify_app curenvnb pb opt substn cM f1 l1 cN f2 l2
+ | _ -> raise ex)
| _, App (f2, l2) when flags.modulo_eta &&
is_eta_constructor_app curenv flags.modulo_delta f2 l2 cM ->
- let l2', l1' = eta_constructor_app curenv f2 l2 cM in
- let opt' = {opt with at_top = true; with_cs = false} in
- Array.fold_left2 (unirec_rec curenvnb CONV opt') substn l1' l2'
-
+ (try
+ let l2', l1' = eta_constructor_app curenv f2 l2 cM in
+ let opt' = {opt with at_top = true; with_cs = false} in
+ Array.fold_left2 (unirec_rec curenvnb CONV opt') substn l1' l2'
+ with ex when precatchable_exception ex ->
+ match kind_of_term cM with
+ | App(f1,l1) when isMeta f1 || isEvar f1 ->
+ unify_app curenvnb pb opt substn cM f1 l1 cN f2 l2
+ | _ -> raise ex)
+
| Case (_,p1,c1,cl1), Case (_,p2,c2,cl2) ->
(try
let opt' = {opt with at_top = true; with_types = false} in
@@ -729,9 +743,15 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
| App (f1,l1), App (f2,l2) ->
unify_app curenvnb pb opt substn cM f1 l1 cN f2 l2
+
+ | App (f1,l1), Proj(p2,c2) ->
+ unify_app curenvnb pb opt substn cM f1 l1 cN cN [||]
+
+ | Proj (p1,c1), App(f2,l2) ->
+ unify_app curenvnb pb opt substn cM cM [||] cN f2 l2
| _ ->
- unify_not_same_head curenvnb pb opt substn cM cN
+ unify_not_same_head curenvnb pb opt substn cM cN
and unify_app (curenv, nb as curenvnb) pb opt (sigma, metas, evars as substn) cM f1 l1 cN f2 l2 =
try
@@ -756,8 +776,10 @@ let rec unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb
let opta = {opt with at_top = true; with_types = false} in
let optf = {opt with at_top = true; with_types = true} in
let (f1,l1,f2,l2) = adjust_app_array_size f1 l1 f2 l2 in
- Array.fold_left2 (unirec_rec curenvnb CONV opta)
- (unirec_rec curenvnb CONV optf substn f1 f2) l1 l2
+ if Array.length l1 == 0 then error_cannot_unify (fst curenvnb) sigma (cM,cN)
+ else
+ Array.fold_left2 (unirec_rec curenvnb CONV opta)
+ (unirec_rec curenvnb CONV optf substn f1 f2) l1 l2
with ex when precatchable_exception ex ->
try reduce curenvnb pb {opt with with_types = false} substn cM cN
with ex when precatchable_exception ex ->
diff --git a/test-suite/bugs/closed/3484.v b/test-suite/bugs/closed/3484.v
index 3070a4128..6c40a4266 100644
--- a/test-suite/bugs/closed/3484.v
+++ b/test-suite/bugs/closed/3484.v
@@ -14,7 +14,10 @@ Proof.
apply (@ap _ _ pr1 _ y).
Undo.
Unset Printing Notations.
- apply (ap pr1). admit.
+ apply (ap pr1).
+ Undo.
+ refine (ap pr1 _).
+admit.
Defined.
(* Toplevel input, characters 22-28: