summaryrefslogtreecommitdiff
path: root/pretyping/evarconv.ml
diff options
context:
space:
mode:
Diffstat (limited to 'pretyping/evarconv.ml')
-rw-r--r--pretyping/evarconv.ml61
1 files changed, 35 insertions, 26 deletions
diff --git a/pretyping/evarconv.ml b/pretyping/evarconv.ml
index 58951302..323cd06f 100644
--- a/pretyping/evarconv.ml
+++ b/pretyping/evarconv.ml
@@ -6,7 +6,7 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(* $Id: evarconv.ml 11157 2008-06-21 10:45:51Z herbelin $ *)
+(* $Id: evarconv.ml 11309 2008-08-06 10:30:35Z herbelin $ *)
open Pp
open Util
@@ -99,21 +99,21 @@ let check_conv_record (t1,l1) (t2,l2) =
lookup_canonical_conversion
(proji, Sort_cs (family_of_sort s)),[]
| _ ->
- let c2 = try global_of_constr t2 with _ -> raise Not_found in
+ let c2 = global_of_constr t2 in
lookup_canonical_conversion (proji, Const_cs c2),l2
with Not_found ->
lookup_canonical_conversion (proji,Default_cs),[]
in
- let { o_DEF = c; o_INJ=n; o_TABS = bs; o_TPARAMS = params; o_TCOMPS = us }
- = canon_s in
+ let { o_DEF = c; o_INJ=n; o_TABS = bs;
+ o_TPARAMS = params; o_NPARAMS = nparams; o_TCOMPS = us } = canon_s in
let params1, c1, extra_args1 =
- match list_chop (List.length params) l1 with
+ match list_chop nparams l1 with
| params1, c1::extra_args1 -> params1, c1, extra_args1
- | _ -> assert false in
+ | _ -> raise Not_found in
let us2,extra_args2 = list_chop (List.length us) l2_effective in
c,bs,(params,params1),(us,us2),(extra_args1,extra_args2),c1,
(n,applist(t2,l2))
- with _ ->
+ with Failure _ | Not_found ->
raise Not_found
(* Precondition: one of the terms of the pb is an uninstantiated evar,
@@ -272,33 +272,42 @@ and evar_eqappr_x env evd pbty (term1,l1 as appr1) (term2,l2 as appr2) =
ise_try evd [f1; f4]
| MaybeFlexible flex1, MaybeFlexible flex2 ->
- let f2 i =
- if flex1 = flex2 then
- ise_list2 i (fun i -> evar_conv_x env i CONV) l1 l2
- else (i,false)
- and f3 i =
+ let f1 i =
+ if flex1 = flex2 then
+ ise_list2 i (fun i -> evar_conv_x env i CONV) l1 l2
+ else
+ (i,false)
+ and f2 i =
(try conv_record env i
(try check_conv_record appr1 appr2
with Not_found -> check_conv_record appr2 appr1)
with Not_found -> (i,false))
- and f4 i =
+ and f3 i =
(* heuristic: unfold second argument first, exception made
if the first argument is a beta-redex (expand a constant
- only if necessary) *)
- let val2 =
- match kind_of_term flex1 with
- Lambda _ -> None
- | _ -> eval_flexible_term env flex2 in
- match val2 with
+ only if necessary) or the second argument is potentially
+ usable as a canonical projection *)
+ if isLambda flex1 or is_open_canonical_projection (evars_of i) appr2
+ then
+ match eval_flexible_term env flex1 with
+ | Some v1 ->
+ evar_eqappr_x env i pbty (evar_apprec env i l1 v1) appr2
+ | None ->
+ match eval_flexible_term env flex2 with
+ | Some v2 ->
+ evar_eqappr_x env i pbty appr1 (evar_apprec env i l2 v2)
+ | None -> (i,false)
+ else
+ match eval_flexible_term env flex2 with
| Some v2 ->
evar_eqappr_x env i pbty appr1 (evar_apprec env i l2 v2)
| None ->
match eval_flexible_term env flex1 with
- | Some v1 ->
- evar_eqappr_x env i pbty (evar_apprec env i l1 v1) appr2
- | None -> (i,false)
+ | Some v1 ->
+ evar_eqappr_x env i pbty (evar_apprec env i l1 v1) appr2
+ | None -> (i,false)
in
- ise_try evd [f2; f3; f4]
+ ise_try evd [f1; f2; f3]
| Flexible ev1, Rigid _ ->
if
@@ -496,7 +505,7 @@ let choose_less_dependent_instance evk evd term args =
let evi = Evd.find (evars_of evd) evk in
let subst = make_pure_subst evi args in
let subst' = List.filter (fun (id,c) -> c = term) subst in
- if subst' = [] then error "Too complex unification problem" else
+ if subst' = [] then error "Too complex unification problem." else
Evd.evar_define evk (mkVar (fst (List.hd subst'))) evd
let apply_conversion_problem_heuristic env evd pbty t1 t2 =
@@ -506,12 +515,12 @@ let apply_conversion_problem_heuristic env evd pbty t1 t2 =
let (term2,l2 as appr2) = decompose_app t2 in
match kind_of_term term1, kind_of_term term2 with
| Evar (evk1,args1), (Rel _|Var _) when l1 = [] & l2 = [] ->
- (* The typical kind of constraint coming from patter-matching return
+ (* The typical kind of constraint coming from pattern-matching return
type inference *)
assert (array_for_all (fun a -> a = term2 or isEvar a) args1);
choose_less_dependent_instance evk1 evd term2 args1, true
| (Rel _|Var _), Evar (evk2,args2) when l1 = [] & l2 = [] ->
- (* The typical kind of constraint coming from patter-matching return
+ (* The typical kind of constraint coming from pattern-matching return
type inference *)
assert (array_for_all ((=) term1) args2);
choose_less_dependent_instance evk2 evd term1 args2, true