diff options
-rw-r--r-- | lib/cList.ml | 8 | ||||
-rw-r--r-- | lib/cList.mli | 4 | ||||
-rw-r--r-- | plugins/firstorder/sequent.ml | 2 | ||||
-rw-r--r-- | plugins/firstorder/sequent.mli | 2 | ||||
-rw-r--r-- | plugins/funind/functional_principles_proofs.ml | 2 | ||||
-rw-r--r-- | plugins/funind/recdef.ml | 2 | ||||
-rw-r--r-- | tactics/auto.ml | 1208 | ||||
-rw-r--r-- | tactics/auto.mli | 206 | ||||
-rw-r--r-- | tactics/class_tactics.ml | 7 | ||||
-rw-r--r-- | tactics/class_tactics.mli | 4 | ||||
-rw-r--r-- | tactics/eauto.ml4 | 13 | ||||
-rw-r--r-- | tactics/eauto.mli | 3 | ||||
-rw-r--r-- | tactics/extratactics.ml4 | 6 | ||||
-rw-r--r-- | tactics/g_class.ml4 | 2 | ||||
-rw-r--r-- | tactics/rewrite.ml | 6 | ||||
-rw-r--r-- | tactics/tacintern.ml | 2 | ||||
-rw-r--r-- | tactics/tactics.ml | 30 | ||||
-rw-r--r-- | tactics/tactics.mli | 5 | ||||
-rw-r--r-- | tactics/tactics.mllib | 1 | ||||
-rw-r--r-- | toplevel/classes.ml | 16 | ||||
-rw-r--r-- | toplevel/obligations.ml | 8 | ||||
-rw-r--r-- | toplevel/vernacentries.ml | 14 |
22 files changed, 79 insertions, 1472 deletions
diff --git a/lib/cList.ml b/lib/cList.ml index 93ba0637e..3115826c6 100644 --- a/lib/cList.ml +++ b/lib/cList.ml @@ -61,6 +61,7 @@ sig val except : 'a eq -> 'a -> 'a list -> 'a list val remove : 'a eq -> 'a -> 'a list -> 'a list val remove_first : ('a -> bool) -> 'a list -> 'a list + val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool val sep_last : 'a list -> 'a * 'a list val find_map : ('a -> 'b option) -> 'a list -> 'b @@ -442,6 +443,13 @@ let rec remove_first p = function | b::l -> b::remove_first p l | [] -> raise Not_found +let insert p v l = + let rec insrec = function + | [] -> [v] + | h::tl -> if p v h then v::h::tl else h::insrec tl + in + insrec l + let add_set cmp x l = if mem_f cmp x l then l else x :: l (** List equality up to permutation (but considering multiple occurrences) *) diff --git a/lib/cList.mli b/lib/cList.mli index 01ae83960..aa888679c 100644 --- a/lib/cList.mli +++ b/lib/cList.mli @@ -119,6 +119,10 @@ sig val remove_first : ('a -> bool) -> 'a list -> 'a list (** Remove the first element satisfying a predicate, or raise [Not_found] *) + val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list + (** Insert at the (first) position so that if the list is ordered wrt to the + total order given as argument, the order is preserved *) + val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool val sep_last : 'a list -> 'a * 'a list diff --git a/plugins/firstorder/sequent.ml b/plugins/firstorder/sequent.ml index 6d4d8792f..f0afa2ec5 100644 --- a/plugins/firstorder/sequent.ml +++ b/plugins/firstorder/sequent.ml @@ -204,7 +204,7 @@ let extend_with_ref_list l seq gl = (add_formula Hyp gr typ seq gl,gl) in List.fold_right f l (seq,gl) -open Auto +open Hints let extend_with_auto_hints l seq gl= let seqref=ref seq in diff --git a/plugins/firstorder/sequent.mli b/plugins/firstorder/sequent.mli index 40aa169ab..6462fe9d3 100644 --- a/plugins/firstorder/sequent.mli +++ b/plugins/firstorder/sequent.mli @@ -56,7 +56,7 @@ val empty_seq : int -> t val extend_with_ref_list : global_reference list -> t -> Proof_type.goal sigma -> t * Proof_type.goal sigma -val extend_with_auto_hints : Auto.hint_db_name list -> +val extend_with_auto_hints : Hints.hint_db_name list -> t -> Proof_type.goal sigma -> t * Proof_type.goal sigma val print_cmap: global_reference list CM.t -> Pp.std_ppcmds diff --git a/plugins/funind/functional_principles_proofs.ml b/plugins/funind/functional_principles_proofs.ml index 700f67a74..cd3f1a5d4 100644 --- a/plugins/funind/functional_principles_proofs.ml +++ b/plugins/funind/functional_principles_proofs.ml @@ -1454,7 +1454,7 @@ let new_prove_with_tcc is_mes acc_inv hrec tcc_hyps eqs : tactic = Eauto.eauto_with_bases (true,5) [Evd.empty,Lazy.force refl_equal] - [Auto.Hint_db.empty empty_transparent_state false] + [Hints.Hint_db.empty empty_transparent_state false] ) ) ) diff --git a/plugins/funind/recdef.ml b/plugins/funind/recdef.ml index 9f52258ed..8014abf65 100644 --- a/plugins/funind/recdef.ml +++ b/plugins/funind/recdef.ml @@ -1312,7 +1312,7 @@ let open_new_goal build_proof ctx using_lemmas ref_ goal_name (gls_type,decompos Eauto.eauto_with_bases (true,5) [Evd.empty,Lazy.force refl_equal] - [Auto.Hint_db.empty empty_transparent_state false] + [Hints.Hint_db.empty empty_transparent_state false] ] ) ) diff --git a/tactics/auto.ml b/tactics/auto.ml index e06c2b7e0..056b781e1 100644 --- a/tactics/auto.ml +++ b/tactics/auto.ml @@ -6,1153 +6,24 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) +(* +*) open Pp -open Errors open Util +open Errors open Names -open Namegen -open Term open Vars open Termops -open Inductiveops open Environ -open Evd -open Typing -open Pattern -open Patternops open Tacmach -open Pfedit open Genredexpr -open Tacred open Tactics open Tacticals open Clenv -open Libnames -open Globnames -open Smartlocate -open Libobject -open Printer 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 '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 *) - -type hints_path_atom = - | PathHints of global_reference list - | PathAny - -type hints_path = - | PathAtom of hints_path_atom - | PathStar of hints_path - | PathSeq of hints_path * hints_path - | PathOr of hints_path * 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 = (constr * clausenv) 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 -| PathAny, PathAny -> true -| (PathHints _ | PathAny), _ -> false - -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 -| 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 *) -| (Res_pf _ | ERes_pf _ | Give_exact _ | Res_pf_THEN_trivial_fail _ - | Unfold_nth _ | Extern _), _ -> false - -let eq_gen_auto_tactic t1 t2 = - Int.equal t1.pri t2.pri && - Option.equal constr_pattern_eq t1.pat t2.pat && - eq_hints_path_atom t1.name t2.name && - eq_auto_tactic t1.code t2.code - -let pri_order_int (id1, {pri=pri1}) (id2, {pri=pri2}) = - let d = pri1 - pri2 in - if Int.equal d 0 then id2 - id1 - else d - -let pri_order t1 t2 = pri_order_int t1 t2 <= 0 - -let insert v l = - let rec insrec = function - | [] -> [v] - | h::tl -> if pri_order v h then v::h::tl else h::(insrec tl) - in - insrec l - -(* Nov 98 -- Papageno *) -(* Les Hints sont ré-organisés en plusieurs databases. - - La table impérative "searchtable", de type "hint_db_table", - associe une database (hint_db) à chaque nom. - - Une hint_db est une table d'association fonctionelle constr -> search_entry - Le constr correspond à la constante de tête de la conclusion. - - Une search_entry est un triplet comprenant : - - la liste des tactiques qui n'ont pas de pattern associé - - la liste des tactiques qui ont un pattern - - un discrimination net borné (Btermdn.t) constitué de tous les - patterns de la seconde liste de tactiques *) - -type stored_data = int * pri_auto_tactic - (* First component is the index of insertion in the table, to keep most recent first semantics. *) - -module Bounded_net = Btermdn.Make(struct - type t = stored_data - let compare = pri_order_int - end) - -type search_entry = stored_data list * stored_data list * Bounded_net.t * bool array list - - -let empty_se = ([],[],Bounded_net.create (),[]) - -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,_) -> - Term.eq_constr cstr cstr1 - | ERes_pf (cstr,_),ERes_pf (cstr1,_) -> - Term.eq_constr cstr cstr1 - | Give_exact (cstr,_),Give_exact (cstr1,_) -> - Term.eq_constr cstr cstr1 - | Res_pf_THEN_trivial_fail (cstr,_) - ,Res_pf_THEN_trivial_fail (cstr1,_) -> - Term.eq_constr cstr cstr1 - | _,_ -> false - else - false - -let add_tac pat t st (l,l',dn,m) = - match pat with - | None -> - if not (List.exists (eq_pri_auto_tactic t) l) then (insert t l, l', dn, m) - else (l, l', dn, m) - | Some pat -> - if not (List.exists (eq_pri_auto_tactic t) l') - then (l, insert t l', Bounded_net.add st dn (pat,t), m) else (l, l', dn, m) - -let rebuild_dn st ((l,l',dn,m) : search_entry) = - let dn' = - List.fold_left - (fun dn (id, t) -> Bounded_net.add (Some st) dn (Option.get t.pat, (id, t))) - (Bounded_net.create ()) l' - in - (l, l', dn', m) - -let lookup_tacs concl st (l,l',dn) = - let l' = Bounded_net.lookup st dn concl in - let sl' = List.stable_sort pri_order_int l' in - List.merge pri_order_int l sl' - -module Constr_map = Map.Make(RefOrdered) - -let is_transparent_gr (ids, csts) = function - | VarRef id -> Id.Pred.mem id ids - | ConstRef cst -> Cpred.mem cst csts - | IndRef _ | ConstructRef _ -> false - -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 - if Array.length args > n then - mkApp (mkProj (Projection.make p false, args.(n)), - Array.sub args (n+1) (Array.length args - (n + 1))) - else c - | None -> c) - | _ -> c) - | _ -> c - -let instantiate_hint p = - let mk_clenv c cty ctx = - let env = Global.env () in - let sigma = Evd.merge_context_set univ_flexible (Evd.from_env env) ctx in - let cl = mk_clenv_from_env (Global.env()) sigma None (c,cty) in - {cl with templval = - { cl.templval with rebus = strip_params env cl.templval.rebus }; - env = empty_env} - in - let code = match p.code with - | 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 { 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 -| PathAny, PathAny -> true -| _ -> false - -let rec hints_path_eq h1 h2 = match h1, h2 with -| PathAtom h1, PathAtom h2 -> hints_path_atom_eq h1 h2 -| PathStar h1, PathStar h2 -> hints_path_eq h1 h2 -| PathSeq (l1, r1), PathSeq (l2, r2) -> - hints_path_eq l1 l2 && hints_path_eq r1 r2 -| PathOr (l1, r1), PathOr (l2, r2) -> - hints_path_eq l1 l2 && hints_path_eq r1 r2 -| PathEmpty, PathEmpty -> true -| PathEpsilon, PathEpsilon -> true -| _ -> false - -let path_matches hp hints = - let rec aux hp hints k = - match hp, hints with - | PathAtom _, [] -> false - | PathAtom PathAny, (_ :: hints') -> k hints' - | PathAtom p, (h :: hints') -> - if hints_path_atom_eq p h then k hints' else false - | PathStar hp', hints -> - k hints || aux hp' hints (fun hints' -> aux hp hints' k) - | PathSeq (hp, hp'), hints -> - aux hp hints (fun hints' -> aux hp' hints' k) - | PathOr (hp, hp'), hints -> - aux hp hints k || aux hp' hints k - | PathEmpty, _ -> false - | PathEpsilon, hints -> k hints - in aux hp hints (fun hints' -> true) - -let rec matches_epsilon = function - | PathAtom _ -> false - | PathStar _ -> true - | PathSeq (p, p') -> matches_epsilon p && matches_epsilon p' - | PathOr (p, p') -> matches_epsilon p || matches_epsilon p' - | PathEmpty -> false - | PathEpsilon -> true - -let rec is_empty = function - | PathAtom _ -> false - | PathStar _ -> false - | PathSeq (p, p') -> is_empty p || is_empty p' - | PathOr (p, p') -> matches_epsilon p && matches_epsilon p' - | PathEmpty -> true - | PathEpsilon -> false - -let rec path_derivate hp hint = - let rec derivate_atoms hints hints' = - match hints, hints' with - | gr :: grs, gr' :: grs' when eq_gr gr gr' -> derivate_atoms grs grs' - | [], [] -> PathEpsilon - | [], hints -> PathEmpty - | grs, [] -> PathAtom (PathHints grs) - | _, _ -> PathEmpty - in - match hp with - | PathAtom PathAny -> PathEpsilon - | PathAtom (PathHints grs) -> - (match grs, hint with - | h :: hints, PathAny -> PathEmpty - | hints, PathHints hints' -> derivate_atoms hints hints' - | _, _ -> assert false) - | PathStar p -> if path_matches p [hint] then hp else PathEpsilon - | PathSeq (hp, hp') -> - let hpder = path_derivate hp hint in - if matches_epsilon hp then - PathOr (PathSeq (hpder, hp'), path_derivate hp' hint) - else if is_empty hpder then PathEmpty - else PathSeq (hpder, hp') - | PathOr (hp, hp') -> - PathOr (path_derivate hp hint, path_derivate hp' hint) - | PathEmpty -> PathEmpty - | PathEpsilon -> PathEmpty - -let rec normalize_path h = - match h with - | PathStar PathEpsilon -> PathEpsilon - | PathSeq (PathEmpty, _) | PathSeq (_, PathEmpty) -> PathEmpty - | PathSeq (PathEpsilon, p) | PathSeq (p, PathEpsilon) -> normalize_path p - | PathOr (PathEmpty, p) | PathOr (p, PathEmpty) -> normalize_path p - | PathOr (p, q) -> - let p', q' = normalize_path p, normalize_path q in - if hints_path_eq p p' && hints_path_eq q q' then h - else normalize_path (PathOr (p', q')) - | PathSeq (p, q) -> - let p', q' = normalize_path p, normalize_path q in - if hints_path_eq p p' && hints_path_eq q q' then h - else normalize_path (PathSeq (p', q')) - | _ -> h - -let path_derivate hp hint = normalize_path (path_derivate hp hint) - -let rec pp_hints_path = function - | PathAtom (PathAny) -> str"." - | PathAtom (PathHints grs) -> pr_sequence pr_global grs - | PathStar p -> str "(" ++ pp_hints_path p ++ str")*" - | PathSeq (p, p') -> pp_hints_path p ++ str" ; " ++ pp_hints_path p' - | PathOr (p, p') -> - str "(" ++ pp_hints_path p ++ spc () ++ str"|" ++ spc () ++ pp_hints_path p' ++ str ")" - | PathEmpty -> str"Ø" - | PathEpsilon -> str"ε" - -let subst_path_atom subst p = - match p with - | PathAny -> p - | PathHints grs -> - let gr' gr = fst (subst_global subst gr) in - let grs' = List.smartmap gr' grs in - if grs' == grs then p else PathHints grs' - -let rec subst_hints_path subst hp = - match hp with - | PathAtom p -> - let p' = subst_path_atom subst p in - if p' == p then hp else PathAtom p' - | PathStar p -> let p' = subst_hints_path subst p in - if p' == p then hp else PathStar p' - | PathSeq (p, q) -> - let p' = subst_hints_path subst p in - let q' = subst_hints_path subst q in - if p' == p && q' == q then hp else PathSeq (p', q') - | PathOr (p, q) -> - let p' = subst_hints_path subst p in - let q' = subst_hints_path subst q in - if p' == p && q' == q then hp else PathOr (p', q') - | _ -> hp - -module Hint_db = struct - - type t = { - hintdb_state : Names.transparent_state; - hintdb_cut : hints_path; - hintdb_unfolds : Id.Set.t * Cset.t; - mutable hintdb_max_id : int; - use_dn : bool; - hintdb_map : search_entry Constr_map.t; - (* A list of unindexed entries starting with an unfoldable constant - or with no associated pattern. *) - hintdb_nopat : (global_reference option * stored_data) list - } - - let next_hint_id t = - let h = t.hintdb_max_id in t.hintdb_max_id <- succ t.hintdb_max_id; h - - let empty st use_dn = { hintdb_state = st; - hintdb_cut = PathEmpty; - hintdb_unfolds = (Id.Set.empty, Cset.empty); - hintdb_max_id = 0; - use_dn = use_dn; - hintdb_map = Constr_map.empty; - hintdb_nopat = [] } - - let find key db = - try Constr_map.find key db.hintdb_map - with Not_found -> empty_se - - let realize_tac (id,tac) = tac - - let matches_mode args mode = - Array.length args == Array.length mode && - Array.for_all2 (fun arg m -> not (m && occur_existential arg)) args mode - - let matches_modes args modes = - if List.is_empty modes then true - else List.exists (matches_mode args) modes - - let map_none db = - 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 realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat @ l) l') - - (** Precondition: concl has no existentials *) - let map_auto (k,args) concl db = - let (l,l',dn,m) = find k db in - let st = if db.use_dn then (Some db.hintdb_state) else None in - let l' = lookup_tacs concl st (l,l',dn) in - List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat) l') - - let map_existential (k,args) concl db = - let (l,l',_,m) = find k db in - if matches_modes args m then - List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat @ l) l') - else List.map realize_tac (List.map snd db.hintdb_nopat) - - (* [c] contains an existential *) - let map_eauto (k,args) concl db = - let (l,l',dn,m) = find k db in - if matches_modes args m then - let st = if db.use_dn then Some db.hintdb_state else None in - let l' = lookup_tacs concl st (l,l',dn) in - List.map realize_tac (Sort.merge pri_order (List.map snd db.hintdb_nopat) l') - else List.map realize_tac (List.map snd db.hintdb_nopat) - - let is_exact = function - | Give_exact _ -> true - | _ -> false - - let is_unfold = function - | Unfold_nth _ -> true - | _ -> false - - let addkv gr id v db = - let idv = id, v in - let k = match gr with - | Some gr -> if db.use_dn && is_transparent_gr db.hintdb_state gr && - is_unfold v.code then None else Some gr - | None -> None - in - let dnst = if db.use_dn then Some db.hintdb_state else None in - let pat = if not db.use_dn && is_exact v.code then None else v.pat in - match k with - | None -> - (** 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 -> - let oval = find gr db in - { db with hintdb_map = Constr_map.add gr (add_tac pat idv dnst oval) db.hintdb_map } - - let rebuild_db st' db = - let db' = - { db with hintdb_map = Constr_map.map (rebuild_dn st') db.hintdb_map; - hintdb_state = st'; hintdb_nopat = [] } - in - List.fold_left (fun db (gr,(id,v)) -> addkv gr id v db) db' db.hintdb_nopat - - let add_one (k, v) db = - let v = instantiate_hint v in - let st',db,rebuild = - match v.code with - | Unfold_nth egr -> - let addunf (ids,csts) (ids',csts') = - match egr with - | EvalVarRef id -> (Id.Pred.add id ids, csts), (Id.Set.add id ids', csts') - | EvalConstRef cst -> (ids, Cpred.add cst csts), (ids', Cset.add cst csts') - in - let state, unfs = addunf db.hintdb_state db.hintdb_unfolds in - state, { db with hintdb_unfolds = unfs }, true - | _ -> db.hintdb_state, db, false - in - let db = if db.use_dn && rebuild then rebuild_db st' db else db - in addkv k (next_hint_id db) v db - - let add_list l db = List.fold_left (fun db k -> add_one k db) db l - - let remove_sdl p sdl = List.smartfilter p sdl - let remove_he st p (sl1, sl2, dn, m as he) = - let sl1' = remove_sdl p sl1 and sl2' = remove_sdl p sl2 in - if sl1' == sl1 && sl2' == sl2 then he - else rebuild_dn st (sl1', sl2', dn, m) - - let remove_list grs db = - let filter (_, h) = - match h.name with PathHints [gr] -> not (List.mem_f eq_gr gr grs) | _ -> true in - let hintmap = Constr_map.map (remove_he db.hintdb_state filter) db.hintdb_map in - let hintnopat = List.smartfilter (fun (ge, sd) -> filter sd) db.hintdb_nopat in - { db with hintdb_map = hintmap; hintdb_nopat = hintnopat } - - let remove_one gr db = remove_list [gr] db - - let iter f db = - f None [] (List.map (fun x -> realize_tac (snd x)) db.hintdb_nopat); - Constr_map.iter (fun k (l,l',_,m) -> f (Some k) m (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 - Constr_map.fold (fun k (l,l',_,m) -> f (Some k) m (List.map snd (l@l'))) db.hintdb_map accu - - let transparent_state db = db.hintdb_state - - let set_transparent_state db st = - if db.use_dn then rebuild_db st db - else { db with hintdb_state = st } - - let add_cut path db = - { db with hintdb_cut = normalize_path (PathOr (db.hintdb_cut, path)) } - - let add_mode gr m db = - let (l,l',dn,ms) = find gr db in - { db with hintdb_map = Constr_map.add gr (l,l',dn,m :: ms) db.hintdb_map } - - let cut db = db.hintdb_cut - - let unfolds db = db.hintdb_unfolds - - let use_dn db = db.use_dn - -end - -module Hintdbmap = String.Map - -type hint_db = Hint_db.t - -type hint_db_table = hint_db Hintdbmap.t ref - -type hint_db_name = string - -(** Initially created hint databases, for typeclasses and rewrite *) - -let typeclasses_db = "typeclass_instances" -let rewrite_db = "rewrite" - -let auto_init_db = - Hintdbmap.add typeclasses_db (Hint_db.empty full_transparent_state true) - (Hintdbmap.add rewrite_db (Hint_db.empty cst_full_transparent_state true) - Hintdbmap.empty) - -let searchtable : hint_db_table = ref auto_init_db - -let searchtable_map name = - Hintdbmap.find name !searchtable -let searchtable_add (name,db) = - searchtable := Hintdbmap.add name db !searchtable -let current_db_names () = Hintdbmap.domain !searchtable -let current_db () = Hintdbmap.bindings !searchtable - -(**************************************************************************) -(* Definition of the summary *) -(**************************************************************************) - -let auto_init : (unit -> unit) ref = ref (fun () -> ()) -let add_auto_init f = - let init = !auto_init in - auto_init := (fun () -> init (); f ()) - -let init () = searchtable := auto_init_db; !auto_init () -let freeze _ = !searchtable -let unfreeze fs = searchtable := fs - -let _ = Summary.declare_summary "search" - { Summary.freeze_function = freeze; - Summary.unfreeze_function = unfreeze; - Summary.init_function = init } - - -(**************************************************************************) -(* Auxiliary functions to prepare AUTOHINT objects *) -(**************************************************************************) - -let rec nb_hyp c = match kind_of_term c with - | Prod(_,_,c2) -> if noccurn 1 c2 then 1+(nb_hyp c2) else nb_hyp c2 - | _ -> 0 - -(* adding and removing tactics in the search table *) - -let try_head_pattern c = - try head_pattern_bound c - with BoundPattern -> error "Bound head variable." - -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" - | _ -> - let pat = snd (Patternops.pattern_of_constr env sigma cty) in - let hd = - try head_pattern_bound pat - with BoundPattern -> failwith "make_exact_entry" - in - (Some hd, - { pri = (match pri with None -> 0 | Some p -> p); - poly = poly; - pat = Some pat; - name = name; - code = Give_exact (c, cty, ctx) }) - -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 sigma' = Evd.merge_context_set univ_flexible sigma ctx in - let ce = mk_clenv_from_env env sigma' None (c,cty) in - let c' = clenv_type (* ~reduce:false *) ce in - let pat = snd (Patternops.pattern_of_constr env ce.evd c') in - let hd = - try head_pattern_bound pat - with BoundPattern -> failwith "make_apply_entry" in - let nmiss = List.length (clenv_missing ce) in - 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,ctx) }) - else begin - if not eapply then failwith "make_apply_entry"; - if verbose then - msg_warning (str "the hint: eapply " ++ pr_lconstr c ++ - 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,ctx) }) - end - | _ -> failwith "make_apply_entry" - -(* flags is (e,h,v) with e=true if eapply and h=true if hnf and v=true if verbose - c is a constr - cty is the type of constr *) - -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, ctx)) with Failure _ -> None in - let ents = List.map_filter try_apply - [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" - (pr_lconstr c ++ spc() ++ - (if pi1 flags then str"cannot be used as a hint." - else str "can be used as a hint only for eauto.")); - ents - -(* 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 false - ~name:(PathHints [VarRef hname]) - (mkVar hname, htyp, Univ.ContextSet.empty)] - with - | Failure _ -> [] - | e when Logic.catchable_exception e -> anomaly (Pp.str "make_resolve_hyp") - -(* REM : in most cases hintname = id *) -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 }) - -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_mode ref m = - let ty = Global.type_of_global_unsafe ref in - let ctx, t = decompose_prod ty in - let n = List.length ctx in - let m' = Array.of_list m in - if not (n == Array.length m') then - errorlabstrm "Hint" - (pr_global ref ++ str" has " ++ int n ++ - str" arguments while the mode declares " ++ int (Array.length m')) - else m' - -let make_trivial env sigma poly ?(name=PathAny) r = - let c,ctx = fresh_global_or_constr env sigma poly r in - let sigma = Evd.merge_context_set univ_flexible sigma ctx in - let t = hnf_constr env sigma (type_of env sigma c) in - let hd = head_of_constr_reference (head_constr t) in - let ce = mk_clenv_from_env env sigma None (c,t) in - (Some hd, { pri=1; - poly = poly; - pat = Some (snd (Patternops.pattern_of_constr env ce.evd (clenv_type ce))); - name = name; - code=Res_pf_THEN_trivial_fail(c,t,ctx) }) - -open Vernacexpr - -(**************************************************************************) -(* declaration of the AUTOHINT library object *) -(**************************************************************************) - -(* If the database does not exist, it is created *) -(* TODO: should a warning be printed in this case ?? *) - -let get_db dbname = - try searchtable_map dbname - with Not_found -> Hint_db.empty empty_transparent_state false - -let add_hint dbname hintlist = - let db = get_db dbname in - let db' = Hint_db.add_list hintlist db in - searchtable_add (dbname,db') - -let add_transparency dbname grs b = - let db = get_db dbname in - let st = Hint_db.transparent_state db in - let st' = - List.fold_left (fun (ids, csts) gr -> - match gr with - | EvalConstRef c -> (ids, (if b then Cpred.add else Cpred.remove) c csts) - | EvalVarRef v -> (if b then Id.Pred.add else Id.Pred.remove) v ids, csts) - st grs - in searchtable_add (dbname, Hint_db.set_transparent_state db st') - -let remove_hint dbname grs = - let db = get_db dbname in - let db' = Hint_db.remove_list grs db in - searchtable_add (dbname, db') - -type hint_action = - | CreateDB of bool * transparent_state - | AddTransparency of evaluable_global_reference list * bool - | AddHints of hint_entry list - | RemoveHints of global_reference list - | AddCut of hints_path - | AddMode of global_reference * bool array - -let add_cut dbname path = - let db = get_db dbname in - let db' = Hint_db.add_cut path db in - searchtable_add (dbname, db') - -let add_mode dbname l m = - let db = get_db dbname in - let db' = Hint_db.add_mode l m db in - searchtable_add (dbname, db') - -type hint_obj = bool * string * hint_action (* locality, name, action *) - -let cache_autohint (_,(local,name,hints)) = - match hints with - | CreateDB (b, st) -> searchtable_add (name, Hint_db.empty st b) - | AddTransparency (grs, b) -> add_transparency name grs b - | AddHints hints -> add_hint name hints - | RemoveHints grs -> remove_hint name grs - | AddCut path -> add_cut name path - | AddMode (l, m) -> add_mode name l m - -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 (head_constr_bound elab') - with Tactics.Bound -> lab'') - in if gr' == gr then gr else gr' - in - let subst_hint (k,data as hint) = - 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,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',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',ctx) - | Give_exact (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 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',ctx) - | Unfold_nth ref -> - let ref' = subst_evaluable_reference subst ref in - if ref==ref' then data.code else Unfold_nth ref' - | Extern tac -> - let tac' = Tacsubst.subst_tactic subst tac in - if tac==tac' then data.code else Extern tac' - in - let name' = subst_path_atom subst data.name in - let data' = - if data.pat==pat' && data.name == name' && data.code==code' then data - else { data with pat = pat'; name = name'; code = code' } - in - if k' == k && data' == data then hint else (k',data') - in - match hintlist with - | CreateDB _ -> obj - | AddTransparency (grs, b) -> - let grs' = List.smartmap (subst_evaluable_reference subst) grs in - if grs==grs' then obj else (local, name, AddTransparency (grs', b)) - | AddHints hintlist -> - let hintlist' = List.smartmap subst_hint hintlist in - if hintlist' == hintlist then obj else - (local,name,AddHints hintlist') - | RemoveHints grs -> - let grs' = List.smartmap (subst_global_reference subst) grs in - if grs==grs' then obj else (local, name, RemoveHints grs') - | AddCut path -> - let path' = subst_hints_path subst path in - if path' == path then obj else (local, name, AddCut path') - | AddMode (l,m) -> - let l' = subst_global_reference subst l in - (local, name, AddMode (l', m)) - -let classify_autohint ((local,name,hintlist) as obj) = - match hintlist with - | AddHints [] -> Dispose - | _ -> if local then Dispose else Substitute obj - -let inAutoHint : hint_obj -> obj = - declare_object {(default_object "AUTOHINT") with - cache_function = cache_autohint; - load_function = (fun _ -> cache_autohint); - subst_function = subst_autohint; - classify_function = classify_autohint; } - -let create_hint_db l n st b = - Lib.add_anonymous_leaf (inAutoHint (l,n,CreateDB (b, st))) - -let remove_hints local dbnames grs = - let dbnames = if List.is_empty dbnames then ["core"] else dbnames in - List.iter - (fun dbname -> - Lib.add_anonymous_leaf (inAutoHint(local, dbname, RemoveHints grs))) - dbnames - -open Misctypes - -(**************************************************************************) -(* The "Hint" vernacular command *) -(**************************************************************************) -let add_resolves env sigma clist local dbnames = - List.iter - (fun dbname -> - Lib.add_anonymous_leaf - (inAutoHint - (local,dbname, AddHints - (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 = - List.iter - (fun dbname -> Lib.add_anonymous_leaf - (inAutoHint (local,dbname, AddHints (List.map make_unfold l)))) - dbnames - -let add_cuts l local dbnames = - List.iter - (fun dbname -> Lib.add_anonymous_leaf - (inAutoHint (local,dbname, AddCut l))) - dbnames - -let add_mode l m local dbnames = - List.iter - (fun dbname -> Lib.add_anonymous_leaf - (let m' = make_mode l m in - (inAutoHint (local,dbname, AddMode (l,m'))))) - dbnames - -let add_transparency l b local dbnames = - List.iter - (fun dbname -> Lib.add_anonymous_leaf - (inAutoHint (local,dbname, AddTransparency (l, b)))) - dbnames - -let add_extern pri pat tacast local dbname = - let pat = match pat with - | None -> None - | Some (_, pat) -> Some pat - in - let hint = local, dbname, AddHints [make_extern pri pat tacast] in - Lib.add_anonymous_leaf (inAutoHint hint) - -let add_externs pri pat tacast local dbnames = - List.iter (add_extern pri pat tacast local) dbnames - -let add_trivials env sigma l local dbnames = - List.iter - (fun dbname -> - Lib.add_anonymous_leaf ( - inAutoHint(local,dbname, - 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 - -type hints_entry = - | 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 - | HintsModeEntry of global_reference * bool list - | HintsExternEntry of - int * (patvar list * constr_pattern) option * glob_tactic_expr - -let default_prepare_hint_ident = Id.of_string "H" - -exception Found of constr * types - -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 - thing make_resolves will do is to re-instantiate the products *) - let c = drop_extra_implicit_args (Evarutil.nf_evar sigma c) in - let vars = ref (collect_vars c) in - let subst = ref [] in - let rec find_next_evar c = match kind_of_term c with - | Evar (evk,args as ev) -> - (* We skip the test whether args is the identity or not *) - let t = Evarutil.nf_evar sigma (existential_type sigma ev) in - let t = List.fold_right (fun (e,id) c -> replace_term e id c) !subst t in - if not (Int.Set.is_empty (free_rels t)) then - error "Hints with holes dependent on a bound variable not supported."; - if occur_existential t then - (* Not clever enough to construct dependency graph of evars *) - error "Not clever enough to deal with evars dependent in other evars."; - raise (Found (c,t)) - | _ -> iter_constr find_next_evar c in - let rec iter c = - try find_next_evar c; c - with Found (evar,t) -> - let id = next_ident_away_from default_prepare_hint_ident (fun id -> Id.Set.mem id !vars) in - vars := Id.Set.add id !vars; - subst := (evar,mkVar id)::!subst; - mkNamedLambda id t (iter (replace_term evar (mkVar id) c)) in - 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.universe_context_set diff) - -let interp_hints poly = - fun h -> - let f c = - let evd,c = Constrintern.interp_open_constr (Global.env()) Evd.empty c in - prepare_hint true (Global.env()) Evd.empty (evd,c) in - let fref r = - let gr = global_with_alias r in - Dumpglob.add_glob (loc_of_reference r) gr; - gr in - let fr r = - evaluable_of_global_reference (Global.env()) (fref r) - in - let fi c = - match c with - | HintsReference c -> - let gr = global_with_alias c in - (PathHints [gr], poly, IsGlobRef gr) - | HintsConstr c -> (PathAny, poly, f c) - in - 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 - | HintsResolve lhints -> HintsResolveEntry (List.map fres lhints) - | HintsImmediate lhints -> HintsImmediateEntry (List.map fi lhints) - | HintsUnfold lhints -> HintsUnfoldEntry (List.map fr lhints) - | HintsTransparency (lhints, b) -> - HintsTransparencyEntry (List.map fr lhints, b) - | HintsMode (r, l) -> HintsModeEntry (fref r, l) - | 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, 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 - let tacexp = Hook.get forward_intern_tac l tacexp in - HintsExternEntry (pri, pat, tacexp) - -let add_hints local dbnames0 h = - if String.List.mem "nocore" dbnames0 then - error "The hint database \"nocore\" is meant to stay empty."; - let dbnames = if List.is_empty dbnames0 then ["core"] else dbnames0 in - let env = Global.env() and sigma = Evd.empty in - match h with - | HintsResolveEntry lhints -> add_resolves env sigma lhints local dbnames - | HintsImmediateEntry lhints -> add_trivials env sigma lhints local dbnames - | HintsCutEntry lhints -> add_cuts lhints local dbnames - | HintsModeEntry (l,m) -> add_mode l m local dbnames - | HintsUnfoldEntry lhints -> add_unfolds lhints local dbnames - | HintsTransparencyEntry (lhints, b) -> - add_transparency lhints b local dbnames - | HintsExternEntry (pri, pat, tacexp) -> - add_externs pri pat tacexp local dbnames - -(**************************************************************************) -(* Functions for printing the hints *) -(**************************************************************************) - -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,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) - | Extern tac -> - let env = - try - let (_, env) = Pfedit.get_current_goal_context () in - env - with e when Errors.noncritical e -> Global.env () - in - (str "(*external*) " ++ Pptactic.pr_glob_tactic env tac) - -let pr_hint (id, v) = - (pr_autotactic v.code ++ str"(level " ++ int v.pri ++ str", id " ++ int id ++ str ")" ++ spc ()) - -let pr_hint_list hintlist = - (str " " ++ hov 0 (prlist pr_hint hintlist) ++ fnl ()) - -let pr_hints_db (name,db,hintlist) = - (str "In the database " ++ str name ++ str ":" ++ - if List.is_empty hintlist then (str " nothing" ++ fnl ()) - else (fnl () ++ pr_hint_list hintlist)) - -(* Print all hints associated to head c in any database *) -let pr_hint_list_for_head c = - let dbs = current_db () in - let validate (name, db) = - let hints = List.map (fun v -> 0, v) (Hint_db.map_all c db) in - (name, db, hints) - in - let valid_dbs = List.map validate dbs in - if List.is_empty valid_dbs then - (str "No hint declared for :" ++ pr_global c) - else - hov 0 - (str"For " ++ pr_global c ++ str" -> " ++ fnl () ++ - hov 0 (prlist pr_hints_db valid_dbs)) - -let pr_hint_ref ref = pr_hint_list_for_head ref - -(* Print all hints associated to head id in any database *) - -let pr_hint_term cl = - try - let dbs = current_db () in - let valid_dbs = - let fn = try - let hdc = decompose_app_bound cl in - if occur_existential cl then - Hint_db.map_existential hdc cl - else Hint_db.map_auto hdc cl - with Bound -> Hint_db.map_none - in - let fn db = List.map (fun x -> 0, x) (fn db) in - List.map (fun (name, db) -> (name, db, fn db)) dbs - in - if List.is_empty valid_dbs then - (str "No hint applicable for current goal") - else - (str "Applicable Hints :" ++ fnl () ++ - hov 0 (prlist pr_hints_db valid_dbs)) - with Match_failure _ | Failure _ -> - (str "No hint applicable for current goal") - -let error_no_such_hint_database x = - error ("No such Hint database: "^x^".") - -(* print all hints that apply to the concl of the current goal *) -let pr_applicable_hint () = - let pts = get_pftreestate () in - let glss = Proof.V82.subgoals pts in - match glss.Evd.it with - | [] -> Errors.error "No focused goal." - | g::_ -> - let gl = { Evd.it = g; sigma = glss.Evd.sigma; } in - pr_hint_term (pf_concl gl) - -(* displays the whole hint database db *) -let pr_hint_db db = - let pr_mode = prvect_with_sep spc (fun x -> if x then str"+" else str"-") in - let pr_modes l = - if List.is_empty l then mt () - else str" (modes " ++ prlist_with_sep pr_comma pr_mode l ++ str")" - in - let content = - let fold head modes hintlist accu = - let goal_descr = match head with - | None -> str "For any goal" - | Some head -> str "For " ++ pr_global head ++ pr_modes modes - in - let hints = pr_hint_list (List.map (fun x -> (0, x)) hintlist) in - let hint_descr = hov 0 (goal_descr ++ str " -> " ++ hints) in - accu ++ hint_descr - in - Hint_db.fold fold db (mt ()) - in - let (ids, csts) = Hint_db.transparent_state db in - hov 0 - ((if Hint_db.use_dn db then str"Discriminated database" - else str"Non-discriminated database")) ++ fnl () ++ - hov 2 (str"Unfoldable variable definitions: " ++ pr_idpred ids) ++ fnl () ++ - hov 2 (str"Unfoldable constant definitions: " ++ pr_cpred csts) ++ fnl () ++ - hov 2 (str"Cut: " ++ pp_hints_path (Hint_db.cut db)) ++ fnl () ++ - content - -let pr_hint_db_by_name dbname = - try - let db = searchtable_map dbname in pr_hint_db db - with Not_found -> - error_no_such_hint_database dbname - -(* displays all the hints of all databases *) -let pr_searchtable () = - let fold name db accu = - accu ++ str "In the database " ++ str name ++ str ":" ++ fnl () ++ - pr_hint_db db ++ fnl () - in - Hintdbmap.fold fold !searchtable (mt ()) +open Hints (**************************************************************************) (* Automatic tactics *) @@ -1233,44 +104,6 @@ let exact poly (c,clenv) = (* Util *) -let expand_constructor_hints env sigma lems = - List.map_append (fun (evd,lem) -> - match kind_of_term lem with - | Ind (ind,u) -> - List.init (nconstructors ind) - (fun i -> IsConstr (mkConstructU ((ind,i+1),u), - Univ.ContextSet.empty)) - | _ -> - [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) (project gl) lems in - let hintlist' = - 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 sign = pf_hyps gl in - let ts = match ts with - | None -> Hint_db.transparent_state (searchtable_map "core") - | Some ts -> ts - in - let hintlist = List.map_append (pf_apply make_resolve_hyp gl) sign in - 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) *) @@ -1557,31 +390,24 @@ and trivial_resolve dbg mod_delta db_list local_db cl = (** The use of the "core" database can be de-activated by passing "nocore" amongst the databases. *) -let make_db_list dbnames = - let use_core = not (List.mem "nocore" dbnames) in - let dbnames = List.remove String.equal "nocore" dbnames in - let dbnames = if use_core then "core"::dbnames else dbnames in - let lookup db = - try searchtable_map db with Not_found -> error_no_such_hint_database db - in - List.map lookup dbnames - let trivial ?(debug=Off) lems dbnames = Proofview.Goal.nf_enter begin fun gl -> + let env = Proofview.Goal.env gl in + let sigma = Proofview.Goal.sigma gl in let db_list = make_db_list dbnames in let d = mk_trivial_dbg debug in - let hints = Tacmach.New.of_old (make_local_hint_db false lems) gl in + let hints = make_local_hint_db env sigma false lems in tclTRY_dbg d (trivial_fail_db d false db_list hints) end let full_trivial ?(debug=Off) lems = Proofview.Goal.nf_enter begin fun gl -> - let dbs = !searchtable in - let dbs = String.Map.remove "v62" dbs in - let db_list = List.map snd (String.Map.bindings dbs) in + let env = Proofview.Goal.env gl in + let sigma = Proofview.Goal.sigma gl in + let db_list = current_pure_db () in let d = mk_trivial_dbg debug in - let hints = Tacmach.New.of_old (make_local_hint_db false lems) gl in + let hints = make_local_hint_db env sigma false lems in tclTRY_dbg d (trivial_fail_db d false db_list hints) end @@ -1647,9 +473,11 @@ let default_search_depth = ref 5 let delta_auto debug mod_delta n lems dbnames = Proofview.Goal.nf_enter begin fun gl -> + let env = Proofview.Goal.env gl in + let sigma = Proofview.Goal.sigma gl in let db_list = make_db_list dbnames in let d = mk_auto_dbg debug in - let hints = Tacmach.New.of_old (make_local_hint_db false lems) gl in + let hints = make_local_hint_db env sigma false lems in tclTRY_dbg d (search d n mod_delta db_list hints) end @@ -1668,11 +496,11 @@ let default_auto = auto !default_search_depth [] [] let delta_full_auto ?(debug=Off) mod_delta n lems = Proofview.Goal.nf_enter begin fun gl -> - let dbs = !searchtable in - let dbs = String.Map.remove "v62" dbs in - let db_list = List.map snd (String.Map.bindings dbs) in + let env = Proofview.Goal.env gl in + let sigma = Proofview.Goal.sigma gl in + let db_list = current_pure_db () in let d = mk_auto_dbg debug in - let hints = Tacmach.New.of_old (make_local_hint_db false lems) gl in + let hints = make_local_hint_db env sigma false lems in tclTRY_dbg d (search d n mod_delta db_list hints) end diff --git a/tactics/auto.mli b/tactics/auto.mli index 26dcee8cc..fd24846d8 100644 --- a/tactics/auto.mli +++ b/tactics/auto.mli @@ -6,208 +6,19 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -open Util open Names open Term -open Context open Proof_type -open Tacmach open Clenv open Pattern -open Environ open Evd -open Globnames -open Vernacexpr -open Mod_subst -open Misctypes -open Pp open Decl_kinds - -(** Auto and related automation tactics *) - -type 'a auto_tactic = - | 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 Tacexpr.glob_tactic_expr (* Hint Extern *) - -type hints_path_atom = - | PathHints of global_reference list - | PathAny - -type 'a gen_auto_tactic = { - pri : int; (** A number between 0 and 4, 4 = lower 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 = (constr * clausenv) gen_auto_tactic - -type search_entry - -(** The head may not be bound. *) - -type hint_entry = global_reference option * - (constr * types * Univ.universe_context_set) gen_auto_tactic - -type hints_path = - | PathAtom of hints_path_atom - | PathStar of hints_path - | PathSeq of hints_path * hints_path - | PathOr of hints_path * hints_path - | PathEmpty - | PathEpsilon - -val normalize_path : hints_path -> hints_path -val path_matches : hints_path -> hints_path_atom list -> bool -val path_derivate : hints_path -> hints_path_atom -> hints_path -val pp_hints_path : hints_path -> Pp.std_ppcmds - -module Hint_db : - sig - type t - val empty : transparent_state -> bool -> t - val find : global_reference -> t -> search_entry - val map_none : t -> pri_auto_tactic list - - (** All hints associated to the reference *) - val map_all : global_reference -> t -> pri_auto_tactic list - - (** All hints associated to the reference, respecting modes if evars appear in the - arguments, _not_ using the discrimination net. *) - val map_existential : (global_reference * constr array) -> constr -> t -> pri_auto_tactic list - - (** All hints associated to the reference, respecting modes if evars appear in the - arguments and using the discrimination net. *) - val map_eauto : (global_reference * constr array) -> constr -> t -> pri_auto_tactic list - - (** All hints associated to the reference, respecting modes if evars appear in the - arguments. *) - val map_auto : (global_reference * constr array) -> constr -> t -> pri_auto_tactic list - - val add_one : hint_entry -> t -> t - val add_list : (hint_entry) list -> t -> t - val remove_one : global_reference -> t -> t - val remove_list : global_reference list -> t -> t - val iter : (global_reference option -> bool array list -> pri_auto_tactic list -> unit) -> t -> unit - - val use_dn : t -> bool - val transparent_state : t -> transparent_state - val set_transparent_state : t -> transparent_state -> t - - val add_cut : hints_path -> t -> t - val cut : t -> hints_path - - val unfolds : t -> Id.Set.t * Cset.t - end - -type hint_db_name = string - -type hint_db = Hint_db.t - -type hnf = bool - -type hint_term = - | IsGlobRef of global_reference - | IsConstr of constr * Univ.universe_context_set - -type hints_entry = - | 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 - | HintsModeEntry of global_reference * bool list - | HintsExternEntry of - int * (patvar list * constr_pattern) option * Tacexpr.glob_tactic_expr - -val searchtable_map : hint_db_name -> hint_db - -val searchtable_add : (hint_db_name * hint_db) -> unit - -(** [create_hint_db local name st use_dn]. - [st] is a transparency state for unification using this db - [use_dn] switches the use of the discrimination net for all hints - and patterns. *) - -val create_hint_db : bool -> hint_db_name -> transparent_state -> bool -> unit - -val remove_hints : bool -> hint_db_name list -> global_reference list -> unit - -val current_db_names : unit -> String.Set.t - -val interp_hints : polymorphic -> hints_expr -> hints_entry - -val add_hints : locality_flag -> hint_db_name list -> hints_entry -> unit - -val prepare_hint : bool (* Check no remaining evars *) -> env -> evar_map -> - open_constr -> hint_term - -val pr_searchtable : unit -> std_ppcmds -val pr_applicable_hint : unit -> std_ppcmds -val pr_hint_ref : global_reference -> std_ppcmds -val pr_hint_db_by_name : hint_db_name -> std_ppcmds -val pr_hint_db : Hint_db.t -> std_ppcmds - -(** [make_exact_entry pri (c, ctyp)]. - [c] is the term given as an exact proof to solve the goal; - [ctyp] is the type of [c]. *) - -val make_exact_entry : env -> evar_map -> int option -> polymorphic -> ?name:hints_path_atom -> - (constr * types * Univ.universe_context_set) -> hint_entry - -(** [make_apply_entry (eapply,hnf,verbose) pri (c,cty)]. - [eapply] is true if this hint will be used only with EApply; - [hnf] should be true if we should expand the head of cty before searching for - products; - [c] is the term given as an exact proof to solve the goal; - [cty] is the type of [c]. *) - -val make_apply_entry : - env -> evar_map -> bool * bool * bool -> int option -> polymorphic -> ?name:hints_path_atom -> - (constr * types * Univ.universe_context_set) -> hint_entry - -(** A constr which is Hint'ed will be: - - (1) used as an Exact, if it does not start with a product - - (2) used as an Apply, if its HNF starts with a product, and - has no missing arguments. - - (3) used as an EApply, if its HNF starts with a product, and - has missing arguments. *) - -val make_resolves : - env -> evar_map -> bool * bool * bool -> int option -> polymorphic -> ?name:hints_path_atom -> - hint_term -> hint_entry list - -(** [make_resolve_hyp hname htyp]. - used to add an hypothesis to the local hint database; - Never raises a user exception; - If the hyp cannot be used as a Hint, the empty list is returned. *) - -val make_resolve_hyp : - env -> evar_map -> named_declaration -> hint_entry list - -(** [make_extern pri pattern tactic_expr] *) - -val make_extern : - int -> constr_pattern option -> Tacexpr.glob_tactic_expr - -> hint_entry +open Hints val extern_interp : (patvar_map -> Tacexpr.glob_tactic_expr -> unit Proofview.tactic) Hook.t -val extern_intern_tac : - (patvar list -> Tacexpr.raw_tactic_expr -> Tacexpr.glob_tactic_expr) Hook.t - -(** Create a Hint database from the pairs (name, constr). - Useful to take the current goal hypotheses as hints; - Boolean tells if lemmas with evars are allowed *) - -val make_local_hint_db : ?ts:transparent_state -> bool -> open_constr list -> goal sigma -> hint_db +(** Auto and related automation tactics *) val priority : ('a * pri_auto_tactic) list -> ('a * pri_auto_tactic) list @@ -232,8 +43,6 @@ val conclPattern : constr -> constr_pattern option -> Tacexpr.glob_tactic_expr - (** The use of the "core" database can be de-activated by passing "nocore" amongst the databases. *) -val make_db_list : hint_db_name list -> hint_db list - val auto : ?debug:Tacexpr.debug -> int -> open_constr list -> hint_db_name list -> unit Proofview.tactic @@ -276,14 +85,3 @@ val full_trivial : ?debug:Tacexpr.debug -> open_constr list -> unit Proofview.tactic val h_trivial : ?debug:Tacexpr.debug -> open_constr list -> hint_db_name list option -> unit Proofview.tactic - -val pr_autotactic : (constr * 'a) auto_tactic -> Pp.std_ppcmds - -(** Hook for changing the initialization of auto *) - -val add_auto_init : (unit -> unit) -> unit - -(** Pre-created hint databases *) - -val typeclasses_db : hint_db_name -val rewrite_db : hint_db_name diff --git a/tactics/class_tactics.ml b/tactics/class_tactics.ml index d9f90b02e..38f1114b5 100644 --- a/tactics/class_tactics.ml +++ b/tactics/class_tactics.ml @@ -25,6 +25,7 @@ open Evd open Locus open Misctypes open Proofview.Notations +open Hints (** Hint database named "typeclass_instances", now created directly in Auto *) @@ -215,7 +216,7 @@ let pr_ev evs ev = Printer.pr_constr_env (Goal.V82.env evs ev) evs (Evarutil.nf_ let pr_depth l = prlist_with_sep (fun () -> str ".") int (List.rev l) -type autoinfo = { hints : Auto.hint_db; is_evar: existential_key option; +type autoinfo = { hints : hint_db; is_evar: existential_key option; only_classes: bool; unique : bool; auto_depth: int list; auto_last_tac: std_ppcmds Lazy.t; auto_path : global_reference option list; @@ -750,7 +751,7 @@ let set_typeclasses_depth = let typeclasses_eauto ?(only_classes=false) ?(st=full_transparent_state) dbs gl = try let dbs = List.map_filter - (fun db -> try Some (Auto.searchtable_map db) + (fun db -> try Some (searchtable_map db) with e when Errors.noncritical e -> None) dbs in @@ -787,7 +788,7 @@ let is_ground c gl = let autoapply c i gl = let flags = auto_unif_flags Evar.Set.empty - (Auto.Hint_db.transparent_state (Auto.searchtable_map i)) in + (Hints.Hint_db.transparent_state (Hints.searchtable_map i)) in let cty = pf_type_of gl c in let ce = mk_clenv_from gl (c,cty) in unify_e_resolve false flags (c,ce) gl diff --git a/tactics/class_tactics.mli b/tactics/class_tactics.mli index f64f708de..00c601d28 100644 --- a/tactics/class_tactics.mli +++ b/tactics/class_tactics.mli @@ -21,7 +21,7 @@ val get_typeclasses_depth : unit -> int option val progress_evars : unit Proofview.tactic -> unit Proofview.tactic val typeclasses_eauto : ?only_classes:bool -> ?st:transparent_state -> - Auto.hint_db_name list -> tactic + Hints.hint_db_name list -> tactic val head_of_constr : Id.t -> Term.constr -> unit Proofview.tactic @@ -29,4 +29,4 @@ val not_evar : constr -> unit Proofview.tactic val is_ground : constr -> tactic -val autoapply : constr -> Auto.hint_db_name -> tactic +val autoapply : constr -> Hints.hint_db_name -> tactic diff --git a/tactics/eauto.ml4 b/tactics/eauto.ml4 index 711ae92b0..334e0c22a 100644 --- a/tactics/eauto.ml4 +++ b/tactics/eauto.ml4 @@ -27,6 +27,7 @@ open Tacexpr open Misctypes open Locus open Locusops +open Hints DECLARE PLUGIN "eauto" @@ -196,8 +197,8 @@ type search_state = { depth : int; (*r depth of search before failing *) tacres : goal list sigma; last_tactic : std_ppcmds Lazy.t; - dblist : Auto.hint_db list; - localdb : Auto.hint_db list; + dblist : hint_db list; + localdb : hint_db list; prev : prev_search_state } @@ -289,7 +290,7 @@ module SearchProblem = struct let gls = {Evd.it = gl; sigma = lgls.Evd.sigma } in let hyps' = pf_hyps gls in if hyps' == hyps then List.hd s.localdb - else make_local_hint_db ~ts:full_transparent_state true [] gls) + else make_local_hint_db (pf_env gls) (project gls) ~ts:full_transparent_state true []) (List.firstn ((nbgl'-nbgl) + 1) (sig_it lgls)) in { depth = pred s.depth; tacres = res; @@ -369,7 +370,7 @@ let make_initial_state dbg n gl dblist localdb = } let e_search_auto debug (in_depth,p) lems db_list gl = - let local_db = make_local_hint_db ~ts:full_transparent_state true lems gl in + let local_db = make_local_hint_db (pf_env gl) (project gl) ~ts:full_transparent_state true lems in let d = mk_eauto_dbg debug in let tac = match in_depth,d with | (true,Debug) -> Search.debug_depth_first @@ -505,7 +506,7 @@ let autounfold db cls gl = let autounfold_tac db cls gl = let dbs = match db with - | None -> String.Set.elements (Auto.current_db_names ()) + | None -> String.Set.elements (current_db_names ()) | Some [] -> ["core"] | Some l -> l in @@ -661,6 +662,6 @@ END VERNAC COMMAND EXTEND HintCut CLASSIFIED AS SIDEFF | [ "Hint" "Cut" "[" hints_path(p) "]" opthints(dbnames) ] -> [ let entry = HintsCutEntry p in - Auto.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ())) + Hints.add_hints (Locality.make_section_locality (Locality.LocalityFixme.consume ())) (match dbnames with None -> ["core"] | Some l -> l) entry ] END diff --git a/tactics/eauto.mli b/tactics/eauto.mli index e2da23aaa..488bc037c 100644 --- a/tactics/eauto.mli +++ b/tactics/eauto.mli @@ -10,6 +10,7 @@ open Term open Proof_type open Auto open Evd +open Hints val hintbases : hint_db_name list option Pcoq.Gram.entry @@ -33,6 +34,6 @@ val gen_eauto : ?debug:Tacexpr.debug -> bool * int -> open_constr list -> val eauto_with_bases : ?debug:Tacexpr.debug -> bool * int -> - open_constr list -> Auto.hint_db list -> Proof_type.tactic + open_constr list -> hint_db list -> Proof_type.tactic val autounfold : hint_db_name list -> Locus.clause -> tactic diff --git a/tactics/extratactics.ml4 b/tactics/extratactics.ml4 index cb15bb94c..342e65cba 100644 --- a/tactics/extratactics.ml4 +++ b/tactics/extratactics.ml4 @@ -325,11 +325,11 @@ let project_hint pri l2r r = in let ctx = Evd.universe_context_set sigma in let c = Declare.declare_definition ~internal:Declare.KernelSilent id (c,ctx) in - (pri,false,true,Auto.PathAny, Auto.IsGlobRef (Globnames.ConstRef c)) + (pri,false,true,Hints.PathAny, Hints.IsGlobRef (Globnames.ConstRef c)) let add_hints_iff l2r lc n bl = - Auto.add_hints true bl - (Auto.HintsResolveEntry (List.map (project_hint n l2r) lc)) + Hints.add_hints true bl + (Hints.HintsResolveEntry (List.map (project_hint n l2r) lc)) VERNAC COMMAND EXTEND HintResolveIffLR CLASSIFIED AS SIDEFF [ "Hint" "Resolve" "->" ne_global_list(lc) natural_opt(n) diff --git a/tactics/g_class.ml4 b/tactics/g_class.ml4 index 1e666e5a5..a49c76f14 100644 --- a/tactics/g_class.ml4 +++ b/tactics/g_class.ml4 @@ -64,7 +64,7 @@ END TACTIC EXTEND typeclasses_eauto | [ "typeclasses" "eauto" "with" ne_preident_list(l) ] -> [ Proofview.V82.tactic (typeclasses_eauto l) ] -| [ "typeclasses" "eauto" ] -> [ Proofview.V82.tactic (typeclasses_eauto ~only_classes:true [Auto.typeclasses_db]) ] +| [ "typeclasses" "eauto" ] -> [ Proofview.V82.tactic (typeclasses_eauto ~only_classes:true [Hints.typeclasses_db]) ] END TACTIC EXTEND head_of_constr diff --git a/tactics/rewrite.ml b/tactics/rewrite.ml index fbcd9ee2d..63885318c 100644 --- a/tactics/rewrite.ml +++ b/tactics/rewrite.ml @@ -517,12 +517,12 @@ let rewrite_db = "rewrite" let conv_transparent_state = (Id.Pred.empty, Cpred.full) let _ = - Auto.add_auto_init + Hints.add_hints_init (fun () -> - Auto.create_hint_db false rewrite_db conv_transparent_state true) + Hints.create_hint_db false rewrite_db conv_transparent_state true) let rewrite_transparent_state () = - Auto.Hint_db.transparent_state (Auto.searchtable_map rewrite_db) + Hints.Hint_db.transparent_state (Hints.searchtable_map rewrite_db) let rewrite_core_unif_flags = { Unification.modulo_conv_on_closed_terms = None; diff --git a/tactics/tacintern.ml b/tactics/tacintern.ml index 08dd0dff4..3f27d0b91 100644 --- a/tactics/tacintern.ml +++ b/tactics/tacintern.ml @@ -825,4 +825,4 @@ let _ = Flags.with_option strict_check (intern_pure_tactic { (make_empty_glob_sign()) with ltacvars }) in - Hook.set Auto.extern_intern_tac f + Hook.set Hints.extern_intern_tac f diff --git a/tactics/tactics.ml b/tactics/tactics.ml index c40dc4078..68aac55c8 100644 --- a/tactics/tactics.ml +++ b/tactics/tactics.ml @@ -44,8 +44,6 @@ open Locusops open Misctypes open Proofview.Notations -exception Bound - let nb_prod x = let rec count n c = match kind_of_term c with @@ -114,34 +112,6 @@ let _ = (* Tactics *) (*********************************************) -(****************************************) -(* General functions *) -(****************************************) - -let head_constr_bound t = - let t = strip_outer_cast t in - let _,ccl = decompose_prod_assum t in - let hd,args = decompose_app ccl in - match kind_of_term hd with - | Const _ | Ind _ | Construct _ | Var _ -> hd - | Proj (p, _) -> mkConst (Projection.constant p) - | _ -> raise Bound - -let head_constr c = - try head_constr_bound c with Bound -> error "Bound head variable." - -let decompose_app_bound t = - let t = strip_outer_cast t in - let _,ccl = decompose_prod_assum t in - let hd,args = decompose_app_vect ccl in - match kind_of_term hd with - | Const (c,u) -> ConstRef c, args - | Ind (i,u) -> IndRef i, args - | Construct (c,u) -> ConstructRef c, args - | Var id -> VarRef id, args - | Proj (p, c) -> ConstRef (Projection.constant p), Array.cons c args - | _ -> raise Bound - (******************************************) (* Primitive tactics *) (******************************************) diff --git a/tactics/tactics.mli b/tactics/tactics.mli index 398a90ba3..6ecb48101 100644 --- a/tactics/tactics.mli +++ b/tactics/tactics.mli @@ -26,11 +26,6 @@ open Locus (** {6 General functions. } *) -exception Bound - -val head_constr : constr -> constr -val head_constr_bound : constr -> constr -val decompose_app_bound : constr -> global_reference * constr array val is_quantified_hypothesis : Id.t -> goal sigma -> bool (** {6 Primitive tactics. } *) diff --git a/tactics/tactics.mllib b/tactics/tactics.mllib index e2c0f40fb..46f2abd7f 100644 --- a/tactics/tactics.mllib +++ b/tactics/tactics.mllib @@ -17,6 +17,7 @@ Leminv Tacsubst Taccoerce Tacenv +Hints Auto Tacintern TacticMatching diff --git a/toplevel/classes.ml b/toplevel/classes.ml index 8f36fc79f..4d23a4181 100644 --- a/toplevel/classes.ml +++ b/toplevel/classes.ml @@ -28,22 +28,22 @@ open Entries let typeclasses_db = "typeclass_instances" let set_typeclass_transparency c local b = - Auto.add_hints local [typeclasses_db] - (Auto.HintsTransparencyEntry ([c], b)) + Hints.add_hints local [typeclasses_db] + (Hints.HintsTransparencyEntry ([c], b)) let _ = Hook.set Typeclasses.add_instance_hint_hook (fun inst path local pri poly -> - let inst' = match inst with IsConstr c -> Auto.IsConstr (c, Univ.ContextSet.empty) - | IsGlobal gr -> Auto.IsGlobRef gr + let inst' = match inst with IsConstr c -> Hints.IsConstr (c, Univ.ContextSet.empty) + | IsGlobal gr -> Hints.IsGlobRef gr in Flags.silently (fun () -> - Auto.add_hints local [typeclasses_db] - (Auto.HintsResolveEntry - [pri, poly, false, Auto.PathHints path, inst'])) ()); + Hints.add_hints local [typeclasses_db] + (Hints.HintsResolveEntry + [pri, poly, false, Hints.PathHints path, inst'])) ()); Hook.set Typeclasses.set_typeclass_transparency_hook set_typeclass_transparency; Hook.set Typeclasses.classes_transparent_state_hook - (fun () -> Auto.Hint_db.transparent_state (Auto.searchtable_map typeclasses_db)) + (fun () -> Hints.Hint_db.transparent_state (Hints.searchtable_map typeclasses_db)) (** TODO: add subinstances *) let existing_instance glob g pri = diff --git a/toplevel/obligations.ml b/toplevel/obligations.ml index 2ac4339c1..b303533e4 100644 --- a/toplevel/obligations.ml +++ b/toplevel/obligations.ml @@ -632,8 +632,8 @@ let declare_obligation prg obl body ty uctx = (DefinitionEntry ce,IsProof Property) in if not opaque then - Auto.add_hints false [Id.to_string prg.prg_name] - (Auto.HintsUnfoldEntry [EvalConstRef constant]); + Hints.add_hints false [Id.to_string prg.prg_name] + (Hints.HintsUnfoldEntry [EvalConstRef constant]); definition_message obl.obl_name; { obl with obl_body = if poly then @@ -813,8 +813,8 @@ let rec solve_obligation prg num tac = else DefinedObl cst in if transparent then - Auto.add_hints true [Id.to_string prg.prg_name] - (Auto.HintsUnfoldEntry [EvalConstRef cst]); + Hints.add_hints true [Id.to_string prg.prg_name] + (Hints.HintsUnfoldEntry [EvalConstRef cst]); { obl with obl_body = Some body } in let obls = Array.copy obls in diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml index 63253d54e..f6bc8bbeb 100644 --- a/toplevel/vernacentries.ml +++ b/toplevel/vernacentries.ml @@ -967,15 +967,15 @@ let vernac_declare_tactic_definition locality (x,def) = let vernac_create_hintdb locality id b = let local = make_module_locality locality in - Auto.create_hint_db local id full_transparent_state b + Hints.create_hint_db local id full_transparent_state b let vernac_remove_hints locality dbs ids = let local = make_module_locality locality in - Auto.remove_hints local dbs (List.map Smartlocate.global_with_alias ids) + Hints.remove_hints local dbs (List.map Smartlocate.global_with_alias ids) let vernac_hints locality poly local lb h = let local = enforce_module_locality locality local in - Auto.add_hints local lb (Auto.interp_hints poly h) + Hints.add_hints local lb (Hints.interp_hints poly h) let vernac_syntactic_definition locality lid x local y = Dumpglob.dump_definition lid false "syndef"; @@ -1528,11 +1528,11 @@ let vernac_print = function let univ = if b then Univ.sort_universes univ else univ in msg_notice (Univ.pr_universes univ) | PrintUniverses (b, Some s) -> dump_universes b s - | PrintHint r -> msg_notice (Auto.pr_hint_ref (smart_global r)) - | PrintHintGoal -> msg_notice (Auto.pr_applicable_hint ()) - | PrintHintDbName s -> msg_notice (Auto.pr_hint_db_by_name s) + | PrintHint r -> msg_notice (Hints.pr_hint_ref (smart_global r)) + | PrintHintGoal -> msg_notice (Hints.pr_applicable_hint ()) + | PrintHintDbName s -> msg_notice (Hints.pr_hint_db_by_name s) | PrintRewriteHintDbName s -> msg_notice (Autorewrite.print_rewrite_hintdb s) - | PrintHintDb -> msg_notice (Auto.pr_searchtable ()) + | PrintHintDb -> msg_notice (Hints.pr_searchtable ()) | PrintScopes -> msg_notice (Notation.pr_scopes (Constrextern.without_symbols pr_lglob_constr)) | PrintScope s -> |