diff options
| author | ppedrot | 2013-06-14 18:29:20 +0000 |
|---|---|---|
| committer | ppedrot | 2013-06-14 18:29:20 +0000 |
| commit | 91f44f1da7a5c61f4912084c43646be74bd99d3c (patch) | |
| tree | 3c418a106423a2398e7467423310fde90aca04c5 | |
| parent | 7571dfee41570004e7f236e8b11c18605172eb0e (diff) | |
Using an "extra" Store.t field in interp_sign instead of dedicated
record fields.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@16580 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | tactics/rewrite.ml4 | 4 | ||||
| -rw-r--r-- | tactics/tacinterp.ml | 136 | ||||
| -rw-r--r-- | tactics/tacinterp.mli | 12 |
3 files changed, 98 insertions, 54 deletions
diff --git a/tactics/rewrite.ml4 b/tactics/rewrite.ml4 index a678a4e306..580f8c8bea 100644 --- a/tactics/rewrite.ml4 +++ b/tactics/rewrite.ml4 @@ -1085,7 +1085,9 @@ let rewrite_strat flags occs hyp = let get_hypinfo_ids {c = opt} = match opt with | None -> [] - | Some (is, gc) -> List.map fst is.lfun @ is.avoid_ids + | Some (is, gc) -> + let avoid = Option.default [] (TacStore.get is.extra f_avoid_ids) in + List.map fst is.lfun @ avoid let rewrite_with flags c left2right loccs : strategy = fun env avoid t ty cstr evars -> diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml index 5371611c5d..76c7dfeb35 100644 --- a/tactics/tacinterp.ml +++ b/tactics/tacinterp.ml @@ -36,6 +36,9 @@ open Genarg open Printer open Pretyping open Extrawit + +module TacStore = Store.Make(struct end) + open Evd open Misctypes open Miscops @@ -85,13 +88,19 @@ let catch_error call_trace tac g = raise located_exc end +let f_avoid_ids : Id.t list TacStore.field = TacStore.field () +(* ids inherited from the call context (needed to get fresh ids) *) +let f_debug : debug_info TacStore.field = TacStore.field () +let f_trace : ltac_trace TacStore.field = TacStore.field () + (* Signature for interpretation: val_interp and interpretation functions *) -type interp_sign = - { lfun : (Id.t * value) list; - avoid_ids : Id.t list; (* ids inherited from the call context - (needed to get fresh ids) *) - debug : debug_info; - trace : ltac_trace } +type interp_sign = { + lfun : (Id.t * value) list; + extra : TacStore.t } + +let curr_debug ist = match TacStore.get ist.extra f_debug with +| None -> DebugOff +| Some level -> level let check_is_value v = let v = Value.normalize v in @@ -184,10 +193,17 @@ let lookup_interp_genarg id = add_interp_genarg id f; f -let push_trace (loc,ck) = function +let push_trace (loc, ck) ist = match TacStore.get ist.extra f_trace with +| None -> [1, loc, ck] +| Some trace -> + match trace with | (n,loc',ck')::trl when Pervasives.(=) ck ck' -> (n+1,loc,ck)::trl (** FIXME *) | trl -> (1,loc,ck)::trl +let extract_trace ist = match TacStore.get ist.extra f_trace with +| None -> [] +| Some l -> l + let propagate_trace ist loc id v = let v = Value.normalize v in if has_type v (topwit wit_tacvalue) then @@ -195,7 +211,7 @@ let propagate_trace ist loc id v = match tacv with | VFun (_,lfun,it,b) -> let t = if List.is_empty it then b else TacFun (it,b) in - let ans = VFun (push_trace(loc,LtacVarCall (id,t)) ist.trace,lfun,it,b) in + let ans = VFun (push_trace(loc,LtacVarCall (id,t)) ist,lfun,it,b) in of_tacvalue ans | _ -> v else v @@ -268,8 +284,7 @@ let set_debug pos = debug := pos (* Gives the state of debug *) let get_debug () = !debug -let debugging_step ist pp = - match ist.debug with +let debugging_step ist pp = match curr_debug ist with | DebugOn lev -> safe_msgnl (str "Level " ++ int lev ++ str": " ++ pp () ++ fnl()) | _ -> () @@ -440,7 +455,11 @@ let default_fresh_id = Id.of_string "H" let interp_fresh_id ist env l = let ids = List.map_filter (function ArgVar (_, id) -> Some id | _ -> None) l in - let avoid = (extract_ids ids ist.lfun) @ ist.avoid_ids in + let avoid = match TacStore.get ist.extra f_avoid_ids with + | None -> [] + | Some l -> l + in + let avoid = (extract_ids ids ist.lfun) @ avoid in let id = if List.is_empty l then default_fresh_id else @@ -467,13 +486,13 @@ let interp_gen kind ist allow_patvar flags env sigma (c,ce) = intern_gen kind ~allow_patvar ~ltacvars:ltacdata sigma env c in let trace = - push_trace (loc_of_glob_constr c,LtacConstrInterp (c,vars)) ist.trace in + push_trace (loc_of_glob_constr c,LtacConstrInterp (c,vars)) ist in let (evd,c) = (** FIXME: we should propagate the use of Id.Map.t everywhere *) let vars = (ltacbnd, unbndltacvars) in catch_error trace (understand_ltac flags sigma env vars kind) c in - db_constr ist.debug env c; + db_constr (curr_debug ist) env c; (evd,c) let constr_flags = { @@ -656,7 +675,7 @@ let interp_constr_may_eval ist gl c = raise reraise in begin - db_constr ist.debug (pf_env gl) csr; + db_constr (curr_debug ist) (pf_env gl) csr; sigma , csr end @@ -1002,7 +1021,7 @@ let rec val_interp ist gl (tac:glob_tactic_expr) : Evd.evar_map * typed_generic_ let value_interp ist = match tac with (* Immediate evaluation *) | TacFun (it,body) -> - let v = VFun (ist.trace,ist.lfun,it,body) in + let v = VFun (extract_trace ist,ist.lfun,it,body) in project gl, of_tacvalue v | TacLetIn (true,l,u) -> interp_letrec ist gl l u | TacLetIn (false,l,u) -> interp_letin ist gl l u @@ -1011,13 +1030,17 @@ let rec val_interp ist gl (tac:glob_tactic_expr) : Evd.evar_map * typed_generic_ | TacArg (loc,a) -> interp_tacarg ist gl a (* Delayed evaluation *) | t -> - let v = VFun (ist.trace,ist.lfun,[],t) in + let v = VFun (extract_trace ist,ist.lfun,[],t) in project gl, of_tacvalue v in check_for_interrupt (); - match ist.debug with + match curr_debug ist with | DebugOn lev -> - debug_prompt lev gl tac (fun v -> value_interp {ist with debug=v}) + let eval v = + let ist = { ist with extra = TacStore.set ist.extra f_debug v } in + value_interp ist + in + debug_prompt lev gl tac eval | _ -> value_interp ist and eval_tactic ist = function @@ -1025,15 +1048,15 @@ and eval_tactic ist = function fun gl -> let call = LtacAtomCall t in let tac = (* catch error in the interpretation *) - catch_error (push_trace(dloc,call)ist.trace) + catch_error (push_trace(dloc,call)ist) (interp_atomic ist gl) t in (* catch error in the evaluation *) - catch_error (push_trace(loc,call)ist.trace) tac gl + catch_error (push_trace(loc,call)ist) tac gl | TacFun _ | TacLetIn _ -> assert false | TacMatchGoal _ | TacMatch _ -> assert false | TacId s -> fun gl -> let res = tclIDTAC_MESSAGE (interp_message_nl ist gl s) gl in - db_breakpoint ist.debug s; res + db_breakpoint (curr_debug ist) s; res | TacFail (n,s) -> fun gl -> tclFAIL (interp_int_or_var ist n) (interp_message ist gl s) gl | TacProgress tac -> tclPROGRESS (interp_tactic ist tac) | TacShowHyps tac -> tclSHOWHYPS (interp_tactic ist tac) @@ -1078,9 +1101,9 @@ and interp_ltac_reference loc' mustbetac ist gl = function | ArgArg (loc,r) -> let ids = extract_ids [] ist.lfun in let loc_info = ((if Loc.is_ghost loc' then loc else loc'),LtacNameCall r) in - let ist = - { lfun=[]; debug=ist.debug; avoid_ids=ids; - trace = push_trace loc_info ist.trace } in + let extra = TacStore.set ist.extra f_avoid_ids ids in + let extra = TacStore.set extra f_trace (push_trace loc_info ist) in + let ist = { lfun = []; extra = extra; } in val_interp ist gl (lookup_ltacref r) and interp_tacarg ist gl arg = @@ -1168,8 +1191,10 @@ and interp_app loc ist gl fv largs = (* Check evaluation and report problems with current trace *) let (sigma,v) = try - catch_error trace - (val_interp {ist with lfun=newlfun@olfun; trace=[]} gl) body + let ist = { + lfun = newlfun@olfun; + extra = TacStore.set ist.extra f_trace []; } in + catch_error trace (val_interp ist gl) body with reraise -> let reraise = Errors.push reraise in debugging_exception_step ist false reraise @@ -1196,7 +1221,10 @@ and tactic_of_value ist vle g = match to_tacvalue vle with | VRTactic res -> res | VFun (trace,lfun,[],t) -> - let tac = eval_tactic {ist with lfun=lfun; trace=[]} t in + let ist = { + lfun = lfun; + extra = TacStore.set ist.extra f_trace []; } in + let tac = eval_tactic ist t in catch_error trace tac g | (VFun _|VRec _) -> error "A fully applied tactic is expected." else errorlabstrm "" (str"Expression does not evaluate to a tactic.") @@ -1209,7 +1237,10 @@ and eval_with_fail ist is_lazy goal tac = sigma , (if has_type v (topwit wit_tacvalue) then match to_tacvalue v with | VFun (trace,lfun,[],t) when not is_lazy -> - let tac = eval_tactic {ist with lfun=lfun; trace=trace} t in + let ist = { + lfun = lfun; + extra = TacStore.set ist.extra f_trace trace; } in + let tac = eval_tactic ist t in of_tacvalue (VRTactic (catch_error trace tac { goal with sigma=sigma })) | _ -> v else v) @@ -1262,13 +1293,13 @@ and interp_match_goal ist goal lz lr lmr = let rec apply_match_goal ist env goal nrs lex lpt = begin let () = match lex with - | r :: _ -> db_pattern_rule ist.debug nrs r + | r :: _ -> db_pattern_rule (curr_debug ist) nrs r | _ -> () in match lpt with | (All t)::tl -> begin - db_mc_pattern_success ist.debug; + db_mc_pattern_success (curr_debug ist); try eval_with_fail ist lz goal t with e when is_match_catchable e -> apply_match_goal ist env goal (nrs+1) (List.tl lex) tl @@ -1279,13 +1310,13 @@ and interp_match_goal ist goal lz lr lmr = | Term mg -> (try let lmatch = extended_matches mg concl in - db_matched_concl ist.debug env concl; + db_matched_concl (curr_debug ist) env concl; apply_hyps_context ist env lz goal mt [] lmatch mhyps hyps with e when is_match_catchable e -> (match e with - | PatternMatchingFailure -> db_matching_failure ist.debug - | Eval_fail s -> db_eval_failure ist.debug s - | _ -> db_logic_failure ist.debug e); + | PatternMatchingFailure -> db_matching_failure (curr_debug ist) + | Eval_fail s -> db_eval_failure (curr_debug ist) s + | _ -> db_logic_failure (curr_debug ist) e); apply_match_goal ist env goal (nrs+1) (List.tl lex) tl) | Subterm (b,id,mg) -> (try apply_goal_sub b ist (id,mg) concl mt mhyps hyps @@ -1295,7 +1326,7 @@ and interp_match_goal ist goal lz lr lmr = | _ -> errorlabstrm "Tacinterp.apply_match_goal" (v 0 (str "No matching clauses for match goal" ++ - (if ist.debug == DebugOff then + (if (curr_debug ist) == DebugOff then fnl() ++ str "(use \"Set Ltac Debug\" for more info)" else mt()) ++ str".")) end in @@ -1314,11 +1345,11 @@ and apply_hyps_context ist env lz goal mt lctxt lgmatch mhyps hyps = in let rec match_next_pattern next = match IStream.peek next with | None -> - db_hyp_pattern_failure ist.debug env (hypname, pat); + db_hyp_pattern_failure (curr_debug ist) env (hypname, pat); raise PatternMatchingFailure | Some (s, next) -> let lids,hyp_match = s.e_ctx in - db_matched_hyp ist.debug (pf_env goal) hyp_match hypname; + db_matched_hyp (curr_debug ist) (pf_env goal) hyp_match hypname; try let id_match = pi1 hyp_match in let nextlhyps = List.remove_assoc_in_triple id_match lhyps_rest in @@ -1329,7 +1360,7 @@ and apply_hyps_context ist env lz goal mt lctxt lgmatch mhyps hyps = match_next_pattern init_match_pattern | [] -> let lfun = extend_values_with_bindings lmatch (lfun@ist.lfun) in - db_mc_pattern_success ist.debug; + db_mc_pattern_success (curr_debug ist); eval_with_fail {ist with lfun=lfun} lz goal mt in apply_hyps_context_rec lctxt lgmatch hyps mhyps @@ -1421,7 +1452,7 @@ and interp_genarg ist gl x = | ExtraArgType s -> match tactic_genarg_level s with | Some n -> - let f = VFun(ist.trace,ist.lfun,[], + let f = VFun(extract_trace ist,ist.lfun,[], out_gen (glbwit (wit_tactic n)) x) in (* Special treatment of tactic arguments *) @@ -1976,21 +2007,30 @@ and interp_atomic ist gl tac = in let lfun = (List.map (fun (x,c) -> (x,f c)) l)@ist.lfun in - let trace = push_trace (loc,LtacNotationCall s) ist.trace in + let trace = push_trace (loc,LtacNotationCall s) ist in let gl = { gl with sigma = !evdref } in - interp_tactic { ist with lfun=lfun; trace=trace } body gl + let ist = { + lfun = lfun; + extra = TacStore.set ist.extra f_trace trace; } in + interp_tactic ist body gl (* Initial call for interpretation *) +let default_ist () = + let extra = TacStore.set TacStore.empty f_debug (get_debug ()) in + { lfun = []; extra = extra } + let eval_tactic t gls = db_initialize (); - interp_tactic { lfun=[]; avoid_ids=[]; debug=get_debug(); trace=[] } - t gls + interp_tactic (default_ist ()) t gls (* globalization + interpretation *) let interp_tac_gen lfun avoid_ids debug t gl = - interp_tactic { lfun=lfun; avoid_ids=avoid_ids; debug=debug; trace=[] } + let extra = TacStore.set TacStore.empty f_debug debug in + let extra = TacStore.set extra f_avoid_ids avoid_ids in + let ist = { lfun = lfun; extra = extra } in + interp_tactic ist (intern_pure_tactic { ltacvars = (List.map fst lfun, []); ltacrecvars = []; gsigma = project gl; genv = pf_env gl } t) gl @@ -1998,8 +2038,7 @@ let interp_tac_gen lfun avoid_ids debug t gl = let interp t = interp_tac_gen [] [] (get_debug()) t let eval_ltac_constr gl t = - interp_ltac_constr - { lfun=[]; avoid_ids=[]; debug=get_debug(); trace=[] } gl + interp_ltac_constr (default_ist ()) gl (intern_tactic_or_tacarg (make_empty_glob_sign ()) t ) (* Used to hide interpretation for pretty-print, now just launch tactics *) @@ -2017,7 +2056,7 @@ let hide_interp t ot gl = (* Other entry points *) let interp_redexp env sigma r = - let ist = { lfun=[]; avoid_ids=[]; debug=get_debug (); trace=[] } in + let ist = default_ist () in let gist = { fully_empty_glob_sign with genv = env; gsigma = sigma } in interp_red_expr ist sigma env (intern_red_expr gist r) @@ -2038,4 +2077,5 @@ let tacticIn t = let _ = Hook.set Auto.extern_interp (fun l -> let l = Id.Map.map (fun c -> Value.of_constr c) l in - interp_tactic {lfun=Id.Map.bindings l;avoid_ids=[];debug=get_debug(); trace=[]}) + let ist = { (default_ist ()) with lfun = Id.Map.bindings l; } in + interp_tactic ist) diff --git a/tactics/tacinterp.mli b/tactics/tacinterp.mli index 8395306b68..a0862fe8e3 100644 --- a/tactics/tacinterp.mli +++ b/tactics/tacinterp.mli @@ -32,12 +32,14 @@ end (** Values for interpretation *) type value = Value.t +module TacStore : Store.S + (** Signature for interpretation: val\_interp and interpretation functions *) -type interp_sign = - { lfun : (Id.t * value) list; - avoid_ids : Id.t list; - debug : debug_info; - trace : ltac_trace } +type interp_sign = { + lfun : (Id.t * value) list; + extra : TacStore.t } + +val f_avoid_ids : Id.t list TacStore.field val extract_ltac_constr_values : interp_sign -> Environ.env -> Pattern.constr_under_binders Id.Map.t * (Id.Map.key * Id.t option) list |
