src/Pure/Isar/method.ML
changeset 70520 11d8517d9384
parent 69575 f77cc54f6d47
child 70521 9ddd66d53130
equal deleted inserted replaced
70519:67580f2ded90 70520:11d8517d9384
     2     Author:     Markus Wenzel, TU Muenchen
     2     Author:     Markus Wenzel, TU Muenchen
     3 
     3 
     4 Isar proof methods.
     4 Isar proof methods.
     5 *)
     5 *)
     6 
     6 
     7 infix 1 CONTEXT_THEN_ALL_NEW;
       
     8 
       
     9 signature BASIC_METHOD =
       
    10 sig
       
    11   type context_state = Proof.context * thm
       
    12   type context_tactic = context_state -> context_state Seq.result Seq.seq
       
    13   val CONTEXT_CASES: Rule_Cases.cases -> tactic -> context_tactic
       
    14   val CONTEXT_SUBGOAL: (term * int -> context_tactic) -> int -> context_tactic
       
    15   val CONTEXT_THEN_ALL_NEW: (int -> context_tactic) * (int -> tactic) -> int -> context_tactic
       
    16 end;
       
    17 
       
    18 signature METHOD =
     7 signature METHOD =
    19 sig
     8 sig
    20   include BASIC_METHOD
       
    21   type method = thm list -> context_tactic
     9   type method = thm list -> context_tactic
    22   val CONTEXT: Proof.context -> thm Seq.seq -> context_state Seq.result Seq.seq
       
    23   val CONTEXT_TACTIC: tactic -> context_tactic
       
    24   val NO_CONTEXT_TACTIC: Proof.context -> context_tactic -> tactic
       
    25   val CONTEXT_METHOD: (thm list -> context_tactic) -> method
    10   val CONTEXT_METHOD: (thm list -> context_tactic) -> method
    26   val METHOD: (thm list -> tactic) -> method
    11   val METHOD: (thm list -> tactic) -> method
    27   val fail: method
    12   val fail: method
    28   val succeed: method
    13   val succeed: method
    29   val insert_tac: Proof.context -> thm list -> int -> tactic
    14   val insert_tac: Proof.context -> thm list -> int -> tactic
   113 structure Method: METHOD =
    98 structure Method: METHOD =
   114 struct
    99 struct
   115 
   100 
   116 (** proof methods **)
   101 (** proof methods **)
   117 
   102 
   118 (* tactics with proof context / cases *)
       
   119 
       
   120 type context_state = Proof.context * thm;
       
   121 type context_tactic = context_state -> context_state Seq.result Seq.seq;
       
   122 
       
   123 fun CONTEXT ctxt : thm Seq.seq -> context_state Seq.result Seq.seq =
       
   124   Seq.map (Seq.Result o pair ctxt);
       
   125 
       
   126 fun CONTEXT_TACTIC tac : context_tactic =
       
   127   fn (ctxt, st) => CONTEXT ctxt (tac st);
       
   128 
       
   129 fun NO_CONTEXT_TACTIC ctxt (tac: context_tactic) st =
       
   130   tac (ctxt, st) |> Seq.filter_results |> Seq.map snd;
       
   131 
       
   132 fun CONTEXT_CASES cases tac : context_tactic =
       
   133   fn (ctxt, st) => CONTEXT (Proof_Context.update_cases cases ctxt) (tac st);
       
   134 
       
   135 fun CONTEXT_SUBGOAL tac i : context_tactic =
       
   136   fn (ctxt, st) =>
       
   137     (case try Logic.nth_prem (i, Thm.prop_of st) of
       
   138       SOME goal => tac (goal, i) (ctxt, st)
       
   139     | NONE => Seq.empty);
       
   140 
       
   141 fun (tac1 CONTEXT_THEN_ALL_NEW tac2) i : context_tactic =
       
   142   fn (ctxt, st) =>
       
   143     (ctxt, st) |> tac1 i |> Seq.maps_results (fn (ctxt', st') =>
       
   144       CONTEXT ctxt' ((Seq.INTERVAL tac2 i (i + Thm.nprems_of st' - Thm.nprems_of st)) st'));
       
   145 
       
   146 
       
   147 (* type method *)
   103 (* type method *)
   148 
   104 
   149 type method = thm list -> context_tactic;
   105 type method = thm list -> context_tactic;
   150 
   106 
   151 fun CONTEXT_METHOD tac : method =
   107 fun CONTEXT_METHOD tac : method =
   163 fun insert_tac _ [] _ = all_tac
   119 fun insert_tac _ [] _ = all_tac
   164   | insert_tac ctxt facts i =
   120   | insert_tac ctxt facts i =
   165       EVERY (map (fn r => resolve_tac ctxt [Drule.forall_intr_vars r COMP_INCR revcut_rl] i) facts);
   121       EVERY (map (fn r => resolve_tac ctxt [Drule.forall_intr_vars r COMP_INCR revcut_rl] i) facts);
   166 
   122 
   167 fun insert thms =
   123 fun insert thms =
   168   CONTEXT_METHOD (fn _ => fn (ctxt, st) => st |> ALLGOALS (insert_tac ctxt thms) |> CONTEXT ctxt);
   124   CONTEXT_METHOD (fn _ => fn (ctxt, st) =>
       
   125     st |> ALLGOALS (insert_tac ctxt thms) |> TACTIC_CONTEXT ctxt);
   169 
   126 
   170 
   127 
   171 fun SIMPLE_METHOD tac =
   128 fun SIMPLE_METHOD tac =
   172   CONTEXT_METHOD (fn facts => fn (ctxt, st) =>
   129   CONTEXT_METHOD (fn facts => fn (ctxt, st) =>
   173     st |> (ALLGOALS (insert_tac ctxt facts) THEN tac) |> CONTEXT ctxt);
   130     st |> (ALLGOALS (insert_tac ctxt facts) THEN tac) |> TACTIC_CONTEXT ctxt);
   174 
   131 
   175 fun SIMPLE_METHOD'' quant tac =
   132 fun SIMPLE_METHOD'' quant tac =
   176   CONTEXT_METHOD (fn facts => fn (ctxt, st) =>
   133   CONTEXT_METHOD (fn facts => fn (ctxt, st) =>
   177     st |> quant (insert_tac ctxt facts THEN' tac) |> CONTEXT ctxt);
   134     st |> quant (insert_tac ctxt facts THEN' tac) |> TACTIC_CONTEXT ctxt);
   178 
   135 
   179 val SIMPLE_METHOD' = SIMPLE_METHOD'' HEADGOAL;
   136 val SIMPLE_METHOD' = SIMPLE_METHOD'' HEADGOAL;
   180 
   137 
   181 
   138 
   182 (* goals as cases *)
   139 (* goals as cases *)
   193 
   150 
   194 (* cheating *)
   151 (* cheating *)
   195 
   152 
   196 fun cheating int = CONTEXT_METHOD (fn _ => fn (ctxt, st) =>
   153 fun cheating int = CONTEXT_METHOD (fn _ => fn (ctxt, st) =>
   197   if int orelse Config.get ctxt quick_and_dirty then
   154   if int orelse Config.get ctxt quick_and_dirty then
   198     CONTEXT ctxt (ALLGOALS (Skip_Proof.cheat_tac ctxt) st)
   155     TACTIC_CONTEXT ctxt (ALLGOALS (Skip_Proof.cheat_tac ctxt) st)
   199   else error "Cheating requires quick_and_dirty mode!");
   156   else error "Cheating requires quick_and_dirty mode!");
   200 
   157 
   201 
   158 
   202 (* unfold intro/elim rules *)
   159 (* unfold intro/elim rules *)
   203 
   160 
   214 (* atomize rule statements *)
   171 (* atomize rule statements *)
   215 
   172 
   216 fun atomize false ctxt =
   173 fun atomize false ctxt =
   217       SIMPLE_METHOD' (CHANGED_PROP o Object_Logic.atomize_prems_tac ctxt)
   174       SIMPLE_METHOD' (CHANGED_PROP o Object_Logic.atomize_prems_tac ctxt)
   218   | atomize true ctxt =
   175   | atomize true ctxt =
   219       CONTEXT_TACTIC o K (HEADGOAL (CHANGED_PROP o Object_Logic.full_atomize_tac ctxt));
   176       Context_Tactic.CONTEXT_TACTIC o
       
   177         K (HEADGOAL (CHANGED_PROP o Object_Logic.full_atomize_tac ctxt));
   220 
   178 
   221 
   179 
   222 (* this -- resolve facts directly *)
   180 (* this -- resolve facts directly *)
   223 
   181 
   224 fun this ctxt = METHOD (EVERY o map (HEADGOAL o resolve_tac ctxt o single));
   182 fun this ctxt = METHOD (EVERY o map (HEADGOAL o resolve_tac ctxt o single));
   528 
   486 
   529 fun BYPASS_CONTEXT (tac: tactic) =
   487 fun BYPASS_CONTEXT (tac: tactic) =
   530   fn result =>
   488   fn result =>
   531     (case result of
   489     (case result of
   532       Seq.Error _ => Seq.single result
   490       Seq.Error _ => Seq.single result
   533     | Seq.Result (ctxt, st) => tac st |> CONTEXT ctxt);
   491     | Seq.Result (ctxt, st) => tac st |> TACTIC_CONTEXT ctxt);
   534 
   492 
   535 val preparation = BYPASS_CONTEXT (ALLGOALS Goal.conjunction_tac);
   493 val preparation = BYPASS_CONTEXT (ALLGOALS Goal.conjunction_tac);
   536 
   494 
   537 fun RESTRICT_GOAL i n method =
   495 fun RESTRICT_GOAL i n method =
   538   BYPASS_CONTEXT (PRIMITIVE (Goal.restrict i n)) THEN
   496   BYPASS_CONTEXT (PRIMITIVE (Goal.restrict i n)) THEN
   837   setup \<^binding>\<open>rotate_tac\<close> (Args.goal_spec -- Scan.lift (Scan.optional Parse.int 1) >>
   795   setup \<^binding>\<open>rotate_tac\<close> (Args.goal_spec -- Scan.lift (Scan.optional Parse.int 1) >>
   838     (fn (quant, i) => K (SIMPLE_METHOD'' quant (rotate_tac i))))
   796     (fn (quant, i) => K (SIMPLE_METHOD'' quant (rotate_tac i))))
   839       "rotate assumptions of goal" #>
   797       "rotate assumptions of goal" #>
   840   setup \<^binding>\<open>tactic\<close> (parse_tactic >> (K o METHOD))
   798   setup \<^binding>\<open>tactic\<close> (parse_tactic >> (K o METHOD))
   841     "ML tactic as proof method" #>
   799     "ML tactic as proof method" #>
   842   setup \<^binding>\<open>raw_tactic\<close> (parse_tactic >> (fn tac => fn _ => CONTEXT_TACTIC o tac))
   800   setup \<^binding>\<open>raw_tactic\<close> (parse_tactic >> (fn tac => fn _ => Context_Tactic.CONTEXT_TACTIC o tac))
   843     "ML tactic as raw proof method" #>
   801     "ML tactic as raw proof method" #>
   844   setup \<^binding>\<open>use\<close>
   802   setup \<^binding>\<open>use\<close>
   845     (Attrib.thms -- (Scan.lift (Parse.$$$ "in") |-- text_closure) >>
   803     (Attrib.thms -- (Scan.lift (Parse.$$$ "in") |-- text_closure) >>
   846       (fn (thms, text) => fn ctxt => fn _ => evaluate_runtime text ctxt thms))
   804       (fn (thms, text) => fn ctxt => fn _ => evaluate_runtime text ctxt thms))
   847     "indicate method facts and context for method expression");
   805     "indicate method facts and context for method expression");
   851 val unfold = unfold_meth;
   809 val unfold = unfold_meth;
   852 val fold = fold_meth;
   810 val fold = fold_meth;
   853 
   811 
   854 end;
   812 end;
   855 
   813 
   856 structure Basic_Method: BASIC_METHOD = Method;
       
   857 open Basic_Method;
       
   858 
       
   859 val CONTEXT_METHOD = Method.CONTEXT_METHOD;
   814 val CONTEXT_METHOD = Method.CONTEXT_METHOD;
   860 val METHOD = Method.METHOD;
   815 val METHOD = Method.METHOD;
   861 val SIMPLE_METHOD = Method.SIMPLE_METHOD;
   816 val SIMPLE_METHOD = Method.SIMPLE_METHOD;
   862 val SIMPLE_METHOD' = Method.SIMPLE_METHOD';
   817 val SIMPLE_METHOD' = Method.SIMPLE_METHOD';
   863 val SIMPLE_METHOD'' = Method.SIMPLE_METHOD'';
   818 val SIMPLE_METHOD'' = Method.SIMPLE_METHOD'';