src/Pure/Isar/proof.ML
changeset 60611 27255d1fbe1a
parent 60595 804dfdc82835
child 60618 4c79543cc376
equal deleted inserted replaced
60610:f52b4b0c10c4 60611:27255d1fbe1a
   208 (* context *)
   208 (* context *)
   209 
   209 
   210 val context_of = #context o top;
   210 val context_of = #context o top;
   211 val theory_of = Proof_Context.theory_of o context_of;
   211 val theory_of = Proof_Context.theory_of o context_of;
   212 
   212 
   213 fun map_node_context f =
       
   214   map_node (fn (ctxt, facts, mode, goal) => (f ctxt, facts, mode, goal));
       
   215 
       
   216 fun map_context f =
   213 fun map_context f =
   217   map_top (fn (ctxt, facts, mode, goal) => (f ctxt, facts, mode, goal));
   214   map_top (fn (ctxt, facts, mode, goal) => (f ctxt, facts, mode, goal));
   218 
   215 
   219 fun map_context_result f state =
   216 fun map_context_result f state =
   220   f (context_of state) ||> (fn ctxt => map_context (K ctxt) state);
   217   f (context_of state) ||> (fn ctxt => map_context (K ctxt) state);
   317   in bottom (op :: (Stack.dest stack)) end;
   314   in bottom (op :: (Stack.dest stack)) end;
   318 
   315 
   319 
   316 
   320 (* nested goal *)
   317 (* nested goal *)
   321 
   318 
   322 fun map_goal f g h (State stack) =
   319 fun map_goal f (State stack) =
   323   (case Stack.dest stack of
   320   (case Stack.dest stack of
   324     (Node {context, facts, mode, goal = SOME goal}, node :: nodes) =>
   321     (Node {context = ctxt, facts, mode, goal = SOME goal}, node :: nodes) =>
   325       let
   322       let
   326         val Goal {statement, using, goal, before_qed, after_qed} = goal;
   323         val Goal {statement, using, goal, before_qed, after_qed} = goal;
   327         val goal' = make_goal (g (statement, using, goal, before_qed, after_qed));
   324         val (ctxt', statement', using', goal', before_qed', after_qed') =
   328         val node' = map_node_context h node;
   325           f (ctxt, statement, using, goal, before_qed, after_qed);
   329         val stack' = Stack.make (make_node (f context, facts, mode, SOME goal')) (node' :: nodes);
   326         val goal' = make_goal (statement', using', goal', before_qed', after_qed');
   330       in State stack' end
   327       in State (Stack.make (make_node (ctxt', facts, mode, SOME goal')) (node :: nodes)) end
   331   | (nd, node :: nodes) =>
   328   | (top_node, node :: nodes) =>
   332       let
   329       let
   333         val nd' = map_node_context f nd;
   330         val State stack' = map_goal f (State (Stack.make node nodes));
   334         val State stack' = map_goal f g h (State (Stack.make node nodes));
       
   335         val (node', nodes') = Stack.dest stack';
   331         val (node', nodes') = Stack.dest stack';
   336       in State (Stack.make nd' (node' :: nodes')) end
   332       in State (Stack.make top_node (node' :: nodes')) end
   337   | _ => State stack);
   333   | _ => State stack);
   338 
   334 
   339 fun provide_goal goal =
   335 fun provide_goal goal =
   340   map_goal I (fn (statement, using, _, before_qed, after_qed) =>
   336   map_goal (fn (ctxt, statement, using, _, before_qed, after_qed) =>
   341     (statement, using, goal, before_qed, after_qed)) I;
   337     (ctxt, statement, using, goal, before_qed, after_qed));
   342 
   338 
   343 fun using_facts using =
   339 fun using_facts using =
   344   map_goal I (fn (statement, _, goal, before_qed, after_qed) =>
   340   map_goal (fn (ctxt, statement, _, goal, before_qed, after_qed) =>
   345     (statement, using, goal, before_qed, after_qed)) I;
   341     (ctxt, statement, using, goal, before_qed, after_qed));
   346 
   342 
   347 local
   343 fun find_goal state =
   348   fun find i state =
   344   (case try current_goal state of
   349     (case try current_goal state of
   345     SOME ctxt_goal => ctxt_goal
   350       SOME (ctxt, goal) => (ctxt, (i, goal))
   346   | NONE => find_goal (close_block state handle ERROR _ => error "No proof goal"));
   351     | NONE => find (i + 1) (close_block state handle ERROR _ => error "No proof goal"));
       
   352 in val find_goal = find 0 end;
       
   353 
   347 
   354 fun get_goal state =
   348 fun get_goal state =
   355   let val (ctxt, (_, {using, goal, ...})) = find_goal state
   349   let val (ctxt, {using, goal, ...}) = find_goal state
   356   in (ctxt, (using, goal)) end;
   350   in (ctxt, (using, goal)) end;
   357 
   351 
   358 
   352 
   359 
   353 
   360 (** pretty_state **)
   354 (** pretty_state **)
   373 fun pretty_state state =
   367 fun pretty_state state =
   374   let
   368   let
   375     val {context = ctxt, facts, mode, goal = _} = top state;
   369     val {context = ctxt, facts, mode, goal = _} = top state;
   376     val verbose = Config.get ctxt Proof_Context.verbose;
   370     val verbose = Config.get ctxt Proof_Context.verbose;
   377 
   371 
   378     fun prt_goal (SOME (_, (_, {statement = _, using, goal, before_qed = _, after_qed = _}))) =
   372     fun prt_goal (SOME (_, {statement = _, using, goal, before_qed = _, after_qed = _})) =
   379           pretty_sep
   373           pretty_sep
   380             (pretty_facts ctxt "using"
   374             (pretty_facts ctxt "using"
   381               (if mode <> Backward orelse null using then NONE else SOME using))
   375               (if mode <> Backward orelse null using then NONE else SOME using))
   382             ([Proof_Display.pretty_goal_header goal] @ Goal_Display.pretty_goals ctxt goal)
   376             ([Proof_Display.pretty_goal_header goal] @ Goal_Display.pretty_goals ctxt goal)
   383       | prt_goal NONE = [];
   377       | prt_goal NONE = [];
   415 
   409 
   416 fun goal_cases ctxt st =
   410 fun goal_cases ctxt st =
   417   Rule_Cases.make_common ctxt (Thm.prop_of st) (map (rpair [] o rpair []) (goals st));
   411   Rule_Cases.make_common ctxt (Thm.prop_of st) (map (rpair [] o rpair []) (goals st));
   418 
   412 
   419 fun apply_method text ctxt state =
   413 fun apply_method text ctxt state =
   420   #2 (#2 (find_goal state)) |> (fn {statement, using, goal, before_qed, after_qed} =>
   414   find_goal state |> (fn (goal_ctxt, {statement, using, goal, before_qed, after_qed}) =>
   421     Method.evaluate text ctxt using goal
   415     Method.evaluate text ctxt using goal
   422     |> Seq.map (fn (meth_cases, goal') =>
   416     |> Seq.map (fn (meth_cases, goal') =>
   423       state
   417       let
   424       |> map_goal
   418         val goal_ctxt' = goal_ctxt
   425           (Proof_Context.update_cases_legacy (no_goal_cases goal @ goal_cases ctxt goal') #>
   419           |> Proof_Context.update_cases_legacy (no_goal_cases goal @ goal_cases ctxt goal')
   426            Proof_Context.update_cases meth_cases)
   420           |> Proof_Context.update_cases meth_cases;
   427           (K (statement, using, goal', before_qed, after_qed)) I));
   421         val state' = state
       
   422           |> map_goal (K (goal_ctxt', statement, using, goal', before_qed, after_qed));
       
   423       in state' end));
   428 
   424 
   429 in
   425 in
   430 
   426 
   431 fun refine text state = apply_method text (context_of state) state;
   427 fun refine text state = apply_method text (context_of state) state;
   432 fun refine_end text state = apply_method text (#1 (find_goal state)) state;
   428 fun refine_end text state = apply_method text (#1 (find_goal state)) state;
   748   |> assert_backward
   744   |> assert_backward
   749   |> map_context_result
   745   |> map_context_result
   750     (fn ctxt => ctxt |> Proof_Context.note_thmss ""
   746     (fn ctxt => ctxt |> Proof_Context.note_thmss ""
   751       (Attrib.map_facts_refs (map (prep_att ctxt)) (prep_fact ctxt) (no_binding args)))
   747       (Attrib.map_facts_refs (map (prep_att ctxt)) (prep_fact ctxt) (no_binding args)))
   752   |> (fn (named_facts, state') =>
   748   |> (fn (named_facts, state') =>
   753     state' |> map_goal I (fn (statement, using, goal, before_qed, after_qed) =>
   749     state' |> map_goal (fn (goal_ctxt, statement, using, goal, before_qed, after_qed) =>
   754       let
   750       let
   755         val ctxt = context_of state';
   751         val ctxt = context_of state';
   756         val ths = maps snd named_facts;
   752         val ths = maps snd named_facts;
   757       in (statement, f ctxt ths using, g ctxt ths goal, before_qed, after_qed) end) I);
   753       in (goal_ctxt, statement, f ctxt ths using, g ctxt ths goal, before_qed, after_qed) end));
   758 
   754 
   759 fun append_using _ ths using = using @ filter_out Thm.is_dummy ths;
   755 fun append_using _ ths using = using @ filter_out Thm.is_dummy ths;
   760 fun unfold_using ctxt ths = map (Local_Defs.unfold ctxt ths);
   756 fun unfold_using ctxt ths = map (Local_Defs.unfold ctxt ths);
   761 val unfold_goals = Local_Defs.unfold_goals;
   757 val unfold_goals = Local_Defs.unfold_goals;
   762 
   758 
  1203 (** future proofs **)
  1199 (** future proofs **)
  1204 
  1200 
  1205 (* relevant proof states *)
  1201 (* relevant proof states *)
  1206 
  1202 
  1207 fun schematic_goal state =
  1203 fun schematic_goal state =
  1208   let val (_, (_, {statement = (_, _, prop), ...})) = find_goal state
  1204   let val (_, {statement = (_, _, prop), ...}) = find_goal state
  1209   in Goal.is_schematic prop end;
  1205   in Goal.is_schematic prop end;
  1210 
  1206 
  1211 fun is_relevant state =
  1207 fun is_relevant state =
  1212   (case try find_goal state of
  1208   (case try find_goal state of
  1213     NONE => true
  1209     NONE => true
  1214   | SOME (_, (_, {statement = (_, _, prop), goal, ...})) =>
  1210   | SOME (_, {statement = (_, _, prop), goal, ...}) =>
  1215       Goal.is_schematic prop orelse not (Logic.protect prop aconv Thm.concl_of goal));
  1211       Goal.is_schematic prop orelse not (Logic.protect prop aconv Thm.concl_of goal));
  1216 
  1212 
  1217 
  1213 
  1218 (* full proofs *)
  1214 (* full proofs *)
  1219 
  1215 
  1236 in
  1232 in
  1237 
  1233 
  1238 fun future_proof fork_proof state =
  1234 fun future_proof fork_proof state =
  1239   let
  1235   let
  1240     val _ = assert_backward state;
  1236     val _ = assert_backward state;
  1241     val (goal_ctxt, (_, goal_info)) = find_goal state;
  1237     val (goal_ctxt, goal_info) = find_goal state;
  1242     val {statement as (kind, _, prop), using, goal, before_qed, after_qed} = goal_info;
  1238     val {statement as (kind, _, prop), using, goal, before_qed, after_qed} = goal_info;
  1243 
  1239 
  1244     val _ = is_relevant state andalso error "Cannot fork relevant proof";
  1240     val _ = is_relevant state andalso error "Cannot fork relevant proof";
  1245 
  1241 
  1246     val after_qed' =
  1242     val after_qed' =
  1247       (fn (_, [[th]]) => map_context (set_result th),
  1243       (fn (_, [[th]]) => map_context (set_result th),
  1248        fn (_, [[th]]) => set_result th);
  1244        fn (_, [[th]]) => set_result th);
  1249     val result_ctxt =
  1245     val result_ctxt =
  1250       state
  1246       state
  1251       |> map_context reset_result
  1247       |> map_context reset_result
  1252       |> map_goal I (K ((kind, [[], [prop]], prop), using, goal, before_qed, after_qed')) I
  1248       |> map_goal (K (goal_ctxt, (kind, [[], [prop]], prop), using, goal, before_qed, after_qed'))
  1253       |> fork_proof;
  1249       |> fork_proof;
  1254 
  1250 
  1255     val future_thm = Future.map (the_result o snd) result_ctxt;
  1251     val future_thm = Future.map (the_result o snd) result_ctxt;
  1256     val finished_goal = Goal.protect 0 (Goal.future_result goal_ctxt future_thm prop);
  1252     val finished_goal = Goal.protect 0 (Goal.future_result goal_ctxt future_thm prop);
  1257     val state' =
  1253     val state' =
  1258       state
  1254       state
  1259       |> map_goal I (K (statement, using, finished_goal, NONE, after_qed)) I;
  1255       |> map_goal (K (goal_ctxt, statement, using, finished_goal, NONE, after_qed));
  1260   in (Future.map fst result_ctxt, state') end;
  1256   in (Future.map fst result_ctxt, state') end;
  1261 
  1257 
  1262 end;
  1258 end;
  1263 
  1259 
  1264 
  1260