diff options
| author | herbelin | 2007-05-21 17:47:25 +0000 |
|---|---|---|
| committer | herbelin | 2007-05-21 17:47:25 +0000 |
| commit | 5fbf92a3a63a5d464313ed4a3e8dd6adb0b67cf2 (patch) | |
| tree | ece0226b9a079702b5d2c654bbe1374b78458885 | |
| parent | ed5578ecabad14a772c64f53265d168a51777045 (diff) | |
Essai d'une nouvelle heuristique pour clenv_unique_resolver : si le
lemme n'est pas un lemme d'induction (plus précisément si la tête de
la conclusion n'est pas une variable), alors on n'instancie pas les
with-bindings pour que les unifications venant du filtrage de la
conclusion du lemme avec le but soient prioritaires (en effet
l'utilisation des types des with-bindings pour inférer des instances
-- portion du commit r9842 -- ne produit pas des solutions exactes
mais seulement des sous-types de solutions exactes alors que
l'unification avec le but produit des solutions exactes qui doivent
donc être considérées en priorité). Toutefois, dans certains cas, du
fait que unify_0 travaille modulo conversion uniquement sur les termes
clos, il faut quand même donner crédit aux instances données en
with-bindings pour que la conversion puisse être prise en compte et
ainsi retrouver un comportement au moins identique au précédent.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@9847 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | pretyping/clenv.ml | 15 | ||||
| -rw-r--r-- | pretyping/evd.ml | 6 | ||||
| -rw-r--r-- | pretyping/evd.mli | 3 | ||||
| -rw-r--r-- | pretyping/unification.ml | 48 |
4 files changed, 34 insertions, 38 deletions
diff --git a/pretyping/clenv.ml b/pretyping/clenv.ml index 929535b76b..c563688a8b 100644 --- a/pretyping/clenv.ml +++ b/pretyping/clenv.ml @@ -67,13 +67,7 @@ let clenv_type clenv = meta_instance clenv.evd clenv.templtyp let clenv_hnf_constr ce t = hnf_constr (cl_env ce) (cl_sigma ce) t let clenv_get_type_of ce c = - let metamap = - List.map - (function - | (n,Clval(_,_,typ)) -> (n,typ.rebus) - | (n,Cltyp (_,typ)) -> (n,typ.rebus)) - (meta_list ce.evd) in - Retyping.get_type_of_with_meta (cl_env ce) (cl_sigma ce) metamap c + Retyping.get_type_of_with_meta (cl_env ce) (cl_sigma ce) (metas_of ce.evd) c exception NotExtensibleClause @@ -255,8 +249,11 @@ let clenv_unify allow_K cv_pb t1 t2 clenv = { clenv with evd = w_unify allow_K clenv.env cv_pb t1 t2 clenv.evd } let clenv_unique_resolver allow_K clenv gl = - clenv_unify allow_K CUMUL (clenv_type clenv) (pf_concl gl) clenv - + if isMeta (fst (whd_stack clenv.templtyp.rebus)) then + clenv_unify allow_K CUMUL (clenv_type clenv) (pf_concl gl) clenv + else + try clenv_unify allow_K CUMUL clenv.templtyp.rebus (pf_concl gl) clenv + with _ -> clenv_unify allow_K CUMUL (clenv_type clenv) (pf_concl gl) clenv (* [clenv_pose_dependent_evars clenv] * For each dependent evar in the clause-env which does not have a value, diff --git a/pretyping/evd.ml b/pretyping/evd.ml index 5d959be8bd..1ff0c633a0 100644 --- a/pretyping/evd.ml +++ b/pretyping/evd.ml @@ -464,6 +464,12 @@ let pr_sort_constraints (_,sm) = pr_sort_cstrs sm let meta_list evd = metamap_to_list evd.metas +let metas_of evd = + List.map (function + | (n,Clval(_,_,typ)) -> (n,typ.rebus) + | (n,Cltyp (_,typ)) -> (n,typ.rebus)) + (meta_list evd) + let meta_defined evd mv = match Metamap.find mv evd.metas with | Clval _ -> true diff --git a/pretyping/evd.mli b/pretyping/evd.mli index f6052b3686..a1323e501c 100644 --- a/pretyping/evd.mli +++ b/pretyping/evd.mli @@ -15,6 +15,7 @@ open Term open Sign open Libnames open Mod_subst +open Termops (*i*) (* The type of mappings for existential variables. @@ -174,6 +175,8 @@ val meta_reassign : metavariable -> constr * instance_status -> evar_defs -> ev (* [meta_merge evd1 evd2] returns [evd2] extended with the metas of [evd1] *) val meta_merge : evar_defs -> evar_defs -> evar_defs +val metas_of : evar_defs -> metamap + (**********************************************************) (* Sort variables *) diff --git a/pretyping/unification.ml b/pretyping/unification.ml index d991486c40..5231cce429 100644 --- a/pretyping/unification.ml +++ b/pretyping/unification.ml @@ -23,6 +23,7 @@ open Rawterm open Pattern open Evarutil open Pretype_errors +open Retyping (* if lname_typ is [xn,An;..;x1,A1] and l is a list of terms, gives [x1:A1]..[xn:An]c' such that c converts to ([x1:A1]..[xn:An]c' l) *) @@ -86,7 +87,7 @@ let solve_pattern_eqn_array env f l c (metasubst,evarsubst) = (k,solve_pattern_eqn env (Array.to_list l) c,pb)::metasubst,evarsubst | Evar ev -> (* Currently unused: incompatible with eauto/eassumption backtracking *) - metasubst,(f,solve_pattern_eqn env (Array.to_list l) c)::evarsubst + metasubst,(ev,solve_pattern_eqn env (Array.to_list l) c)::evarsubst | _ -> assert false (*******************************) @@ -136,8 +137,8 @@ let unify_0 env sigma cv_pb mod_delta m n = if (closedn (nb_rel env) cM) then (k,cM,fst (extract_instance_status pb))::metasubst,evarsubst else error_cannot_unify_local curenv sigma (m,n,cM) - | Evar _, _ -> metasubst,((cM,cN)::evarsubst) - | _, Evar _ -> metasubst,((cN,cM)::evarsubst) + | Evar ev, _ -> metasubst,((ev,cN)::evarsubst) + | _, Evar ev -> metasubst,((ev,cM)::evarsubst) | Lambda (na,t1,c1), Lambda (_,t2,c2) -> unirec_rec (push_rel_assum (na,t1) curenv) topconv (unirec_rec curenv topconv substn t1 t2) c1 c2 @@ -319,20 +320,18 @@ let w_merge env with_types mod_delta metas evars evd = let ty_evars = ref [] in let rec w_merge_rec evd metas evars = match (evars,metas) with - | ([], []) -> evd + | [], [] -> evd - | ((lhs,rhs)::t, metas) -> - (match kind_of_term rhs with + | ((evn,_ as ev),rhs)::t, metas -> + (match kind_of_term rhs with - | Meta k -> w_merge_rec evd ((k,lhs,ConvUpToEta 0)::metas) t + | Meta k -> w_merge_rec evd ((k,mkEvar ev,ConvUpToEta 0)::metas) t | krhs -> - (match kind_of_term lhs with - - | Evar (evn,_ as ev) -> if is_defined_evar evd ev then + let v = Evd.existential_value (evars_of evd) ev in let (metas',evars') = - unify_0 env (evars_of evd) topconv mod_delta rhs lhs in + unify_0 env (evars_of evd) topconv mod_delta rhs v in w_merge_rec evd (metas'@metas) (evars'@t) else begin let rhs' = @@ -352,9 +351,7 @@ let w_merge env with_types mod_delta metas evars evd = | _ -> (* ensure tail recursion in non-mimickable case! *) w_merge_rec (fst (evar_define env ev rhs' evd)) metas t - end - - | _ -> anomaly "w_merge_rec")) + end) | ([], (mv,n,status)::t) -> if meta_defined evd mv then @@ -368,26 +365,19 @@ let w_merge env with_types mod_delta metas evars evd = w_merge_rec evd' (metas'@t) evars' else begin + let evd' = meta_assign mv (n,status) evd in if with_types (* or occur_meta mvty *) then begin - let mvty = Typing.meta_type evd mv in + let mvty = Typing.meta_type evd' mv in try - let sigma = evars_of evd in - (* why not typing with the metamap ? *) - let nty = Typing.type_of env sigma (nf_meta evd n) in - (* unification with arities may induce a too early *) - (* commitment of an evar to an arity of wrong sort *) - if - not (is_arity env sigma mvty) && - not (is_arity env sigma nty) - then - let (mc,ec) = unify_0 env sigma Cumul mod_delta nty mvty - in - ty_metas := mc @ !ty_metas; - ty_evars := ec @ !ty_evars + let sigma = evars_of evd' in + let metas = metas_of evd' in + let nty = get_type_of_with_meta env sigma metas (nf_meta evd' n) in + let (mc,ec) = unify_0 env sigma Cumul mod_delta nty mvty in + ty_metas := mc @ !ty_metas; + ty_evars := ec @ !ty_evars with e when precatchable_exception e -> () end; - let evd' = meta_assign mv (n,status) evd in w_merge_rec evd' t [] end |
