aboutsummaryrefslogtreecommitdiff
path: root/pretyping
diff options
context:
space:
mode:
authorherbelin2008-04-27 21:39:08 +0000
committerherbelin2008-04-27 21:39:08 +0000
commit7e6ce51bf1a7beea6fa7818d2e5447ade79c30e7 (patch)
treee4e967c5bb65efee5978d394ddd70fa7dbd641f3 /pretyping
parentca3812d7804f3936bb420e96fad034983ede271a (diff)
Quelques bricoles autour de l'unification:
- Un patch pour le bug de non vérification du typage de Stéphane L. - Changement du fameux message "cannot solve a second-order matching problem" en espérant, à défaut de savoir résoudre plus souvent le problème, que le message est plus explicite. - Divers changements cosmétiques. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@10860 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'pretyping')
-rw-r--r--pretyping/evd.mli2
-rw-r--r--pretyping/pretype_errors.ml4
-rw-r--r--pretyping/pretype_errors.mli4
-rw-r--r--pretyping/unification.ml44
4 files changed, 34 insertions, 20 deletions
diff --git a/pretyping/evd.mli b/pretyping/evd.mli
index 71c6bb0dc3..605f2fcd03 100644
--- a/pretyping/evd.mli
+++ b/pretyping/evd.mli
@@ -112,7 +112,7 @@ val metavars_of : constr -> Metaset.t
val mk_freelisted : constr -> constr freelisted
val map_fl : ('a -> 'b) -> 'a freelisted -> 'b freelisted
-(* Possible constraints over the instance of a metavariable:
+(* Status of an instance found by unification wrt to the meta it solves:
- a supertype of the meta (e.g. the solution to ?X <= T is a supertype of ?X)
- a subtype of the meta (e.g. the solution to T <= ?X is a supertype of ?X)
- a term that can be eta-expanded n times while still being a solution
diff --git a/pretyping/pretype_errors.ml b/pretyping/pretype_errors.ml
index cd32ac450a..06d1aa533b 100644
--- a/pretyping/pretype_errors.ml
+++ b/pretyping/pretype_errors.ml
@@ -32,6 +32,7 @@ type pretype_error =
| CannotUnifyBindingType of constr * constr
| CannotGeneralize of constr
| NoOccurrenceFound of constr * identifier option
+ | CannotFindWellTypedAbstraction of constr * constr list
(* Pretyping *)
| VarNotFound of identifier
| UnexpectedType of constr * constr
@@ -166,6 +167,9 @@ let error_cannot_unify_local env sigma (m,n,sn) =
let error_cannot_coerce env sigma (m,n) =
raise (PretypeError (env_ise sigma env,CannotUnify (m,n)))
+let error_cannot_find_well_typed_abstraction env sigma p l =
+ raise (PretypeError (env_ise sigma env,CannotFindWellTypedAbstraction (p,l)))
+
(*s Ml Case errors *)
let error_cant_find_case_type_loc loc env sigma expr =
diff --git a/pretyping/pretype_errors.mli b/pretyping/pretype_errors.mli
index c6527f337e..a276b4ed51 100644
--- a/pretyping/pretype_errors.mli
+++ b/pretyping/pretype_errors.mli
@@ -34,6 +34,7 @@ type pretype_error =
| CannotUnifyBindingType of constr * constr
| CannotGeneralize of constr
| NoOccurrenceFound of constr * identifier option
+ | CannotFindWellTypedAbstraction of constr * constr list
(* Pretyping *)
| VarNotFound of identifier
| UnexpectedType of constr * constr
@@ -101,6 +102,9 @@ val error_cannot_unify : env -> Evd.evar_map -> constr * constr -> 'b
val error_cannot_unify_local : env -> Evd.evar_map -> constr * constr * constr -> 'b
+val error_cannot_find_well_typed_abstraction : env -> Evd.evar_map ->
+ constr -> constr list -> 'b
+
(*s Ml Case errors *)
val error_cant_find_case_type_loc :
diff --git a/pretyping/unification.ml b/pretyping/unification.ml
index 84f9330d3b..578afdb75c 100644
--- a/pretyping/unification.ml
+++ b/pretyping/unification.ml
@@ -48,8 +48,8 @@ let abstract_list_all env evd typ c l =
try
if is_conv_leq env (evars_of evd) (Typing.mtype_of env evd p) typ then p
else error "abstract_list_all"
- with UserError _ ->
- raise (PretypeError (env,CannotGeneralize typ))
+ with UserError _ | Type_errors.TypeError _ ->
+ error_cannot_find_well_typed_abstraction env (evars_of evd) p l
(**)
@@ -142,7 +142,7 @@ let expand_constant env flags c =
| Var id when Idpred.mem id ids && Idpred.mem id (fst flags.modulo_delta) -> named_body id env
| _ -> None
-let unify_0_with_initial_metas metas conv_at_top env sigma cv_pb flags m n =
+let unify_0_with_initial_metas subst conv_at_top env sigma cv_pb flags m n =
let nb = nb_rel env in
let trivial_unify pb (metasubst,_) m n =
match subst_defined_metas metasubst m with
@@ -243,11 +243,11 @@ let unify_0_with_initial_metas metas conv_at_top env sigma cv_pb flags m n =
is_trans_fconv (conv_pb_of cv_pb) flags env sigma m n
| None -> eq_constr m n)
then
- (metas,[])
+ subst
else
- unirec_rec env cv_pb conv_at_top (metas,[]) m n
+ unirec_rec env cv_pb conv_at_top subst m n
-let unify_0 = unify_0_with_initial_metas [] true
+let unify_0 = unify_0_with_initial_metas ([],[]) true
let left = true
let right = false
@@ -451,7 +451,7 @@ let solve_simple_evar_eqn env evd ev rhs =
or in evars, possibly generating new unification problems; if [b]
is true, unification of types of metas is required *)
-let w_merge env with_types flags metas evars evd =
+let w_merge env with_types flags (metas,evars) evd =
let rec w_merge_rec evd metas evars eqns =
(* Process evars *)
@@ -528,7 +528,7 @@ let w_merge env with_types flags metas evars evd =
let w_unify_meta_types env ?(flags=default_unify_flags) evd =
let metas,evd = retract_coercible_metas evd in
- w_merge env true flags metas [] evd
+ w_merge env true flags (metas,[]) evd
(* [w_unify env evd M N]
performs a unification of M and N, generating a bunch of
@@ -540,12 +540,22 @@ let w_unify_meta_types env ?(flags=default_unify_flags) evd =
[clenv_typed_unify M N clenv] expects in addition that expected
types of metavars are unifiable with the types of their instances *)
+let check_types env evd subst m n =
+ if isEvar (fst (whd_stack m)) or isEvar (fst (whd_stack n)) then
+ unify_0_with_initial_metas subst true env (evars_of evd) topconv
+ default_unify_flags
+ (Retyping.get_type_of_with_meta env (evars_of evd) (metas_of evd) m)
+ (Retyping.get_type_of_with_meta env (evars_of evd) (metas_of evd) n)
+ else
+ subst
+
let w_unify_core_0 env with_types cv_pb flags m n evd =
let (mc1,evd') = retract_coercible_metas evd in
- let (mc2,ec) =
- unify_0_with_initial_metas mc1 true env (evars_of evd') cv_pb flags m n
+ let subst1 = check_types env evd (mc1,[]) m n in
+ let subst2 =
+ unify_0_with_initial_metas subst1 true env (evars_of evd') cv_pb flags m n
in
- w_merge env with_types flags mc2 ec evd'
+ w_merge env with_types flags subst2 evd'
let w_unify_0 env = w_unify_core_0 env false
let w_typed_unify env = w_unify_core_0 env true
@@ -653,7 +663,7 @@ let secondOrderAbstraction env flags allow_K typ (p, oplist) evd =
w_unify_to_subterm_list env flags allow_K oplist typ evd in
let typp = Typing.meta_type evd' p in
let pred = abstract_list_all env evd' typp typ cllist in
- w_unify_0 env topconv flags (mkMeta p) pred evd'
+ w_merge env false flags ([p,pred,(ConvUpToEta 0,TypeProcessed)],[]) evd'
let w_unify2 env flags allow_K cv_pb ty1 ty2 evd =
let c1, oplist1 = whd_stack ty1 in
@@ -673,7 +683,6 @@ let w_unify2 env flags allow_K cv_pb ty1 ty2 evd =
w_unify_0 env cv_pb flags ty1 (nf_meta evd' ty2) evd'
| _ -> error "w_unify2"
-
(* The unique unification algorithm works like this: If the pattern is
flexible, and the goal has a lambda-abstraction at the head, then
we do a first-order unification.
@@ -707,9 +716,7 @@ let w_unify allow_K env cv_pb ?(flags=default_unify_flags) ty1 ty2 evd =
with ex when precatchable_exception ex ->
try
w_unify2 env flags allow_K cv_pb ty1 ty2 evd
- with PretypeError (env,NoOccurrenceFound _) as e -> raise e
- | ex when precatchable_exception ex ->
- error "Cannot solve a second-order unification problem")
+ with PretypeError (env,NoOccurrenceFound _) as e -> raise e)
(* Second order case *)
| (Meta _, true, _, _ | _, _, Meta _, true) ->
@@ -719,9 +726,8 @@ let w_unify allow_K env cv_pb ?(flags=default_unify_flags) ty1 ty2 evd =
| ex when precatchable_exception ex ->
try
w_typed_unify env cv_pb flags ty1 ty2 evd
- with ex when precatchable_exception ex ->
- error "Cannot solve a second-order unification problem")
+ with ex' when precatchable_exception ex' ->
+ raise ex)
(* General case: try first order *)
| _ -> w_typed_unify env cv_pb flags ty1 ty2 evd
-