aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-03-20 08:02:20 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-03-20 08:02:20 +0000
commit2e23b8850d533f94d7bab6d58afb7044c5cb4f66 (patch)
tree1ea2cde82d1ecb5eb91d1f3d5fdc8e4196ee3c37
parent75d51735e95d43323b03ecf586c6aba163cf70a6 (diff)
Use a careful analysis of dependencies in restricting instances to
solve the following kind of code broken by being less restrictive on projecting: Set Printing Existential Instances. Parameter f : forall x, x=0 -> x=0 -> x=1 /\ x=2. Parameter g : forall y, y=0 /\ y=0. Check match g _ with conj a b => f _ a b end. (* and the return clause should not depend on the "_" *) git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@15064 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--pretyping/evarutil.ml45
1 files changed, 36 insertions, 9 deletions
diff --git a/pretyping/evarutil.ml b/pretyping/evarutil.ml
index b23ac4211..109020dd8 100644
--- a/pretyping/evarutil.ml
+++ b/pretyping/evarutil.ml
@@ -704,11 +704,11 @@ let is_unification_pattern_meta env nb m l t =
None
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
+ if List.for_all (fun x -> isRel x || isVar x) l & not (occur_evar evk t) then
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)
+ | Some l -> Some (list_skipn n l)
| _ -> None
else
None
@@ -1285,14 +1285,40 @@ let restrict_candidates conv_algo env evd filter1 (evk1,argsv1) (evk2,argsv2) =
exception CannotProject of bool list option
-let has_constrainable_free_vars evd aliases k (fv_rels,fv_ids) t =
- match kind_of_term (expansion_of_var aliases t) with
+(* Assume that FV(?n[x1:=t1..xn:=tn]) belongs to some set U.
+ Can ?n be instantiated by a term u depending essentially on xi such that the
+ FV(u[x1:=t1..xn:=tn]) are in the set U?
+ - If ti is a variable, it has to be in U.
+ - If ti is a constructor, its parameters cannot be erased even if u
+ matches on it, so we have to discard ti if the parameters
+ contain variables not in U.
+ - If ti is rigid, we have to discard it if it contains variables in U.
+
+ Note: when restricting as part of an equation ?n[x1:=t1..xn:=tn] = ?m[...]
+ then, occurrences of ?m in the ti can be seen, like variables, as occurrences
+ of subterms to eventually discard so as to be allowed to keep ti.
+*)
+
+let rec is_constrainable_in k (ev,(fv_rels,fv_ids) as g) t =
+ let f,args = decompose_app_vect t in
+ match kind_of_term f with
+ | Construct (ind,_) ->
+ let params,_ = array_chop (Inductiveops.inductive_nparams ind) args in
+ array_for_all (is_constrainable_in k g) params
+ | Ind _ -> array_for_all (is_constrainable_in k g) args
+ | Prod (_,t1,t2) -> is_constrainable_in k g t1 && is_constrainable_in k g t2
+ | Evar (ev',_) -> ev' <> ev (*If ev' needed, one may also try to restrict it*)
+ | Var id -> Idset.mem id fv_ids
+ | Rel n -> n <= k || Intset.mem n fv_rels
+ | Sort _ -> true
+ | _ -> (* We don't try to be more clever *) true
+
+let has_constrainable_free_vars evd aliases k ev (fv_rels,fv_ids as fvs) t =
+ let t = expansion_of_var aliases t in
+ match kind_of_term t with
| Var id -> Idset.mem id fv_ids
| Rel n -> n <= k || Intset.mem n fv_rels
- | _ ->
- (* TODO: try to see if evars in t can be restricted so that the free
- vars of t are in fvs and return false if impossible *)
- true
+ | _ -> is_constrainable_in k (ev,fvs) t
exception EvarSolvedOnTheFly of evar_map * constr
@@ -1300,7 +1326,8 @@ let project_evar_on_evar g env evd aliases k2 (evk1,argsv1 as ev1) (evk2,argsv2
(* Apply filtering on ev1 so that fvs(ev1) are in fvs(ev2). *)
let fvs2 = free_vars_and_rels_up_alias_expansion aliases (mkEvar ev2) in
let filter1 = restrict_upon_filter evd evk1
- (has_constrainable_free_vars evd aliases k2 fvs2) (Array.to_list argsv1) in
+ (has_constrainable_free_vars evd aliases k2 evk2 fvs2)
+ (Array.to_list argsv1) in
(* Only try pruning on variable substitutions, postpone otherwise. *)
(* Rules out non-linear instances. *)
if is_unification_pattern_pure_evar env evd ev2 (mkEvar ev1) then