aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--proofs/clenv.ml12
-rw-r--r--proofs/clenv.mli1
-rw-r--r--tactics/eauto.ml2
-rw-r--r--tactics/tactics.ml37
4 files changed, 39 insertions, 13 deletions
diff --git a/proofs/clenv.ml b/proofs/clenv.ml
index 70f4f7080..94d3c1b69 100644
--- a/proofs/clenv.ml
+++ b/proofs/clenv.ml
@@ -352,6 +352,14 @@ let clenv_environments bound c =
in
clrec (Intmap.empty,Intmap.empty,[]) bound c
+let mk_clenv_from_n wc n (c,cty) =
+ let (namenv,env,args,concl) = clenv_environments n cty in
+ { templval = mk_freelisted (match args with [] -> c | _ -> applist (c,args));
+ templtyp = mk_freelisted concl;
+ namenv = namenv;
+ env = env;
+ hook = wc }
+
let mk_clenv_from wc (c,cty) =
let (namenv,env,args,concl) = clenv_environments (-1) cty in
{ templval = mk_freelisted (match args with [] -> c | _ -> applist (c,args));
@@ -1060,11 +1068,11 @@ let e_res_pf kONT clenv gls =
let collect_com lbind =
map_succeed (function (Com,c)->c | _ -> failwith "Com") lbind
-let make_clenv_binding_apply wc (c,t) lbind =
+let make_clenv_binding_apply wc n (c,t) lbind =
let largs = collect_com lbind in
let lcomargs = List.length largs in
if lcomargs = List.length lbind then
- let clause = mk_clenv_from wc (c,t) in
+ let clause = mk_clenv_from_n wc n (c,t) in
clenv_constrain_missing_args largs clause
else if lcomargs = 0 then
let clause = mk_clenv_rename_from wc (c,t) in
diff --git a/proofs/clenv.mli b/proofs/clenv.mli
index 106369d33..20eae8111 100644
--- a/proofs/clenv.mli
+++ b/proofs/clenv.mli
@@ -97,6 +97,7 @@ val clenv_unique_resolver : bool -> wc clausenv -> goal sigma -> wc clausenv
val make_clenv_binding_apply :
walking_constraints ->
+ int ->
constr * constr ->
(bindOcc * types) list ->
walking_constraints clausenv
diff --git a/tactics/eauto.ml b/tactics/eauto.ml
index 38bb22342..24beccf3b 100644
--- a/tactics/eauto.ml
+++ b/tactics/eauto.ml
@@ -42,7 +42,7 @@ let registered_e_assumption gl =
let e_resolve_with_bindings_tac (c,lbind) gl =
let (wc,kONT) = startWalk gl in
let t = w_hnf_constr wc (w_type_of wc c) in
- let clause = make_clenv_binding_apply wc (c,t) lbind in
+ let clause = make_clenv_binding_apply wc (-1) (c,t) lbind in
e_res_pf kONT clause gl
let e_resolve_with_bindings =
diff --git a/tactics/tactics.ml b/tactics/tactics.ml
index bb34e96de..5ef73e5c4 100644
--- a/tactics/tactics.ml
+++ b/tactics/tactics.ml
@@ -33,6 +33,15 @@ open Coqlib
exception Bound
+let rec nb_prod x =
+ let rec count n c =
+ match kind_of_term c with
+ IsProd(_,_,t) -> count (n+1) t
+ | IsLetIn(_,a,_,t) -> count n (subst1 a t)
+ | IsCast(c,_) -> count n c
+ | _ -> n
+ in count 0 x
+
(*********************************************)
(* Tactics *)
(*********************************************)
@@ -482,6 +491,7 @@ let bring_hyps clsl gl =
(* Resolution with missing arguments *)
+
let apply_with_bindings (c,lbind) gl =
let apply =
match kind_of_term c with
@@ -489,20 +499,27 @@ let apply_with_bindings (c,lbind) gl =
| _ -> res_pf
in
let (wc,kONT) = startWalk gl in
+ (* The actual type of the theorem. It will be matched against the
+ goal. If this fails, then the head constant will be unfolded step by
+ step. *)
+ let thm_ty0 = (w_type_of wc c) in
let rec try_apply thm_ty =
try
- let clause = make_clenv_binding_apply wc (c,thm_ty) lbind in
+ let n = nb_prod thm_ty - nb_prod (pf_concl gl) in
+ if n<0 then error "Apply: theorem has not enough premisses.";
+ let clause = make_clenv_binding_apply wc n (c,thm_ty) lbind in
apply kONT clause gl
with (RefinerError _|UserError _|Failure _) as exn ->
- let ored =
- try Some (Tacred.red_product (w_env wc) (w_Underlying wc) thm_ty)
- with Tacred.Redelimination -> None
- in
- (match ored with
- Some rty ->
- try_apply rty
- | None -> raise exn) in
- try_apply (w_type_of wc c)
+ let red_thm =
+ try red_product (w_env wc) (w_Underlying wc) thm_ty
+ with (Redelimination | UserError _) -> raise exn in
+ try_apply red_thm in
+ try try_apply thm_ty0
+ with (RefinerError _|UserError _|Failure _) ->
+ (* Last chance: if the head is a variable, apply may try
+ second order unification *)
+ let clause = make_clenv_binding_apply wc (-1) (c,thm_ty0) lbind in
+ apply kONT clause gl
let apply c = apply_with_bindings (c,[])