src/Pure/Isar/method.ML
changeset 7555 dd281afb33d7
parent 7526 1ea137d3b5bf
child 7574 5bcb7fc31caa
equal deleted inserted replaced
7554:30327f9f6b4a 7555:dd281afb33d7
    17   val METHOD: (thm list -> tactic) -> Proof.method
    17   val METHOD: (thm list -> tactic) -> Proof.method
    18   val METHOD0: tactic -> Proof.method
    18   val METHOD0: tactic -> Proof.method
    19   val fail: Proof.method
    19   val fail: Proof.method
    20   val succeed: Proof.method
    20   val succeed: Proof.method
    21   val insert_tac: thm list -> int -> tactic
    21   val insert_tac: thm list -> int -> tactic
    22   val insert: Proof.method
    22   val insert_facts: Proof.method
    23   val fold: thm list -> Proof.method
    23   val fold: thm list -> Proof.method
    24   val unfold: thm list -> Proof.method
    24   val unfold: thm list -> Proof.method
    25   val multi_resolve: thm list -> thm -> thm Seq.seq
    25   val multi_resolve: thm list -> thm -> thm Seq.seq
    26   val multi_resolves: thm list -> thm list -> thm Seq.seq
    26   val multi_resolves: thm list -> thm list -> thm Seq.seq
    27   val rule_tac: thm list -> thm list -> int -> tactic
    27   val rule_tac: thm list -> thm list -> int -> tactic
    28   val erule_tac: thm list -> thm list -> int -> tactic
    28   val erule_tac: thm list -> thm list -> int -> tactic
    29   val rule: thm list -> Proof.method
    29   val rule: thm list -> Proof.method
    30   val erule: thm list -> Proof.method
    30   val erule: thm list -> Proof.method
    31   val assumption: Proof.method
    31   val assumption: Proof.context -> Proof.method
    32   exception METHOD_FAIL of (string * Position.T) * exn
    32   exception METHOD_FAIL of (string * Position.T) * exn
    33   val help_methods: theory -> unit
    33   val help_methods: theory -> unit
    34   val method: theory -> Args.src -> Proof.context -> Proof.method
    34   val method: theory -> Args.src -> Proof.context -> Proof.method
    35   val add_methods: (bstring * (Args.src -> Proof.context -> Proof.method) * string) list
    35   val add_methods: (bstring * (Args.src -> Proof.context -> Proof.method) * string) list
    36     -> theory -> theory
    36     -> theory -> theory
    37   val syntax: (Proof.context * Args.T list -> 'a * (Proof.context * Args.T list)) ->
    37   val syntax: (Proof.context * Args.T list -> 'a * (Proof.context * Args.T list)) ->
    38     Proof.context -> Args.src -> Proof.context * 'a
    38     Proof.context -> Args.src -> Proof.context * 'a
       
    39   val ctxt_args: (Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    39   val no_args: Proof.method -> Args.src -> Proof.context -> Proof.method
    40   val no_args: Proof.method -> Args.src -> Proof.context -> Proof.method
    40   type modifier
    41   type modifier
    41   val sectioned_args: ((Args.T list -> modifier * Args.T list) list ->
    42   val sectioned_args: ((Args.T list -> modifier * Args.T list) list ->
    42       Proof.context * Args.T list -> 'a * (Proof.context * Args.T list)) ->
    43       Proof.context * Args.T list -> 'a * (Proof.context * Args.T list)) ->
    43     (Args.T list -> modifier * Args.T list) list ->
    44     (Args.T list -> modifier * Args.T list) list ->
    44     ('a -> Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    45     ('a -> Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    45   val default_sectioned_args: modifier ->
    46   val bang_sectioned_args: (Args.T list -> modifier * Args.T list) list ->
    46     (Args.T list -> modifier * Args.T list) list ->
    47     (thm list -> Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    47     (Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
       
    48   val only_sectioned_args: (Args.T list -> modifier * Args.T list) list ->
    48   val only_sectioned_args: (Args.T list -> modifier * Args.T list) list ->
    49     (Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    49     (Proof.context -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    50   val thms_args: (thm list -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    50   val thms_args: (thm list -> Proof.method) -> Args.src -> Proof.context -> Proof.method
    51   datatype text =
    51   datatype text =
    52     Basic of (Proof.context -> Proof.method) |
    52     Basic of (Proof.context -> Proof.method) |
   100 
   100 
   101 fun cut_rule_tac raw_rule =
   101 fun cut_rule_tac raw_rule =
   102   let
   102   let
   103     val rule = Drule.forall_intr_vars raw_rule;
   103     val rule = Drule.forall_intr_vars raw_rule;
   104     val revcut_rl = Drule.incr_indexes_wrt [] [] [] [rule] Drule.revcut_rl;
   104     val revcut_rl = Drule.incr_indexes_wrt [] [] [] [rule] Drule.revcut_rl;
   105   in Tactic.rtac (rule COMP revcut_rl) THEN' Tactic.rotate_tac ~1 end;
   105   in Tactic.rtac (rule COMP revcut_rl) end;
   106 
   106 
   107 in
   107 in
   108 
   108 
   109 fun insert_tac [] i = all_tac
   109 fun insert_tac [] i = all_tac
   110   | insert_tac facts i = EVERY (map (fn th => cut_rule_tac th i) facts);
   110   | insert_tac facts i = EVERY (map (fn th => cut_rule_tac th i) facts);
   111 
   111 
   112 val insert = METHOD (ALLGOALS o insert_tac);
   112 val insert_facts = METHOD (ALLGOALS o insert_tac);
   113 
   113 
   114 end;
   114 end;
   115 
   115 
   116 
   116 
   117 (* fold / unfold definitions *)
   117 (* fold / unfold definitions *)
   118 
   118 
   119 fun fold thms = METHOD (fn _ => fold_goals_tac thms);
   119 fun fold thms = METHOD (fn facts => ALLGOALS (insert_tac facts) THEN fold_goals_tac thms);
   120 fun unfold thms = METHOD (fn _ => rewrite_goals_tac thms);
   120 fun unfold thms = METHOD (fn facts => ALLGOALS (insert_tac facts) THEN rewrite_goals_tac thms);
   121 
   121 
   122 
   122 
   123 (* multi_resolve *)
   123 (* multi_resolve *)
   124 
   124 
   125 local
   125 local
   158 fun erule rules = METHOD (FIRSTGOAL o erule_tac rules);
   158 fun erule rules = METHOD (FIRSTGOAL o erule_tac rules);
   159 
   159 
   160 end;
   160 end;
   161 
   161 
   162 
   162 
   163 (* assumption *)
   163 (* assumption / finish *)
   164 
   164 
   165 fun assumption_tac [] = assume_tac
   165 fun assm_tac ctxt =
   166   | assumption_tac [fact] = resolve_tac [fact]
   166   assume_tac APPEND' resolve_tac (filter Thm.no_prems (ProofContext.prems_of ctxt));
   167   | assumption_tac _ = K no_tac;
   167 
   168 
   168 fun assumption_tac ctxt [] = assm_tac ctxt
   169 val assumption = METHOD (FIRSTGOAL o assumption_tac);
   169   | assumption_tac _ [fact] = resolve_tac [fact]
       
   170   | assumption_tac _ _ = K no_tac;
       
   171 
       
   172 fun assumption ctxt = METHOD (FIRSTGOAL o assumption_tac ctxt);
       
   173 fun finish ctxt = METHOD (K (FILTER Thm.no_prems (ALLGOALS (assm_tac ctxt))));
   170 
   174 
   171 
   175 
   172 
   176 
   173 (** methods theory data **)
   177 (** methods theory data **)
   174 
   178 
   254 (* basic *)
   258 (* basic *)
   255 
   259 
   256 fun syntax (scan: (Proof.context * Args.T list -> 'a * (Proof.context * Args.T list))) =
   260 fun syntax (scan: (Proof.context * Args.T list -> 'a * (Proof.context * Args.T list))) =
   257   Args.syntax "method" scan;
   261   Args.syntax "method" scan;
   258 
   262 
   259 fun no_args (x: Proof.method) src ctxt = #2 (syntax (Scan.succeed x) ctxt src);
   263 fun ctxt_args (f: Proof.context -> Proof.method) src ctxt =
       
   264   #2 (syntax (Scan.succeed (f ctxt)) ctxt src);
       
   265 
       
   266 fun no_args m = ctxt_args (K m);
   260 
   267 
   261 
   268 
   262 (* sections *)
   269 (* sections *)
   263 
   270 
   264 type modifier = (Proof.context -> Proof.context) * Proof.context attribute;
   271 type modifier = (Proof.context -> Proof.context) * Proof.context attribute;
   280 
   287 
   281 fun sectioned_args args ss f src ctxt =
   288 fun sectioned_args args ss f src ctxt =
   282   let val (ctxt', (x, _)) = syntax (sectioned args ss) ctxt src
   289   let val (ctxt', (x, _)) = syntax (sectioned args ss) ctxt src
   283   in f x ctxt' end;
   290   in f x ctxt' end;
   284 
   291 
   285 fun default_sectioned_args m ss f src ctxt =
   292 fun bang_sectioned_args ss f = sectioned_args (K Args.bang_facts) ss f;
   286   sectioned_args thmss ss (fn ths => fn ctxt' => f (#1 (apply m (ctxt', ths)))) src ctxt;
       
   287 
       
   288 fun only_sectioned_args ss f = sectioned_args (K (Scan.succeed ())) ss (fn () => f);
   293 fun only_sectioned_args ss f = sectioned_args (K (Scan.succeed ())) ss (fn () => f);
   289 
   294 
   290 fun thms_args f = sectioned_args thmss [] (fn ths => fn _ => f ths);
   295 fun thms_args f = sectioned_args thmss [] (fn ths => fn _ => f ths);
   291 
   296 
   292 end;
   297 end;
   324   state
   329   state
   325   |> Proof.goal_facts (K [])
   330   |> Proof.goal_facts (K [])
   326   |> refine text;
   331   |> refine text;
   327 
   332 
   328 
   333 
   329 (* finish *)
       
   330 
       
   331 val FINISHED = FILTER (equal 0 o Thm.nprems_of);
       
   332 val finish = METHOD (K (FINISHED (ALLGOALS assume_tac)));
       
   333 val basic_finish = Basic (K finish);
       
   334 
       
   335 fun finish_text None = basic_finish
       
   336   | finish_text (Some txt) = Then [txt, basic_finish];
       
   337 
       
   338 
       
   339 (* structured proof steps *)
   334 (* structured proof steps *)
   340 
   335 
   341 val default_text = Source (Args.src (("default", []), Position.none));
   336 val default_text = Source (Args.src (("default", []), Position.none));
   342 val assumption_text = Basic (K assumption);
   337 
       
   338 fun finish_text None = Basic finish
       
   339   | finish_text (Some txt) = Then [txt, Basic finish];
   343 
   340 
   344 fun proof opt_text state =
   341 fun proof opt_text state =
   345   state
   342   state
   346   |> Proof.assert_backward
   343   |> Proof.assert_backward
   347   |> refine (if_none opt_text default_text)
   344   |> refine (if_none opt_text default_text)
   348   |> Seq.map Proof.enter_forward;
   345   |> Seq.map Proof.enter_forward;
   349 
   346 
   350 fun local_qed opt_text = Proof.local_qed (refine (finish_text opt_text));
   347 fun local_qed opt_text = Proof.local_qed (refine (finish_text opt_text));
   351 fun local_terminal_proof (text, opt_text) pr = Seq.THEN (proof (Some text), local_qed opt_text pr);
   348 fun local_terminal_proof (text, opt_text) pr = Seq.THEN (proof (Some text), local_qed opt_text pr);
   352 val local_immediate_proof = local_terminal_proof (assumption_text, None);
   349 val local_immediate_proof = local_terminal_proof (Basic assumption, None);
   353 val local_default_proof = local_terminal_proof (default_text, None);
   350 val local_default_proof = local_terminal_proof (default_text, None);
   354 
   351 
   355 
   352 
   356 fun global_qeds opt_text = Proof.global_qed (refine (finish_text opt_text));
   353 fun global_qeds opt_text = Proof.global_qed (refine (finish_text opt_text));
   357 
   354 
   367   |> Proof.check_result "Terminal proof method failed" state
   364   |> Proof.check_result "Terminal proof method failed" state
   368   |> (Seq.flat o Seq.map (global_qeds opt_text))
   365   |> (Seq.flat o Seq.map (global_qeds opt_text))
   369   |> Proof.check_result "Failed to finish proof (after successful terminal method)" state
   366   |> Proof.check_result "Failed to finish proof (after successful terminal method)" state
   370   |> Seq.hd;
   367   |> Seq.hd;
   371 
   368 
   372 val global_immediate_proof = global_terminal_proof (assumption_text, None);
   369 val global_immediate_proof = global_terminal_proof (Basic assumption, None);
   373 val global_default_proof = global_terminal_proof (default_text, None);
   370 val global_default_proof = global_terminal_proof (default_text, None);
   374 
   371 
   375 
   372 
   376 
   373 
   377 (** theory setup **)
   374 (** theory setup **)
   379 (* pure_methods *)
   376 (* pure_methods *)
   380 
   377 
   381 val pure_methods =
   378 val pure_methods =
   382  [("fail", no_args fail, "force failure"),
   379  [("fail", no_args fail, "force failure"),
   383   ("succeed", no_args succeed, "succeed"),
   380   ("succeed", no_args succeed, "succeed"),
   384   ("-", no_args insert, "insert facts, nothing else"),
   381   ("-", no_args insert_facts, "insert facts"),
   385   ("fold", thms_args fold, "fold definitions"),
   382   ("fold", thms_args fold, "fold definitions, ignoring facts"),
   386   ("unfold", thms_args unfold, "unfold definitions"),
   383   ("unfold", thms_args unfold, "unfold definitions, ignoring facts"),
   387   ("rule", thms_args rule, "apply some rule"),
   384   ("rule", thms_args rule, "apply some rule"),
   388   ("erule", thms_args erule, "apply some erule (improper!)"),
   385   ("erule", thms_args erule, "apply some erule (improper!)"),
   389   ("assumption", no_args assumption, "proof by assumption")];
   386   ("assumption", ctxt_args assumption, "proof by assumption, preferring facts")];
   390 
   387 
   391 
   388 
   392 (* setup *)
   389 (* setup *)
   393 
   390 
   394 val setup = [MethodsData.init, add_methods pure_methods];
   391 val setup = [MethodsData.init, add_methods pure_methods];