src/Pure/Isar/proof.ML
changeset 29383 223f18cfbb32
parent 29381 45d77aeb1608
child 29385 c96b91bab2e6
equal deleted inserted replaced
29382:9f6e2658a868 29383:223f18cfbb32
    85   val apply: Method.text -> state -> state Seq.seq
    85   val apply: Method.text -> state -> state Seq.seq
    86   val apply_end: Method.text -> state -> state Seq.seq
    86   val apply_end: Method.text -> state -> state Seq.seq
    87   val local_goal: (context -> ((string * string) * (string * thm list) list) -> unit) ->
    87   val local_goal: (context -> ((string * string) * (string * thm list) list) -> unit) ->
    88     (theory -> 'a -> attribute) ->
    88     (theory -> 'a -> attribute) ->
    89     (context * 'b list -> context * (term list list * (context -> context))) ->
    89     (context * 'b list -> context * (term list list * (context -> context))) ->
    90     string -> Method.text option -> (thm list list -> state -> state Seq.seq) ->
    90     string -> Method.text option -> (thm list list -> state -> state) ->
    91     ((Binding.T * 'a list) * 'b) list -> state -> state
    91     ((Binding.T * 'a list) * 'b) list -> state -> state
    92   val local_qed: Method.text option * bool -> state -> state Seq.seq
    92   val local_qed: Method.text option * bool -> state -> state
    93   val theorem: Method.text option -> (thm list list -> context -> context) ->
    93   val theorem: Method.text option -> (thm list list -> context -> context) ->
    94     (string * string list) list list -> context -> state
    94     (string * string list) list list -> context -> state
    95   val theorem_i: Method.text option -> (thm list list -> context -> context) ->
    95   val theorem_i: Method.text option -> (thm list list -> context -> context) ->
    96     (term * term list) list list -> context -> state
    96     (term * term list) list list -> context -> state
    97   val global_qed: Method.text option * bool -> state -> context
    97   val global_qed: Method.text option * bool -> state -> context
    98   val local_terminal_proof: Method.text * Method.text option -> state -> state Seq.seq
    98   val local_terminal_proof: Method.text * Method.text option -> state -> state
    99   val local_default_proof: state -> state Seq.seq
    99   val local_default_proof: state -> state
   100   val local_immediate_proof: state -> state Seq.seq
   100   val local_immediate_proof: state -> state
   101   val local_done_proof: state -> state Seq.seq
   101   val local_skip_proof: bool -> state -> state
   102   val local_skip_proof: bool -> state -> state Seq.seq
   102   val local_done_proof: state -> state
   103   val global_terminal_proof: Method.text * Method.text option -> state -> context
   103   val global_terminal_proof: Method.text * Method.text option -> state -> context
   104   val global_default_proof: state -> context
   104   val global_default_proof: state -> context
   105   val global_immediate_proof: state -> context
   105   val global_immediate_proof: state -> context
       
   106   val global_skip_proof: bool -> state -> context
   106   val global_done_proof: state -> context
   107   val global_done_proof: state -> context
   107   val global_skip_proof: bool -> state -> context
   108   val have: Method.text option -> (thm list list -> state -> state) ->
   108   val have: Method.text option -> (thm list list -> state -> state Seq.seq) ->
       
   109     (Attrib.binding * (string * string list) list) list -> bool -> state -> state
   109     (Attrib.binding * (string * string list) list) list -> bool -> state -> state
   110   val have_i: Method.text option -> (thm list list -> state -> state Seq.seq) ->
   110   val have_i: Method.text option -> (thm list list -> state -> state) ->
   111     ((Binding.T * attribute list) * (term * term list) list) list -> bool -> state -> state
   111     ((Binding.T * attribute list) * (term * term list) list) list -> bool -> state -> state
   112   val show: Method.text option -> (thm list list -> state -> state Seq.seq) ->
   112   val show: Method.text option -> (thm list list -> state -> state) ->
   113     (Attrib.binding * (string * string list) list) list -> bool -> state -> state
   113     (Attrib.binding * (string * string list) list) list -> bool -> state -> state
   114   val show_i: Method.text option -> (thm list list -> state -> state Seq.seq) ->
   114   val show_i: Method.text option -> (thm list list -> state -> state) ->
   115     ((Binding.T * attribute list) * (term * term list) list) list -> bool -> state -> state
   115     ((Binding.T * attribute list) * (term * term list) list) list -> bool -> state -> state
   116   val is_relevant: state -> bool
   116   val is_relevant: state -> bool
   117   val future_proof: (state -> ('a * context) future) -> state -> 'a future * context
   117   val future_proof: (state -> ('a * context) future) -> state -> 'a future * context
   118   val future_terminal_proof: Method.text * Method.text option -> bool -> state -> context
   118   val future_terminal_proof: Method.text * Method.text option -> bool -> state -> context
   119 end;
   119 end;
   146     messages: (unit -> Pretty.T) list,    (*persistent messages (hints etc.)*)
   146     messages: (unit -> Pretty.T) list,    (*persistent messages (hints etc.)*)
   147     using: thm list,                      (*goal facts*)
   147     using: thm list,                      (*goal facts*)
   148     goal: thm,                            (*subgoals ==> statement*)
   148     goal: thm,                            (*subgoals ==> statement*)
   149     before_qed: Method.text option,
   149     before_qed: Method.text option,
   150     after_qed:
   150     after_qed:
   151       (thm list list -> state -> state Seq.seq) *
   151       (thm list list -> state -> state) *
   152       (thm list list -> context -> context)};
   152       (thm list list -> context -> context)};
   153 
   153 
   154 fun make_goal (statement, messages, using, goal, before_qed, after_qed) =
   154 fun make_goal (statement, messages, using, goal, before_qed, after_qed) =
   155   Goal {statement = statement, messages = messages, using = using, goal = goal,
   155   Goal {statement = statement, messages = messages, using = using, goal = goal,
   156     before_qed = before_qed, after_qed = after_qed};
   156     before_qed = before_qed, after_qed = after_qed};
   345 
   345 
   346     fun description strs =
   346     fun description strs =
   347       (case filter_out (fn s => s = "") strs of [] => ""
   347       (case filter_out (fn s => s = "") strs of [] => ""
   348       | strs' => enclose " (" ")" (commas strs'));
   348       | strs' => enclose " (" ")" (commas strs'));
   349 
   349 
   350     fun prt_goal (SOME (ctxt, (i,
   350     fun prt_goal (SOME (ctxt, (i, {statement = ((_, pos), _, _), messages, using, goal, ...}))) =
   351             {statement = ((_, pos), _, _), messages, using, goal, before_qed, after_qed}))) =
       
   352           pretty_facts "using " ctxt
   351           pretty_facts "using " ctxt
   353             (if mode <> Backward orelse null using then NONE else SOME using) @
   352             (if mode <> Backward orelse null using then NONE else SOME using) @
   354           [Pretty.str ("goal" ^
   353           [Pretty.str ("goal" ^
   355             description [levels_up (i div 2), subgoals (Thm.nprems_of goal)] ^ ":")] @
   354             description [levels_up (i div 2), subgoals (Thm.nprems_of goal)] ^ ":")] @
   356           pretty_goals_local ctxt Markup.subgoal
   355           pretty_goals_local ctxt Markup.subgoal
   748   |> close_block
   747   |> close_block
   749   |> assert_current_goal true
   748   |> assert_current_goal true
   750   |> using_facts []
   749   |> using_facts []
   751   |> `before_qed |-> (refine o the_default Method.succeed_text)
   750   |> `before_qed |-> (refine o the_default Method.succeed_text)
   752   |> Seq.maps (refine (Method.finish_text txt (Position.thread_data ())));
   751   |> Seq.maps (refine (Method.finish_text txt (Position.thread_data ())));
       
   752 
       
   753 fun check_result msg sq =
       
   754   (case Seq.pull sq of
       
   755     NONE => error msg
       
   756   | SOME (s, _) => s);
       
   757 
       
   758 fun check_finish sq = check_result "Failed to finish proof" sq;
   753 
   759 
   754 
   760 
   755 (* unstructured refinement *)
   761 (* unstructured refinement *)
   756 
   762 
   757 fun defer i = assert_no_chain #> refine (Method.Basic (K (Method.defer i), Position.none));
   763 fun defer i = assert_no_chain #> refine (Method.Basic (K (Method.defer i), Position.none));
   840     val results =
   846     val results =
   841       tl (conclude_goal goal_ctxt goal stmt)
   847       tl (conclude_goal goal_ctxt goal stmt)
   842       |> burrow (ProofContext.export goal_ctxt outer_ctxt);
   848       |> burrow (ProofContext.export goal_ctxt outer_ctxt);
   843 
   849 
   844     val (after_local, after_global) = after_qed;
   850     val (after_local, after_global) = after_qed;
   845     fun after_local' x y = Position.setmp_thread_data_seq pos (fn () => after_local x y) ();
   851     fun after_local' x y = Position.setmp_thread_data pos (fn () => after_local x y) ();
   846     fun after_global' x y = Position.setmp_thread_data pos (fn () => after_global x y) ();
   852     fun after_global' x y = Position.setmp_thread_data pos (fn () => after_global x y) ();
   847   in
   853   in
   848     outer_state
   854     outer_state
   849     |> map_context (after_ctxt props)
   855     |> map_context (after_ctxt props)
   850     |> pair ((after_local', after_global'), results)
   856     |> pair ((after_local', after_global'), results)
   869     state
   875     state
   870     |> generic_goal prepp kind before_qed (after_qed', K I) propp
   876     |> generic_goal prepp kind before_qed (after_qed', K I) propp
   871     |> tap (Variable.warn_extra_tfrees (context_of state) o context_of)
   877     |> tap (Variable.warn_extra_tfrees (context_of state) o context_of)
   872   end;
   878   end;
   873 
   879 
   874 fun local_qed txt =
   880 fun local_qeds txt =
   875   end_proof false txt #>
   881   end_proof false txt
   876   Seq.maps (generic_qed ProofContext.auto_bind_facts #->
   882   #> Seq.map (generic_qed ProofContext.auto_bind_facts #->
   877     (fn ((after_qed, _), results) => after_qed results));
   883     (fn ((after_qed, _), results) => after_qed results));
       
   884 
       
   885 fun local_qed txt = local_qeds txt #> check_finish;
   878 
   886 
   879 
   887 
   880 (* global goals *)
   888 (* global goals *)
   881 
   889 
   882 fun global_goal prepp before_qed after_qed propp ctxt =
   890 fun global_goal prepp before_qed after_qed propp ctxt =
   883   init ctxt
   891   init ctxt
   884   |> generic_goal (prepp #> ProofContext.auto_fixes) ""
   892   |> generic_goal (prepp #> ProofContext.auto_fixes) "" before_qed (K I, after_qed) propp;
   885     before_qed (K Seq.single, after_qed) propp;
       
   886 
   893 
   887 val theorem = global_goal ProofContext.bind_propp_schematic;
   894 val theorem = global_goal ProofContext.bind_propp_schematic;
   888 val theorem_i = global_goal ProofContext.bind_propp_schematic_i;
   895 val theorem_i = global_goal ProofContext.bind_propp_schematic_i;
   889 
       
   890 fun check_result msg sq =
       
   891   (case Seq.pull sq of
       
   892     NONE => error msg
       
   893   | SOME (s', sq') => Seq.cons s' sq');
       
   894 
   896 
   895 fun global_qeds txt =
   897 fun global_qeds txt =
   896   end_proof true txt
   898   end_proof true txt
   897   #> Seq.map (generic_qed (K I) #> (fn (((_, after_qed), results), state) =>
   899   #> Seq.map (generic_qed (K I) #> (fn (((_, after_qed), results), state) =>
   898     after_qed results (context_of state)))
   900     after_qed results (context_of state)));
   899   |> Seq.DETERM;   (*backtracking may destroy theory!*)
   901 
   900 
   902 fun global_qed txt = global_qeds txt #> check_finish;
   901 fun global_qed txt =
       
   902   global_qeds txt
       
   903   #> check_result "Failed to finish proof"
       
   904   #> Seq.hd;
       
   905 
   903 
   906 
   904 
   907 (* concluding steps *)
   905 (* concluding steps *)
   908 
   906 
   909 fun local_terminal_proof (text, opt_text) =
   907 fun terminal_proof qed initial terminal =
   910   proof (SOME text) #> Seq.maps (local_qed (opt_text, true));
   908   proof (SOME initial) #> Seq.maps (qed terminal) #> check_finish;
   911 
   909 
       
   910 fun local_terminal_proof (text, opt_text) = terminal_proof local_qeds text (opt_text, true);
   912 val local_default_proof = local_terminal_proof (Method.default_text, NONE);
   911 val local_default_proof = local_terminal_proof (Method.default_text, NONE);
   913 val local_immediate_proof = local_terminal_proof (Method.this_text, NONE);
   912 val local_immediate_proof = local_terminal_proof (Method.this_text, NONE);
   914 val local_done_proof = proof (SOME Method.done_text) #> Seq.maps (local_qed (NONE, false));
       
   915 fun local_skip_proof int = local_terminal_proof (Method.sorry_text int, NONE);
   913 fun local_skip_proof int = local_terminal_proof (Method.sorry_text int, NONE);
   916 
   914 val local_done_proof = terminal_proof local_qeds Method.done_text (NONE, false);
   917 fun global_term_proof immed (text, opt_text) =
   915 
   918   proof (SOME text)
   916 fun global_terminal_proof (text, opt_text) = terminal_proof global_qeds text (opt_text, true);
   919   #> check_result "Terminal proof method failed"
       
   920   #> Seq.maps (global_qeds (opt_text, immed))
       
   921   #> check_result "Failed to finish proof (after successful terminal method)"
       
   922   #> Seq.hd;
       
   923 
       
   924 val global_terminal_proof = global_term_proof true;
       
   925 val global_default_proof = global_terminal_proof (Method.default_text, NONE);
   917 val global_default_proof = global_terminal_proof (Method.default_text, NONE);
   926 val global_immediate_proof = global_terminal_proof (Method.this_text, NONE);
   918 val global_immediate_proof = global_terminal_proof (Method.this_text, NONE);
   927 val global_done_proof = global_term_proof false (Method.done_text, NONE);
       
   928 fun global_skip_proof int = global_terminal_proof (Method.sorry_text int, NONE);
   919 fun global_skip_proof int = global_terminal_proof (Method.sorry_text int, NONE);
       
   920 val global_done_proof = terminal_proof global_qeds Method.done_text (NONE, false);
   929 
   921 
   930 
   922 
   931 (* common goal statements *)
   923 (* common goal statements *)
   932 
   924 
   933 local
   925 local
   938 fun gen_show prep_att prepp before_qed after_qed stmt int state =
   930 fun gen_show prep_att prepp before_qed after_qed stmt int state =
   939   let
   931   let
   940     val testing = ref false;
   932     val testing = ref false;
   941     val rule = ref (NONE: thm option);
   933     val rule = ref (NONE: thm option);
   942     fun fail_msg ctxt =
   934     fun fail_msg ctxt =
   943       "Local statement will fail to solve any pending goal" ::
   935       "Local statement will fail to refine any pending goal" ::
   944       (case ! rule of NONE => [] | SOME th => [ProofDisplay.string_of_rule ctxt "Failed" th])
   936       (case ! rule of NONE => [] | SOME th => [ProofDisplay.string_of_rule ctxt "Failed" th])
   945       |> cat_lines;
   937       |> cat_lines;
   946 
   938 
   947     fun print_results ctxt res =
   939     fun print_results ctxt res =
   948       if ! testing then () else ProofDisplay.print_results int ctxt res;
   940       if ! testing then () else ProofDisplay.print_results int ctxt res;
   949     fun print_rule ctxt th =
   941     fun print_rule ctxt th =
   950       if ! testing then rule := SOME th
   942       if ! testing then rule := SOME th
   951       else if int then priority (ProofDisplay.string_of_rule ctxt "Successful" th)
   943       else if int then priority (ProofDisplay.string_of_rule ctxt "Successful" th)
   952       else ();
   944       else ();
   953     val test_proof =
   945     val test_proof =
   954       (Seq.pull oo local_skip_proof) true
   946       try (local_skip_proof true)
   955       |> setmp_noncritical testing true
   947       |> setmp_noncritical testing true
   956       |> Exn.capture;
   948       |> Exn.capture;
   957 
   949 
   958     fun after_qed' results =
   950     fun after_qed' results =
   959       refine_goals print_rule (context_of state) (flat results)
   951       refine_goals print_rule (context_of state) (flat results)
   960       #> Seq.maps (after_qed results);
   952       #> check_result "Failed to refine any pending goal"
       
   953       #> after_qed results;
   961   in
   954   in
   962     state
   955     state
   963     |> local_goal print_results prep_att prepp "show" before_qed after_qed' stmt
   956     |> local_goal print_results prep_att prepp "show" before_qed after_qed' stmt
   964     |> int ? (fn goal_state =>
   957     |> int ? (fn goal_state =>
   965       (case test_proof goal_state of
   958       (case test_proof goal_state of
   996   not (is_original state) orelse
   989   not (is_original state) orelse
   997   schematic_goal state;
   990   schematic_goal state;
   998 
   991 
   999 fun future_proof fork_proof state =
   992 fun future_proof fork_proof state =
  1000   let
   993   let
  1001     val _ = is_relevant state andalso error "Cannot fork relevant proof";
       
  1002 
       
  1003     val _ = assert_backward state;
   994     val _ = assert_backward state;
  1004     val (goal_ctxt, (_, goal)) = find_goal state;
   995     val (goal_ctxt, (_, goal)) = find_goal state;
  1005     val {statement as (kind, propss, prop), messages, using, goal, before_qed, after_qed} = goal;
   996     val {statement as (kind, propss, prop), messages, using, goal, before_qed, after_qed} = goal;
       
   997 
       
   998     val _ = is_relevant state andalso error "Cannot fork relevant proof";
  1006 
   999 
  1007     val prop' = Logic.protect prop;
  1000     val prop' = Logic.protect prop;
  1008     val statement' = (kind, [[], [prop']], prop');
  1001     val statement' = (kind, [[], [prop']], prop');
  1009     val goal' = Thm.adjust_maxidx_thm (Thm.maxidx_of goal)
  1002     val goal' = Thm.adjust_maxidx_thm (Thm.maxidx_of goal)
  1010       (Drule.comp_no_flatten (goal, Thm.nprems_of goal) 1 Drule.protectI);
  1003       (Drule.comp_no_flatten (goal, Thm.nprems_of goal) 1 Drule.protectI);