1(* Title: HOL/Eisbach/Eisbach.thy
2 Author: Daniel Matichuk, NICTA/UNSW
34Main entry point for Eisbach proof method language.
5*)67theoryEisbach8importsPure9keywords10"method":: thy_decl and11"conclusion"12"declares"13"methods"14"¦""⇒"15"uses"16begin1718ML_file‹parse_tools.ML›19ML_file‹method_closure.ML›20ML_file‹eisbach_rule_insts.ML›21ML_file‹match_method.ML›2223methodsolvesmethodsm‹Apply method only when it solves the goal›=m;fail2425methodrepeat_newmethodsm26‹apply method recursively to the subgoals it generates›=27(m;(repeat_new‹m›)?)282930section‹Debugging methods›3132method_setupprint_raw_goal=‹Scan.succeed(fnctxt=>fnfacts=>33(fn(ctxt,st)=>(34Output.writeln(Thm.string_of_thmctxtst);35Seq.make_results(Seq.single(ctxt,st)))))›36‹print the entire goal statement›3738method_setupprint_headgoal=39‹Scan.succeed(fnctxt=>fn_=>fn(ctxt',thm)=>40((SUBGOAL(fn(t,_)=>41(Output.writeln42(Pretty.string_of(Syntax.pretty_termctxtt));all_tac))1thm);43(Seq.make_results(Seq.single(ctxt',thm)))))›44‹print the first subgoal›4546ML‹funmethod_evaluatetextctxtfacts=47NO_CONTEXT_TACTICctxt48(Method.evaluate_runtimetextctxtfacts)›4950method_setuptimeit=51‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>52let53funtimed_tacstseq=Seq.make(fn()=>Option.map(apsnd(timed_tacst))54(timeit(fn()=>(Seq.pullseq))));5556funtacst'=57timed_tacst'(method_evaluatemctxtfactsst');5859inSIMPLE_METHODtac[]end)60 ›61‹print timing information from running the parameter method›626364section‹Simple Combinators›6566method_setupdefer_tac=67‹Scan.succeed(fn_=>SIMPLE_METHOD(defer_tac1))›68‹make first subgoal the last subgoal. Like "defer" but as proof method›6970method_setupprefer_last=71‹Scan.succeed(fn_=>SIMPLE_METHOD(PRIMITIVE(Thm.permute_prems0~1)))›72‹make last subgoal the first subgoal.›737475method_setupall=76‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>77let78funtacist'=79Goal.restricti1st'80|>method_evaluatemctxtfacts81|>Seq.map(Goal.unrestricti)8283inSIMPLE_METHOD(ALLGOALStac)factsend)84 ›85‹apply parameter method to all subgoals›8687method_setupdeterm=88‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>89let90funtacst'=method_evaluatemctxtfactsst'9192inSIMPLE_METHOD(DETERMtac)factsend)93 ›94‹constrain result sequence to 0 or 1 elements›9596method_setupchanged=97‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>98let99funtacst'=method_evaluatemctxtfactsst'100101inSIMPLE_METHOD(CHANGEDtac)factsend)102 ›103‹fail if the proof state has not changed after parameter method has run›104105106text‹The following ‹fails› and ‹succeeds› methods protect the goal from the effect
107 of a method, instead simply determining whether or not it can be applied to the current goal.
108 The ‹fails› method inverts success, only succeeding if the given method would fail.›109110method_setupfails=111‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>112let113funfail_tacst'=114(caseSeq.pull(method_evaluatemctxtfactsst')of115SOME_=>Seq.empty116|NONE=>Seq.singlest')117118inSIMPLE_METHODfail_tacfactsend)119 ›120‹succeed if the parameter method fails›121122method_setupsucceeds=123‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>124let125funcan_tacst'=126(caseSeq.pull(method_evaluatemctxtfactsst')of127SOME(st'',_)=>Seq.singlest'128|NONE=>Seq.empty)129130inSIMPLE_METHODcan_tacfactsend)131 ›132‹succeed without proof state change if the parameter method has non-empty result sequence›133134135136text‹Finding a goal based on successful application of a method›137138method_setupfind_goal=139‹Method.text_closure>>(fnm=>fnctxt=>fnfacts=>140let141funprefer_firsti=SELECT_GOAL142(fnst'=>143(caseSeq.pull(method_evaluatemctxtfactsst')of144SOME(st'',_)=>Seq.singlest''145|NONE=>Seq.empty))iTHENprefer_taci146147inSIMPLE_METHOD(FIRSTGOALprefer_first)factsend)›148‹find first subgoal where parameter method succeeds, make this the first subgoal, and run method›149150end151