diff options
Diffstat (limited to 'tactics/auto.ml')
-rw-r--r-- | tactics/auto.ml | 314 |
1 files changed, 208 insertions, 106 deletions
diff --git a/tactics/auto.ml b/tactics/auto.ml index 152556c74..0f296c6af 100644 --- a/tactics/auto.ml +++ b/tactics/auto.ml @@ -36,16 +36,17 @@ open Tacexpr open Mod_subst open Locus open Proofview.Notations +open Decl_kinds (****************************************************************************) (* The Type of Constructions Autotactic Hints *) (****************************************************************************) type 'a auto_tactic = - | Res_pf of constr * 'a (* Hint Apply *) - | ERes_pf of constr * 'a (* Hint EApply *) - | Give_exact of constr - | Res_pf_THEN_trivial_fail of constr * 'a (* Hint Immediate *) + | Res_pf of 'a (* Hint Apply *) + | ERes_pf of 'a (* Hint EApply *) + | Give_exact of 'a + | Res_pf_THEN_trivial_fail of 'a (* Hint Immediate *) | Unfold_nth of evaluable_global_reference (* Hint Unfold *) | Extern of glob_tactic_expr (* Hint Extern *) @@ -61,16 +62,22 @@ type hints_path = | PathEmpty | PathEpsilon +type hint_term = + | IsGlobRef of global_reference + | IsConstr of constr * Univ.universe_context_set + type 'a gen_auto_tactic = { pri : int; (* A number lower is higher priority *) + poly : polymorphic; (** Is the hint polymorpic and hence should be refreshed at each application *) pat : constr_pattern option; (* A pattern for the concl of the Goal *) name : hints_path_atom; (* A potential name to refer to the hint *) code : 'a auto_tactic (* the tactic to apply when the concl matches pat *) } -type pri_auto_tactic = clausenv gen_auto_tactic +type pri_auto_tactic = (constr * clausenv) gen_auto_tactic -type hint_entry = global_reference option * types gen_auto_tactic +type hint_entry = global_reference option * + (constr * types * Univ.universe_context_set) gen_auto_tactic let eq_hints_path_atom p1 p2 = match p1, p2 with | PathHints gr1, PathHints gr2 -> List.equal eq_gr gr1 gr2 @@ -80,7 +87,7 @@ let eq_hints_path_atom p1 p2 = match p1, p2 with let eq_auto_tactic t1 t2 = match t1, t2 with | Res_pf (c1, _), Res_pf (c2, _) -> Constr.equal c1 c2 | ERes_pf (c1, _), ERes_pf (c2, _) -> Constr.equal c1 c2 -| Give_exact c1, Give_exact c2 -> Constr.equal c1 c2 +| Give_exact (c1, _), Give_exact (c2, _) -> Constr.equal c1 c2 | Res_pf_THEN_trivial_fail (c1, _), Res_pf_THEN_trivial_fail (c2, _) -> Constr.equal c1 c2 | Unfold_nth gr1, Unfold_nth gr2 -> eq_egr gr1 gr2 | Extern tac1, Extern tac2 -> tac1 == tac2 (** May cause redundancy in addkv *) @@ -134,17 +141,23 @@ type search_entry = stored_data list * stored_data list * Bounded_net.t let empty_se = ([],[],Bounded_net.create ()) +let eq_constr_or_reference x y = + match x, y with + | IsConstr (x,_), IsConstr (y,_) -> eq_constr x y + | IsGlobRef x, IsGlobRef y -> eq_gr x y + | _, _ -> false + let eq_pri_auto_tactic (_, x) (_, y) = if Int.equal x.pri y.pri && Option.equal constr_pattern_eq x.pat y.pat then match x.code,y.code with - | Res_pf(cstr,_),Res_pf(cstr1,_) -> + | Res_pf (cstr,_),Res_pf (cstr1,_) -> eq_constr cstr cstr1 - | ERes_pf(cstr,_),ERes_pf(cstr1,_) -> + | ERes_pf (cstr,_),ERes_pf (cstr1,_) -> eq_constr cstr cstr1 - | Give_exact cstr,Give_exact cstr1 -> + | Give_exact (cstr,_),Give_exact (cstr1,_) -> eq_constr cstr cstr1 - | Res_pf_THEN_trivial_fail(cstr,_) - ,Res_pf_THEN_trivial_fail(cstr1,_) -> + | Res_pf_THEN_trivial_fail (cstr,_) + ,Res_pf_THEN_trivial_fail (cstr1,_) -> eq_constr cstr cstr1 | _,_ -> false else @@ -176,20 +189,44 @@ let is_transparent_gr (ids, csts) = function let dummy_goal = Goal.V82.dummy_goal -let translate_hint (go,p) = - let mk_clenv (c,t) = - let cl = mk_clenv_from dummy_goal (c,t) in {cl with env = empty_env } +let instantiate_constr_or_ref env sigma c = + let c, ctx = Universes.fresh_global_or_constr_instance env c in + let cty = Retyping.get_type_of env sigma c in + (c, cty), ctx + +let strip_params env c = + match kind_of_term c with + | App (f, args) -> + (match kind_of_term f with + | Const (p,_) -> + let cb = lookup_constant p env in + (match cb.Declarations.const_proj with + | Some pb -> + let n = pb.Declarations.proj_npars in + mkApp (mkProj (p, args.(n)), + Array.sub args (n+1) (Array.length args - (n + 1))) + | None -> c) + | _ -> c) + | _ -> c + +let instantiate_hint p = + let mk_clenv c cty ctx = + let sigma = Evd.merge_context_set univ_flexible dummy_goal.sigma ctx in + let goal = { dummy_goal with sigma = sigma } in + let cl = mk_clenv_from goal (c,cty) in + {cl with templval = + { cl.templval with rebus = strip_params (Global.env()) cl.templval.rebus }; + env = empty_env} in let code = match p.code with - | Res_pf (c,t) -> Res_pf (c, mk_clenv (c,t)) - | ERes_pf (c,t) -> ERes_pf (c, mk_clenv (c,t)) - | Res_pf_THEN_trivial_fail (c,t) -> - Res_pf_THEN_trivial_fail (c, mk_clenv (c,t)) - | Give_exact c -> Give_exact c + | Res_pf (c, cty, ctx) -> Res_pf (c, mk_clenv c cty ctx) + | ERes_pf (c, cty, ctx) -> ERes_pf (c, mk_clenv c cty ctx) + | Res_pf_THEN_trivial_fail (c, cty, ctx) -> + Res_pf_THEN_trivial_fail (c, mk_clenv c cty ctx) + | Give_exact (c, cty, ctx) -> Give_exact (c, mk_clenv c cty ctx) | Unfold_nth e -> Unfold_nth e | Extern t -> Extern t - in - (go,{ p with code = code }) + in { pri = p.pri; poly = p.poly; name = p.name; pat = p.pat; code = code } let hints_path_atom_eq h1 h2 = match h1, h2 with | PathHints l1, PathHints l2 -> List.equal eq_gr l1 l2 @@ -350,17 +387,19 @@ module Hint_db = struct try Constr_map.find key db.hintdb_map with Not_found -> empty_se + let realize_tac (id,tac) = tac + let map_none db = - List.map snd (List.merge pri_order_int (List.map snd db.hintdb_nopat) []) + List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat) []) let map_all k db = let (l,l',_) = find k db in - List.map snd (List.merge pri_order_int (List.map snd db.hintdb_nopat @ l) l') + List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat @ l) l') let map_auto (k,c) db = let st = if db.use_dn then Some db.hintdb_state else None in let l' = lookup_tacs (k,c) st (find k db) in - List.map snd (List.merge pri_order_int (List.map snd db.hintdb_nopat) l') + List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat) l') let is_exact = function | Give_exact _ -> true @@ -384,6 +423,7 @@ module Hint_db = struct (** ppedrot: this equality here is dubious. Maybe we can remove it? *) let is_present (_, (_, v')) = eq_gen_auto_tactic v v' in if not (List.exists is_present db.hintdb_nopat) then + (** FIXME *) { db with hintdb_nopat = (gr,idv) :: db.hintdb_nopat } else db | Some gr -> @@ -397,8 +437,8 @@ module Hint_db = struct in List.fold_left (fun db (gr,(id,v)) -> addkv gr id v db) db' db.hintdb_nopat - let add_one kv db = - let (k,v) = translate_hint kv in + let add_one (k, v) db = + let v = instantiate_hint v in let st',db,rebuild = match v.code with | Unfold_nth egr -> @@ -432,8 +472,8 @@ module Hint_db = struct let remove_one gr db = remove_list [gr] db let iter f db = - f None (List.map (fun x -> snd (snd x)) db.hintdb_nopat); - Constr_map.iter (fun k (l,l',_) -> f (Some k) (List.map snd (l@l'))) db.hintdb_map + f None (List.map (fun x -> realize_tac (snd x)) db.hintdb_nopat); + Constr_map.iter (fun k (l,l',_) -> f (Some k) (List.map realize_tac (l@l'))) db.hintdb_map let fold f db accu = let accu = f None (List.map (fun x -> snd (snd x)) db.hintdb_nopat) accu in @@ -516,7 +556,7 @@ let try_head_pattern c = try head_pattern_bound c with BoundPattern -> error "Bound head variable." -let make_exact_entry sigma pri ?(name=PathAny) (c,cty) = +let make_exact_entry env sigma pri poly ?(name=PathAny) (c, cty, ctx) = let cty = strip_outer_cast cty in match kind_of_term cty with | Prod _ -> failwith "make_exact_entry" @@ -528,15 +568,17 @@ let make_exact_entry sigma pri ?(name=PathAny) (c,cty) = in (Some hd, { pri = (match pri with None -> 0 | Some p -> p); + poly = poly; pat = Some pat; name = name; - code = Give_exact c }) + code = Give_exact (c, cty, ctx) }) -let make_apply_entry env sigma (eapply,hnf,verbose) pri ?(name=PathAny) (c,cty) = +let make_apply_entry env sigma (eapply,hnf,verbose) pri poly ?(name=PathAny) (c, cty, ctx) = let cty = if hnf then hnf_constr env sigma cty else cty in match kind_of_term cty with | Prod _ -> - let ce = mk_clenv_from dummy_goal (c,cty) in + let sigma' = Evd.merge_context_set univ_flexible dummy_goal.sigma ctx in + let ce = mk_clenv_from { dummy_goal with sigma = sigma' } (c,cty) in let c' = clenv_type (* ~reduce:false *) ce in let pat = snd (Patternops.pattern_of_constr sigma c') in let hd = @@ -546,9 +588,10 @@ let make_apply_entry env sigma (eapply,hnf,verbose) pri ?(name=PathAny) (c,cty) if Int.equal nmiss 0 then (Some hd, { pri = (match pri with None -> nb_hyp cty | Some p -> p); + poly = poly; pat = Some pat; name = name; - code = Res_pf(c,cty) }) + code = Res_pf(c,cty,ctx) }) else begin if not eapply then failwith "make_apply_entry"; if verbose then @@ -556,9 +599,10 @@ let make_apply_entry env sigma (eapply,hnf,verbose) pri ?(name=PathAny) (c,cty) str " will only be used by eauto"); (Some hd, { pri = (match pri with None -> nb_hyp cty + nmiss | Some p -> p); + poly = poly; pat = Some pat; name = name; - code = ERes_pf(c,cty) }) + code = ERes_pf(c,cty,ctx) }) end | _ -> failwith "make_apply_entry" @@ -566,12 +610,18 @@ let make_apply_entry env sigma (eapply,hnf,verbose) pri ?(name=PathAny) (c,cty) c is a constr cty is the type of constr *) -let make_resolves env sigma flags pri ?name c = +let fresh_global_or_constr env sigma poly cr = + match cr with + | IsGlobRef gr -> Universes.fresh_global_instance env gr + | IsConstr (c, ctx) -> (c, ctx) + +let make_resolves env sigma flags pri poly ?name cr = + let c, ctx = fresh_global_or_constr env sigma poly cr in let cty = Retyping.get_type_of env sigma c in let try_apply f = - try Some (f (c, cty)) with Failure _ -> None in + try Some (f (c, cty, ctx)) with Failure _ -> None in let ents = List.map_filter try_apply - [make_exact_entry sigma pri ?name; make_apply_entry env sigma flags pri ?name] + [make_exact_entry env sigma pri poly ?name; make_apply_entry env sigma flags pri poly ?name] in if List.is_empty ents then errorlabstrm "Hint" @@ -583,9 +633,9 @@ let make_resolves env sigma flags pri ?name c = (* used to add an hypothesis to the local hint database *) let make_resolve_hyp env sigma (hname,_,htyp) = try - [make_apply_entry env sigma (true, true, false) None + [make_apply_entry env sigma (true, true, false) None false ~name:(PathHints [VarRef hname]) - (mkVar hname, htyp)] + (mkVar hname, htyp, Univ.ContextSet.empty)] with | Failure _ -> [] | e when Logic.catchable_exception e -> anomaly (Pp.str "make_resolve_hyp") @@ -595,6 +645,7 @@ let make_unfold eref = let g = global_of_evaluable_reference eref in (Some g, { pri = 4; + poly = false; pat = None; name = PathHints [g]; code = Unfold_nth eref }) @@ -603,19 +654,21 @@ let make_extern pri pat tacast = let hdconstr = Option.map try_head_pattern pat in (hdconstr, { pri = pri; + poly = false; pat = pat; name = PathAny; code = Extern tacast }) -let make_trivial env sigma ?(name=PathAny) r = - let c = constr_of_global_or_constr r in +let make_trivial env sigma poly ?(name=PathAny) r = + let c,ctx = fresh_global_or_constr env sigma poly r in let t = hnf_constr env sigma (type_of env sigma c) in - let hd = head_of_constr_reference (fst (head_constr t)) in + let hd = head_of_constr_reference (head_constr t) in let ce = mk_clenv_from dummy_goal (c,t) in (Some hd, { pri=1; + poly = poly; pat = Some (snd (Patternops.pattern_of_constr sigma (clenv_type ce))); name = name; - code=Res_pf_THEN_trivial_fail(c,t) }) + code=Res_pf_THEN_trivial_fail(c,t,ctx) }) open Vernacexpr @@ -675,11 +728,21 @@ let cache_autohint (_,(local,name,hints)) = let (forward_subst_tactic, extern_subst_tactic) = Hook.make () + (* let subst_mps_or_ref subst cr = *) + (* match cr with *) + (* | IsConstr c -> let c' = subst_mps subst c in *) + (* if c' == c then cr *) + (* else IsConstr c' *) + (* | IsGlobal r -> let r' = subst_global_reference subst r in *) + (* if r' == r then cr *) + (* else IsGlobal r' *) + (* in *) + let subst_autohint (subst,(local,name,hintlist as obj)) = let subst_key gr = let (lab'', elab') = subst_global subst gr in let gr' = - (try head_of_constr_reference (fst (head_constr_bound elab')) + (try head_of_constr_reference (head_constr_bound elab') with Tactics.Bound -> lab'') in if gr' == gr then gr else gr' in @@ -687,21 +750,22 @@ let subst_autohint (subst,(local,name,hintlist as obj)) = let k' = Option.smartmap subst_key k in let pat' = Option.smartmap (subst_pattern subst) data.pat in let code' = match data.code with - | Res_pf (c,t) -> + | Res_pf (c,t,ctx) -> let c' = subst_mps subst c in let t' = subst_mps subst t in - if c==c' && t'==t then data.code else Res_pf (c', t') - | ERes_pf (c,t) -> + if c==c' && t'==t then data.code else Res_pf (c', t',ctx) + | ERes_pf (c,t,ctx) -> let c' = subst_mps subst c in let t' = subst_mps subst t in - if c==c' && t'==t then data.code else ERes_pf (c',t') - | Give_exact c -> + if c==c' && t'==t then data.code else ERes_pf (c',t',ctx) + | Give_exact (c,t,ctx) -> let c' = subst_mps subst c in - if c==c' then data.code else Give_exact c' - | Res_pf_THEN_trivial_fail (c,t) -> + let t' = subst_mps subst t in + if c==c' && t'== t then data.code else Give_exact (c',t',ctx) + | Res_pf_THEN_trivial_fail (c,t,ctx) -> let c' = subst_mps subst c in let t' = subst_mps subst t in - if c==c' && t==t' then data.code else Res_pf_THEN_trivial_fail (c',t') + if c==c' && t==t' then data.code else Res_pf_THEN_trivial_fail (c',t',ctx) | Unfold_nth ref -> let ref' = subst_evaluable_reference subst ref in if ref==ref' then data.code else Unfold_nth ref' @@ -765,13 +829,9 @@ let add_resolves env sigma clist local dbnames = Lib.add_anonymous_leaf (inAutoHint (local,dbname, AddHints - (List.flatten (List.map (fun (x, hnf, path, gr) -> - let c = - match gr with - | IsConstr c -> c - | IsGlobal gr -> constr_of_global gr - in - make_resolves env sigma (true,hnf,Flags.is_verbose()) x ~name:path c) clist))))) + (List.flatten (List.map (fun (pri, poly, hnf, path, gr) -> + make_resolves env sigma (true,hnf,Flags.is_verbose()) + pri poly ~name:path gr) clist))))) dbnames let add_unfolds l local dbnames = @@ -808,14 +868,20 @@ let add_trivials env sigma l local dbnames = (fun dbname -> Lib.add_anonymous_leaf ( inAutoHint(local,dbname, - AddHints (List.map (fun (name, c) -> make_trivial env sigma ~name c) l)))) + AddHints (List.map (fun (name, poly, c) -> make_trivial env sigma poly ~name c) l)))) dbnames let (forward_intern_tac, extern_intern_tac) = Hook.make () +type hnf = bool + +let pr_hint_term = function + | IsConstr (c,_) -> pr_constr c + | IsGlobRef gr -> pr_global gr + type hints_entry = - | HintsResolveEntry of (int option * bool * hints_path_atom * global_reference_or_constr) list - | HintsImmediateEntry of (hints_path_atom * global_reference_or_constr) list + | HintsResolveEntry of (int option * polymorphic * hnf * hints_path_atom * hint_term) list + | HintsImmediateEntry of (hints_path_atom * polymorphic * hint_term) list | HintsCutEntry of hints_path | HintsUnfoldEntry of evaluable_global_reference list | HintsTransparencyEntry of evaluable_global_reference list * bool @@ -826,7 +892,7 @@ let h = Id.of_string "H" exception Found of constr * types -let prepare_hint env (sigma,c) = +let prepare_hint check env init (sigma,c) = let sigma = Typeclasses.resolve_typeclasses ~fail:false env sigma in (* We re-abstract over uninstantiated evars. It is actually a bit stupid to generalize over evars since the first @@ -853,15 +919,16 @@ let prepare_hint env (sigma,c) = vars := Id.Set.add id !vars; subst := (evar,mkVar id)::!subst; mkNamedLambda id t (iter (replace_term evar (mkVar id) c)) in - iter c + let c' = iter c in + if check then Evarutil.check_evars (Global.env()) Evd.empty sigma c'; + let diff = Evd.diff sigma init in + IsConstr (c', Evd.get_universe_context_set diff) -let interp_hints = +let interp_hints poly = fun h -> let f c = let evd,c = Constrintern.interp_open_constr Evd.empty (Global.env()) c in - let c = prepare_hint (Global.env()) (evd,c) in - Evarutil.check_evars (Global.env()) Evd.empty evd c; - c in + prepare_hint true (Global.env()) Evd.empty (evd,c) in let fr r = let gr = global_with_alias r in let r' = evaluable_of_global_reference (Global.env()) gr in @@ -871,12 +938,17 @@ let interp_hints = match c with | HintsReference c -> let gr = global_with_alias c in - (PathHints [gr], IsGlobal gr) - | HintsConstr c -> (PathAny, IsConstr (f c)) + (PathHints [gr], poly, IsGlobRef gr) + | HintsConstr c -> + (* if poly then *) + (* errorlabstrm "Hint" (Ppconstr.pr_constr_expr c ++ spc () ++ *) + (* str" is a term and cannot be made a polymorphic hint," ++ *) + (* str" only global references can be polymorphic hints.") *) + (* else *) (PathAny, poly, f c) in - let fres (o, b, c) = - let path, gr = fi c in - (o, b, path, gr) + let fres (pri, b, r) = + let path, poly, gr = fi r in + (pri, poly, b, path, gr) in let fp = Constrintern.intern_constr_pattern (Global.env()) in match h with @@ -888,11 +960,14 @@ let interp_hints = | HintsConstructors lqid -> let constr_hints_of_ind qid = let ind = global_inductive_with_alias qid in + let mib,_ = Global.lookup_inductive ind in Dumpglob.dump_reference (fst (qualid_of_reference qid)) "<>" (string_of_reference qid) "ind"; - List.init (nconstructors ind) (fun i -> let c = (ind,i+1) in - let gr = ConstructRef c in - None, true, PathHints [gr], IsGlobal gr) in - HintsResolveEntry (List.flatten (List.map constr_hints_of_ind lqid)) + List.init (nconstructors ind) + (fun i -> let c = (ind,i+1) in + let gr = ConstructRef c in + None, mib.Declarations.mind_polymorphic, true, + PathHints [gr], IsGlobRef gr) + in HintsResolveEntry (List.flatten (List.map constr_hints_of_ind lqid)) | HintsExtern (pri, patcom, tacexp) -> let pat = Option.map fp patcom in let l = match pat with None -> [] | Some (l, _) -> l in @@ -922,7 +997,7 @@ let pr_autotactic = function | Res_pf (c,clenv) -> (str"apply " ++ pr_constr c) | ERes_pf (c,clenv) -> (str"eapply " ++ pr_constr c) - | Give_exact c -> (str"exact " ++ pr_constr c) + | Give_exact (c,clenv) -> (str"exact " ++ pr_constr c) | Res_pf_THEN_trivial_fail (c,clenv) -> (str"apply " ++ pr_constr c ++ str" ; trivial") | Unfold_nth c -> (str"unfold " ++ pr_evaluable_reference c) @@ -970,11 +1045,11 @@ let pr_hint_term cl = let dbs = current_db () in let valid_dbs = let fn = try - let (hdc,args) = head_constr_bound cl in + let hdc = head_constr_bound cl in let hd = head_of_constr_reference hdc in if occur_existential cl then Hint_db.map_all hd - else Hint_db.map_auto (hd, applist (hdc,args)) + else Hint_db.map_auto (hd, cl) with Bound -> Hint_db.map_none in let fn db = List.map (fun x -> 0, x) (fn db) in @@ -1072,40 +1147,52 @@ let auto_unif_flags = { (* Try unification with the precompiled clause, then use registered Apply *) -let unify_resolve_nodelta (c,clenv) gl = - let clenv' = connect_clenv gl clenv in +let unify_resolve_nodelta poly (c,clenv) gl = + let clenv' = if poly then fst (Clenv.refresh_undefined_univs clenv) else clenv in + let clenv' = connect_clenv gl clenv' in let clenv'' = clenv_unique_resolver ~flags:auto_unif_flags clenv' gl in Clenvtac.clenv_refine false clenv'' gl -let unify_resolve flags (c,clenv) gl = - let clenv' = connect_clenv gl clenv in +let unify_resolve poly flags (c,clenv) gl = + let clenv' = if poly then fst (Clenv.refresh_undefined_univs clenv) else clenv in + let clenv' = connect_clenv gl clenv' in let clenv'' = clenv_unique_resolver ~flags clenv' gl in Clenvtac.clenv_refine false clenv'' gl -let unify_resolve_gen = function - | None -> unify_resolve_nodelta - | Some flags -> unify_resolve flags - +let unify_resolve_gen poly = function + | None -> unify_resolve_nodelta poly + | Some flags -> unify_resolve poly flags + +let exact poly (c,clenv) = + let c' = + if poly then + let evd', subst = Evd.refresh_undefined_universes clenv.evd in + subst_univs_level_constr subst c + else c + in exact_check c' + (* Util *) -let expand_constructor_hints env lems = - List.map_append (fun (sigma,lem) -> +let expand_constructor_hints env sigma lems = + List.map_append (fun (evd,lem) -> match kind_of_term lem with - | Ind ind -> - List.init (nconstructors ind) (fun i -> mkConstruct (ind,i+1)) + | Ind (ind,u) -> + List.init (nconstructors ind) + (fun i -> IsConstr (mkConstructU ((ind,i+1),u), + Univ.ContextSet.empty)) | _ -> - [prepare_hint env (sigma,lem)]) lems + [prepare_hint false env sigma (evd,lem)]) lems (* builds a hint database from a constr signature *) (* typically used with (lid, ltyp) = pf_hyps_types <some goal> *) let add_hint_lemmas eapply lems hint_db gl = - let lems = expand_constructor_hints (pf_env gl) lems in + let lems = expand_constructor_hints (pf_env gl) (project gl) lems in let hintlist' = - List.map_append (pf_apply make_resolves gl (eapply,true,false) None) lems in + List.map_append (pf_apply make_resolves gl (eapply,true,false) None true) lems in Hint_db.add_list hintlist' hint_db -let make_local_hint_db ?ts eapply lems gl = +let make_local_hint_db ts eapply lems gl = let sign = pf_hyps gl in let ts = match ts with | None -> Hint_db.transparent_state (searchtable_map "core") @@ -1115,6 +1202,15 @@ let make_local_hint_db ?ts eapply lems gl = add_hint_lemmas eapply lems (Hint_db.add_list hintlist (Hint_db.empty ts false)) gl +let make_local_hint_db = + if Flags.profile then + let key = Profile.declare_profile "make_local_hint_db" in + Profile.profile4 key make_local_hint_db + else make_local_hint_db + +let make_local_hint_db ?ts eapply lems gl = + make_local_hint_db ts eapply lems gl + (* Serait-ce possible de compiler d'abord la tactique puis de faire la substitution sans passer par bdize dont l'objectif est de préparer un terme pour l'affichage ? (HH) *) @@ -1358,15 +1454,15 @@ and my_find_search_delta db_list local_db hdc concl = in List.map (fun x -> (Some flags,x)) l) (local_db::db_list) -and tac_of_hint dbg db_list local_db concl (flags, ({pat=p; code=t})) = +and tac_of_hint dbg db_list local_db concl (flags, ({pat=p; code=t;poly=poly})) = let tactic = match t with - | Res_pf (c,cl) -> Proofview.V82.tactic (unify_resolve_gen flags (c,cl)) + | Res_pf (c,cl) -> Proofview.V82.tactic (unify_resolve_gen poly flags (c,cl)) | ERes_pf _ -> Proofview.V82.tactic (fun gl -> error "eres_pf") - | Give_exact c -> Proofview.V82.tactic (exact_check c) + | Give_exact (c, cl) -> Proofview.V82.tactic (exact poly (c, cl)) | Res_pf_THEN_trivial_fail (c,cl) -> Tacticals.New.tclTHEN - (Proofview.V82.tactic (unify_resolve_gen flags (c,cl))) + (Proofview.V82.tactic (unify_resolve_gen poly flags (c,cl))) (* With "(debug) trivial", we shouldn't end here, and with "debug auto" we don't display the details of inner trivial *) (trivial_fail_db (no_dbg ()) (not (Option.is_empty flags)) db_list local_db) @@ -1382,7 +1478,7 @@ and tac_of_hint dbg db_list local_db concl (flags, ({pat=p; code=t})) = and trivial_resolve dbg mod_delta db_list local_db cl = try let head = - try let hdconstr,_ = head_constr_bound cl in + try let hdconstr = head_constr_bound cl in Some (head_of_constr_reference hdconstr) with Bound -> None in @@ -1436,7 +1532,7 @@ let h_trivial ?(debug=Off) lems l = gen_trivial ~debug lems l let possible_resolve dbg mod_delta db_list local_db cl = try let head = - try let hdconstr,_ = head_constr_bound cl in + try let hdconstr = head_constr_bound cl in Some (head_of_constr_reference hdconstr) with Bound -> None in @@ -1482,7 +1578,7 @@ let search d n mod_delta db_list local_db = let default_search_depth = ref 5 -let delta_auto ?(debug=Off) mod_delta n lems dbnames = +let delta_auto debug mod_delta n lems dbnames = Proofview.Goal.enter begin fun gl -> let db_list = make_db_list dbnames in let d = mk_auto_dbg debug in @@ -1491,9 +1587,15 @@ let delta_auto ?(debug=Off) mod_delta n lems dbnames = (search d n mod_delta db_list hints) end -let auto ?(debug=Off) n = delta_auto ~debug false n +let delta_auto = + if Flags.profile then + let key = Profile.declare_profile "delta_auto" in + Profile.profile5 key delta_auto + else delta_auto + +let auto ?(debug=Off) n = delta_auto debug false n -let new_auto ?(debug=Off) n = delta_auto ~debug true n +let new_auto ?(debug=Off) n = delta_auto debug true n let default_auto = auto !default_search_depth [] [] |