aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2011-12-04 20:48:20 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2011-12-04 20:48:20 +0000
commit17e99469c656a157f5ab998e21c41294ea2abbf8 (patch)
tree4e0d8129a9f09659d91d19a05b2cc5e4d61365f9
parentc9f87fca10b37d15fc943dc4f5d2adb1c3304a3c (diff)
Discarding let-ins from the instances of the evars in the
pattern-unification test. They were tolerated up to r14539. Also expanded the let-ins not bound to rel or var in the right-hand side of a term for which pattern-unification is tested (this expansion can refer to a non-let variable that has to be taken into account in the pattern-unification test). git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@14757 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--pretyping/evarconv.ml8
-rw-r--r--pretyping/evarutil.ml56
-rw-r--r--pretyping/evarutil.mli4
-rw-r--r--pretyping/unification.ml4
-rw-r--r--test-suite/success/evars.v43
5 files changed, 84 insertions, 31 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index ec581eaf1..91b0eacc4 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -228,7 +228,7 @@ and evar_eqappr_x ?(rhs_is_stuck_proj = false)
| Flexible ev1, MaybeFlexible flex2 ->
let f1 i =
- match is_unification_pattern_evar env ev1 l1 (applist appr2) with
+ match is_unification_pattern_evar env evd ev1 l1 (applist appr2) with
| Some l1' ->
(* Miller-Pfenning's patterns unification *)
(* Preserve generality (except that CCI has no eta-conversion) *)
@@ -261,7 +261,7 @@ and evar_eqappr_x ?(rhs_is_stuck_proj = false)
| MaybeFlexible flex1, Flexible ev2 ->
let f1 i =
- match is_unification_pattern_evar env ev2 l2 (applist appr1) with
+ match is_unification_pattern_evar env evd ev2 l2 (applist appr1) with
| Some l1' ->
(* Miller-Pfenning's patterns unification *)
(* Preserve generality (except that CCI has no eta-conversion) *)
@@ -361,7 +361,7 @@ and evar_eqappr_x ?(rhs_is_stuck_proj = false)
evar_conv_x ts (push_rel (na,None,c) env) i CONV c'1 c'2)]
| Flexible ev1, (Rigid _ | PseudoRigid _) ->
- (match is_unification_pattern_evar env ev1 l1 (applist appr2) with
+ (match is_unification_pattern_evar env evd ev1 l1 (applist appr2) with
| Some l1 ->
(* Miller-Pfenning's pattern unification *)
(* Preserve generality thanks to eta-conversion) *)
@@ -375,7 +375,7 @@ and evar_eqappr_x ?(rhs_is_stuck_proj = false)
true)
| (Rigid _ | PseudoRigid _), Flexible ev2 ->
- (match is_unification_pattern_evar env ev2 l2 (applist appr1) with
+ (match is_unification_pattern_evar env evd ev2 l2 (applist appr1) with
| Some l2 ->
(* Miller-Pfenning's pattern unification *)
(* Preserve generality thanks to eta-conversion) *)
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index fd07680b5..57a6426ab 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -171,7 +171,8 @@ let compute_var_aliases sign =
let aliases_of_id =
try Idmap.find id' aliases with Not_found -> [] in
Idmap.add id (aliases_of_id@[t]) aliases
- | _ -> aliases)
+ | _ ->
+ Idmap.add id [t] aliases)
| None -> aliases)
sign Idmap.empty
@@ -190,7 +191,7 @@ let compute_rel_aliases var_aliases rels =
try Intmap.find (p+n) aliases with Not_found -> [] in
Intmap.add n (aliases_of_n@[mkRel (p+n)]) aliases
| _ ->
- aliases)
+ Intmap.add n [lift n t] aliases)
| None -> aliases))
rels (List.length rels,Intmap.empty))
@@ -208,7 +209,9 @@ let get_alias_chain_of aliases x = match kind_of_term x with
let normalize_alias_opt aliases x =
match get_alias_chain_of aliases x with
| [] -> None
- | a::_ -> Some a
+ | a::_ when isRel a or isVar a -> Some a
+ | [_] -> None
+ | _::a::_ -> Some a
let normalize_alias aliases x =
match normalize_alias_opt aliases x with
@@ -235,12 +238,20 @@ let extend_alias (_,b,_) (var_aliases,rel_aliases) =
try Intmap.find (p+1) rel_aliases with Not_found -> [] in
Intmap.add 1 (aliases_of_binder@[mkRel (p+1)]) rel_aliases
| _ ->
- rel_aliases)
+ Intmap.add 1 [lift 1 t] rel_aliases)
| None -> rel_aliases in
(var_aliases, rel_aliases)
let rec expansions_of_var aliases x =
- x :: List.rev (get_alias_chain_of aliases x)
+ match get_alias_chain_of aliases x with
+ | [] -> [x]
+ | a::_ as l when isRel a || isVar a -> x :: List.rev l
+ | _::l -> x :: List.rev l
+
+let expansion_of_var aliases x =
+ match get_alias_chain_of aliases x with
+ | [] -> x
+ | a::_ -> a
let rec expand_vars_in_term_using aliases t = match kind_of_term t with
| Rel _ | Var _ ->
@@ -255,7 +266,7 @@ let free_vars_and_rels_up_alias_expansion aliases c =
let acc1 = ref Intset.empty and acc2 = ref Idset.empty in
let rec frec (aliases,depth) c = match kind_of_term c with
| Rel _ | Var _ ->
- let c = normalize_alias aliases c in
+ let c = expansion_of_var aliases c in
(match kind_of_term c with
| Var id -> acc2 := Idset.add id !acc2
| Rel n -> if n >= depth+1 then acc1 := Intset.add (n-depth) !acc1
@@ -402,17 +413,6 @@ let generalize_evar_over_rels sigma (ev,args) =
* operations on the evar constraints *
*------------------------------------*)
-(* Pb: defined Rels and Vars should not be considered as a pattern... *)
-(*
-let is_pattern inst =
- let rec is_hopat l = function
- [] -> true
- | t :: tl ->
- (isRel t or isVar t) && not (List.mem t l) && is_hopat (t::l) tl in
- is_hopat [] (Array.to_list inst)
-*)
-
-
exception IllTypedFilter
let check_restricted_occur evd refine env filter constr =
@@ -1333,6 +1333,15 @@ let get_actual_deps aliases l t =
| Rel n -> Intset.mem n fv_rels
| _ -> assert false) l
+let remove_instance_local_defs evd evk args =
+ let evi = Evd.find evd evk in
+ let rec aux = function
+ | (_,Some _,_)::sign, a::args -> aux (sign,args)
+ | (_,None,_)::sign, a::args -> a::aux (sign,args)
+ | [], [] -> []
+ | _ -> assert false in
+ aux (evar_filtered_context evi, args)
+
(* Check if an applied evar "?X[args] l" is a Miller's pattern *)
let find_unification_pattern_args env l t =
@@ -1354,19 +1363,20 @@ let is_unification_pattern_meta env nb m l t =
else
None
-let is_unification_pattern_evar env (evk,args) l t =
+let is_unification_pattern_evar env evd (evk,args) l t =
if List.for_all (fun x -> isRel x || isVar x) l (* common failure case *) then
- let n = Array.length args in
- match find_unification_pattern_args env (Array.to_list args @ l) t with
+ let args = remove_instance_local_defs evd evk (Array.to_list args) in
+ let n = List.length args in
+ match find_unification_pattern_args env (args @ l) t with
| Some l when not (occur_evar evk t) -> Some (list_skipn n l)
| _ -> None
else
None
-let is_unification_pattern (env,nb) f l t =
+let is_unification_pattern (env,nb) evd f l t =
match kind_of_term f with
| Meta m -> is_unification_pattern_meta env nb m l t
- | Evar ev -> is_unification_pattern_evar env ev l t
+ | Evar ev -> is_unification_pattern_evar env evd ev l t
| _ -> None
(* From a unification problem "?X l = c", build "\x1...xn.(term1 l2)"
@@ -1383,7 +1393,7 @@ let solve_pattern_eqn env l c =
(* Rem: if [a] links to a let-in, do as if it were an assumption *)
| Rel n ->
let d = map_rel_declaration (lift n) (lookup_rel n env) in
- mkLambda_or_LetIn d c'
+ mkLambda_or_LetIn d c'
| Var id ->
let d = lookup_named id env in mkNamedLambda_or_LetIn d c'
| _ -> assert false)
diff --git a/pretyping/evarutil.mli b/pretyping/evarutil.mli
index 36e64c9ad..78898aaa7 100644
--- a/pretyping/evarutil.mli
+++ b/pretyping/evarutil.mli
@@ -96,10 +96,10 @@ val define_evar_as_product : evar_map -> existential -> evar_map * types
val define_evar_as_lambda : env -> evar_map -> existential -> evar_map * types
val define_evar_as_sort : evar_map -> existential -> evar_map * sorts
-val is_unification_pattern_evar : env -> existential -> constr list ->
+val is_unification_pattern_evar : env -> evar_map -> existential -> constr list ->
constr -> constr list option
-val is_unification_pattern : env * int -> constr -> constr list ->
+val is_unification_pattern : env * int -> evar_map -> constr -> constr list ->
constr -> constr list option
val evar_absorb_arguments : env -> evar_map -> existential -> constr list ->
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 187533ad3..78f62a5ab 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -443,13 +443,13 @@ let unify_0_with_initial_metas (sigma,ms,es as subst) conv_at_top env cv_pb flag
| App (f1,l1), _ when
(isMeta f1 && use_metas_pattern_unification flags nb l1
|| use_evars_pattern_unification flags && isAllowedEvar flags f1) &
- store whenmem (is_unification_pattern curenvnb f1 (Array.to_list l1) cN) ->
+ store whenmem (is_unification_pattern curenvnb sigma f1 (Array.to_list l1) cN) ->
solve_pattern_eqn_array curenvnb f1 (restore whenmem) cN substn
| _, App (f2,l2) when
(isMeta f2 && use_metas_pattern_unification flags nb l2
|| use_evars_pattern_unification flags && isAllowedEvar flags f2) &
- store whenmem (is_unification_pattern curenvnb f2 (Array.to_list l2) cM) ->
+ store whenmem (is_unification_pattern curenvnb sigma f2 (Array.to_list l2) cM) ->
solve_pattern_eqn_array curenvnb f2 (restore whenmem) cM substn
| App (f1,l1), App (f2,l2) ->
diff --git a/test-suite/success/evars.v b/test-suite/success/evars.v
index ba8da1a4f..2f1ec7571 100644
--- a/test-suite/success/evars.v
+++ b/test-suite/success/evars.v
@@ -266,3 +266,46 @@ Goal forall (A:Type) (a:A) (P:forall A, A -> Prop), (P A a) /\ (P A a).
intros.
refine ((fun H => conj (proj1 H) (proj2 H)) _).
Abort.
+
+(* The argument of e below failed to be inferred from r14219 (Oct 2011) to *)
+(* r14753 after the restrictions made on detecting Miller's pattern in the *)
+(* presence of alias, only the second-order unification procedure was *)
+(* able to solve this problem but it was deactivated for 8.4 in r14219 *)
+
+Definition k0
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, n = a) o :=
+ match o with (* note: match introduces an alias! *)
+ | Some a => e _ (j a)
+ | None => O
+ end.
+
+Definition k1
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, n = a) a (b:=a) := e _ (j a).
+
+Definition k2
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, n = a) a (b:=a) := e _ (j b).
+
+(* Other examples about aliases involved in pattern unification *)
+
+Definition k3
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, let a' := a in n = a') a (b:=a) := e _ (j b).
+
+Definition k4
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, let a' := S a in n = a') a (b:=a) := e _ (j b).
+
+Definition k5
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, let a' := S a in exists n : nat, n = a') a (b:=a) := e _ (j b).
+
+Definition k6
+ (e:forall P : nat -> Prop, (exists n : nat, P n) -> nat)
+ (j : forall a, exists n : nat, let n' := S n in n' = a) a (b:=a) := e _ (j b).
+
+Definition k7
+ (e:forall P : nat -> Prop, (exists n : nat, let n' := n in P n') -> nat)
+ (j : forall a, exists n : nat, n = a) a (b:=a) := e _ (j b).