(* Title: Pure/Isar/method.ML Author: Markus Wenzel, TU Muenchen
Isar proof methods.
*)
signature METHOD = sig type method = thm list -> context_tactic val CONTEXT_METHOD: (thm list -> context_tactic) -> method val METHOD: (thm list -> tactic) -> method val fail: method val succeed: method val insert_tac: Proof.context -> thm list -> int -> tactic val insert: thm list -> method val SIMPLE_METHOD: tactic -> method val SIMPLE_METHOD': (int -> tactic) -> method val SIMPLE_METHOD'': ((int -> tactic) -> tactic) -> (int -> tactic) -> method val goal_cases_tac: stringlist -> context_tactic val cheating: bool -> method val intro: Proof.context -> thm list -> method val elim: Proof.context -> thm list -> method val unfold: thm list -> Proof.context -> method val fold: thm list -> Proof.context -> method val atomize: bool -> Proof.context -> method val this: Proof.context -> method val fact: thm list -> Proof.context -> method val assm_tac: Proof.context -> int -> tactic val all_assm_tac: Proof.context -> tactic val assumption: Proof.context -> method val rule_trace: bool Config.T val trace: Proof.context -> thm list -> unit val rule_tac: Proof.context -> thm list -> thm list -> int -> tactic val some_rule_tac: Proof.context -> thm list -> thm list -> int -> tactic val intros_tac: Proof.context -> thm list -> thm list -> tactic val try_intros_tac: Proof.context -> thm list -> thm list -> tactic val rule: Proof.context -> thm list -> method val erule: Proof.context -> int -> thm list -> method val drule: Proof.context -> int -> thm list -> method val frule: Proof.context -> int -> thm list -> method val method_space: Context.generic -> Name_Space.T val set_tactic: (morphism -> thm list -> tactic) -> Context.generic -> Context.generic val clean_facts: thm list -> thm list val set_facts: thm list -> Proof.context -> Proof.context val get_facts: Proof.context -> thm list type combinator_info val no_combinator_info: combinator_info datatype combinator = Then | Then_All_New | Orelse | Try | Repeat1 | Select_Goals of int datatype text =
Source of Token.src |
Basic of Proof.context -> method |
Combinator of combinator_info * combinator * text list val map_source: (Token.src -> Token.src) -> text -> text val primitive_text: (Proof.context -> thm -> thm) -> text val succeed_text: text val standard_text: text val this_text: text val done_text: text val sorry_text: bool -> text val finish_text: text option * bool -> text val print_methods: bool -> Proof.context -> unit val check_name: Proof.context -> xstring * Position.T -> string val check_src: Proof.context -> Token.src -> Token.src val check_text: Proof.context -> text -> text val checked_text: text -> bool val method_syntax: (Proof.context -> method) context_parser ->
Token.src -> Proof.context -> method val setup: binding -> (Proof.context -> method) context_parser -> string -> theory -> theory val local_setup: binding -> (Proof.context -> method) context_parser -> string ->
local_theory -> local_theory val method_setup: bstring * Position.T -> Input.source -> string -> local_theory -> local_theory val method: Proof.context -> Token.src -> Proof.context -> method val method_closure: Proof.context -> Token.src -> Token.src val closure: bool Config.T val method_cmd: Proof.context -> Token.src -> Proof.context -> method val detect_closure_state: thm -> bool val STATIC: (unit -> unit) -> context_tactic val RUNTIME: context_tactic -> context_tactic val sleep: Time.time -> context_tactic val evaluate: text -> Proof.context -> method val evaluate_runtime: text -> Proof.context -> method type modifier = {init: Proof.context -> Proof.context, attribute: attribute, pos: Position.T} val modifier: attribute -> Position.T -> modifier val old_section_parser: bool Config.T val sections: modifier parser list -> unit context_parser type text_range = text * Position.range val text: text_range option -> text option val position: text_range option -> Position.T val reports_of: text_range -> Position.report list val report: text_range -> unit val parser: int -> text_range parser val parse: text_range parser val parse_by: ((text_range * text_range option) * Position.report list) parser val read: Proof.context -> Token.src -> text val read_closure: Proof.context -> Token.src -> text * Token.src val read_closure_input: Proof.context -> Input.source -> text * Token.src val text_closure: text context_parser end;
fun goal_cases_tac case_names : context_tactic =
fn (ctxt, st) => let val cases =
(if null case_names thenmap string_of_int (1 upto Thm.nprems_of st) else case_names)
|> map (rpair [] o rpair [])
|> Rule_Cases.make_common ctxt (Thm.prop_of (Rule_Cases.internalize_params st)); in CONTEXT_CASES cases all_tac (ctxt, st) end;
(* cheating *)
fun cheating int = CONTEXT_METHOD (fn _ => fn (ctxt, st) => if int orelse Config.get ctxt quick_and_dirty then
TACTIC_CONTEXT ctxt (ALLGOALS (Skip_Proof.cheat_tac ctxt) st) else error "Cheating requires quick_and_dirty mode!");
(* unfold intro/elim rules *)
fun intro ctxt ths = SIMPLE_METHOD' (CHANGED_PROP o REPEAT_ALL_NEW (match_tac ctxt ths)); fun elim ctxt ths = SIMPLE_METHOD' (CHANGED_PROP o REPEAT_ALL_NEW (ematch_tac ctxt ths));
(* unfold/fold definitions *)
fun unfold_meth ths ctxt = SIMPLE_METHOD (CHANGED_PROP (Local_Defs.unfold_tac ctxt ths)); fun fold_meth ths ctxt = SIMPLE_METHOD (CHANGED_PROP (Local_Defs.fold_tac ctxt ths));
(* atomize rule statements *)
fun atomize false ctxt =
SIMPLE_METHOD' (CHANGED_PROP o Object_Logic.atomize_prems_tac ctxt)
| atomize true ctxt =
Context_Tactic.CONTEXT_TACTIC o
K (HEADGOAL (CHANGED_PROP o Object_Logic.full_atomize_tac ctxt));
(* this -- resolve facts directly *)
fun this ctxt = METHOD (EVERY o map (HEADGOAL o resolve_tac ctxt o single));
fun all_assm_tac ctxt = let fun tac i st = if i > Thm.nprems_of st then all_tac st else ((assm_tac ctxt i THEN tac i) ORELSE tac (i + 1)) st; in tac 1 end;
fun assumption ctxt = METHOD (HEADGOAL o
(fn [] => assm_tac ctxt
| [fact] => solve_tac ctxt [fact]
| _ => K no_tac));
fun finish immed ctxt =
METHOD (K ((if immed then all_assm_tac ctxt else all_tac) THEN flexflex_tac ctxt));
end;
(* rule etc. -- single-step refinements *)
val rule_trace = Attrib.setup_config_bool \<^binding>\<open>rule_trace\<close> (fn _ => false);
fun trace ctxt rules = if Config.get ctxt rule_trace andalso not (null rules) then
Pretty.big_list "rules:" (map (Thm.pretty_thm_item ctxt) rules)
|> Pretty.string_of |> tracing else ();
local
fun gen_rule_tac tac ctxt rules facts =
(fn i => fn st => if null facts then tac ctxt rules i st else
Seq.maps (fn rule => (tac ctxt o single) rule i st)
(Drule.multi_resolves (SOME ctxt) facts rules))
THEN_ALL_NEW Goal.norm_hhf_tac ctxt;
fun primitive_text r = Basic (SIMPLE_METHOD o PRIMITIVE o r); val succeed_text = Basic (K succeed); val standard_text = Source (Token.make_src ("standard", Position.none) []); val this_text = Basic this; val done_text = Basic (K (SIMPLE_METHOD all_tac)); fun sorry_text int = Basic (fn _ => cheating int);
fun detect_closure_state st =
(casetry Logic.dest_term (Thm.concl_of (perhaps (try Goal.conclude) st)) of
NONE => false
| SOME t => Term.is_dummy_pattern t);
fun STATIC test : context_tactic =
fn (ctxt, st) => if detect_closure_state st then (test (); Seq.single (Seq.Result (ctxt, st))) else Seq.empty;
fun RUNTIME (tac: context_tactic) (ctxt, st) = if detect_closure_state st then Seq.empty else tac (ctxt, st);
fun sleep t = RUNTIME (fn ctxt_st => (OS.Process.sleep t; Seq.single (Seq.Result ctxt_st)));
(* evaluate method text *)
local
val op THEN = Seq.THEN;
fun BYPASS_CONTEXT (tac: tactic) =
fn result =>
(case result of
Seq.Error _ => Seq.single result
| Seq.Result (ctxt, st) => tac st |> TACTIC_CONTEXT ctxt);
val preparation = BYPASS_CONTEXT (ALLGOALS Goal.conjunction_tac);
fun RESTRICT_GOAL i n method =
BYPASS_CONTEXT (PRIMITIVE (Goal.restrict i n)) THEN
method THEN
BYPASS_CONTEXT (PRIMITIVE (Goal.unrestrict i));
fun SELECT_GOAL method i = RESTRICT_GOAL i 1 method;
fun (method1 THEN_ALL_NEW method2) i (result : context_state Seq.result) =
(case result of
Seq.Error _ => Seq.single result
| Seq.Result (_, st) =>
result |> method1 i
|> Seq.maps (fn result' =>
(case result' of
Seq.Error _ => Seq.single result'
| Seq.Result (_, st') =>
result' |> Seq.INTERVAL method2 i (i + Thm.nprems_of st' - Thm.nprems_of st))))
fun COMBINATOR1 comb [meth] = comb meth
| COMBINATOR1 _ _ = raise Fail "Method combinator requires exactly one argument";
fun evaluate text ctxt0 facts = let val ctxt = set_facts facts ctxt0; fun eval0 m = Seq.single #> Seq.maps_results (m facts); fun eval (Basic m) = eval0 (m ctxt)
| eval (Source src) = eval0 (method_cmd ctxt src ctxt)
| eval (Combinator (_, c, txts)) = combinator c (map eval txts); in eval text o Seq.Result end;
end;
fun evaluate_runtime text ctxt = let val text' =
text |> (map_source o map o Token.map_facts)
(fn SOME name =>
(case Proof_Context.lookup_fact ctxt name of
SOME {dynamic = true, thms} => K thms
| _ => I)
| NONE => I); val ctxt' = Config.put closure false ctxt; in fn facts => RUNTIME (fn st => evaluate text' ctxt' facts st) end;
val modifier_report =
(#1 (Token.range_of modifier_toks),
Position.entity_markup Markup.method_modifierN ("", pos)); val _ =
Context_Position.reports ctxt (modifier_report :: Token.reports_of_value tok0); val _ = Token.assign (SOME (Token.Declaration decl)) tok0; in decl end); in (Morphism.form decl context, decl) end));
in
fun sections ss =
Args.context :|-- (fn ctxt => if Config.get ctxt old_section_parser then old_sections ss else Scan.repeat (sect (Scan.first ss)) >> K ());
fun read ctxt src =
(case Scan.read Token.stopper (Parse.!!! (parser 0 --| Scan.ahead Parse.eof)) src of
SOME (text, range) => if checked_text text then text else (report (text, range); check_text ctxt text)
| NONE => error ("Failed to parse method" ^ Position.here (#1 (Token.range_of src))));
fun read_closure ctxt src0 = let val src1 = map Token.init_assignable src0; val text = read ctxt src1 |> map_source (method_closure ctxt); val src2 = map Token.closure src1; in (text, src2) end;
fun read_closure_input ctxt = letval keywords = Keyword.no_major_keywords (Thy_Header.get_keywords' ctxt) in Parse.read_embedded ctxt keywords (Scan.many Token.not_eof) #> read_closure ctxt end;
val text_closure =
Args.context -- Scan.lift (Parse.token Parse.embedded) >> (fn (ctxt, tok) =>
(case Token.get_value tok of
SOME (Token.Source src) => read ctxt src
| _ => let val (text, src) = read_closure_input ctxt (Token.input_of tok); val _ = Token.assign (SOME (Token.Source src)) tok; in text end));
(*final declarations of this structure!*) val unfold = unfold_meth; val fold = fold_meth;
end;
val CONTEXT_METHOD = Method.CONTEXT_METHOD; val METHOD = Method.METHOD; val SIMPLE_METHOD = Method.SIMPLE_METHOD; val SIMPLE_METHOD' = Method.SIMPLE_METHOD'; val SIMPLE_METHOD'' = Method.SIMPLE_METHOD'';
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.