src/Pure/Isar/proof.ML
changeset 7176 a329a37ed91a
parent 7011 7e8e9a26ba2c
child 7201 59b9b7aec3c5
equal deleted inserted replaced
7175:8263d0b50e12 7176:a329a37ed91a
    15   val context_of: state -> context
    15   val context_of: state -> context
    16   val theory_of: state -> theory
    16   val theory_of: state -> theory
    17   val sign_of: state -> Sign.sg
    17   val sign_of: state -> Sign.sg
    18   val the_facts: state -> thm list
    18   val the_facts: state -> thm list
    19   val the_fact: state -> thm
    19   val the_fact: state -> thm
       
    20   val get_goal: state -> thm list * thm
    20   val goal_facts: (state -> thm list) -> state -> state
    21   val goal_facts: (state -> thm list) -> state -> state
    21   val use_facts: state -> state
    22   val use_facts: state -> state
    22   val reset_facts: state -> state
    23   val reset_facts: state -> state
    23   val assert_forward: state -> state
    24   val assert_forward: state -> state
    24   val assert_backward: state -> state
    25   val assert_backward: state -> state
    62   val lemma_i: bstring -> theory attribute list -> term * (term list * term list)
    63   val lemma_i: bstring -> theory attribute list -> term * (term list * term list)
    63     -> theory -> state
    64     -> theory -> state
    64   val chain: state -> state
    65   val chain: state -> state
    65   val export_chain: state -> state Seq.seq
    66   val export_chain: state -> state Seq.seq
    66   val from_facts: thm list -> state -> state
    67   val from_facts: thm list -> state -> state
    67   val show: string -> context attribute list -> string * (string list * string list)
    68   val show: (state -> state Seq.seq) -> string -> context attribute list
    68     -> state -> state
    69     -> string * (string list * string list) -> state -> state
    69   val show_i: string -> context attribute list -> term * (term list * term list)
    70   val show_i: (state -> state Seq.seq) -> string -> context attribute list
    70     -> state -> state
    71     -> term * (term list * term list) -> state -> state
    71   val have: string -> context attribute list -> string * (string list * string list)
    72   val have: (state -> state Seq.seq) -> string -> context attribute list
    72     -> state -> state
    73     -> string * (string list * string list) -> state -> state
    73   val have_i: string -> context attribute list -> term * (term list * term list)
    74   val have_i: (state -> state Seq.seq) -> string -> context attribute list
    74     -> state -> state
    75     -> term * (term list * term list) -> state -> state
    75   val at_bottom: state -> bool
    76   val at_bottom: state -> bool
    76   val local_qed: (state -> state Seq.seq)
    77   val local_qed: (state -> state Seq.seq)
    77     -> ({kind: string, name: string, thm: thm} -> unit) * (thm -> unit) -> state -> state Seq.seq
    78     -> ({kind: string, name: string, thm: thm} -> unit) * (thm -> unit) -> state -> state Seq.seq
    78   val global_qed: (state -> state Seq.seq) -> state
    79   val global_qed: (state -> state Seq.seq) -> state
    79     -> (theory * {kind: string, name: string, thm: thm}) Seq.seq
    80     -> (theory * {kind: string, name: string, thm: thm}) Seq.seq
   123 val mode_name =
   124 val mode_name =
   124   enclose "`" "'" o
   125   enclose "`" "'" o
   125     (fn Forward => "state" | ForwardChain => "chain" | Backward => "prove");
   126     (fn Forward => "state" | ForwardChain => "chain" | Backward => "prove");
   126 
   127 
   127 
   128 
   128 (* type node *)
       
   129 
       
   130 type node =
       
   131  {context: context,
       
   132   facts: thm list option,
       
   133   mode: mode,
       
   134   goal: goal option};
       
   135 
       
   136 fun make_node (context, facts, mode, goal) =
       
   137   {context = context, facts = facts, mode = mode, goal = goal}: node;
       
   138 
       
   139 
       
   140 (* datatype state *)
   129 (* datatype state *)
   141 
   130 
   142 datatype state =
   131 datatype node =
       
   132   Node of
       
   133    {context: context,
       
   134     facts: thm list option,
       
   135     mode: mode,
       
   136     goal: (goal * (state -> state Seq.seq)) option}
       
   137 and state =
   143   State of
   138   State of
   144     node *              (*current*)
   139     node *              (*current*)
   145     node list;          (*parents wrt. block structure*)
   140     node list;          (*parents wrt. block structure*)
       
   141 
       
   142 fun make_node (context, facts, mode, goal) =
       
   143   Node {context = context, facts = facts, mode = mode, goal = goal};
       
   144 
   146 
   145 
   147 exception STATE of string * state;
   146 exception STATE of string * state;
   148 
   147 
   149 fun err_malformed name state =
   148 fun err_malformed name state =
   150   raise STATE (name ^ ": internal error -- malformed proof state", state);
   149   raise STATE (name ^ ": internal error -- malformed proof state", state);
   153   (case Seq.pull sq of
   152   (case Seq.pull sq of
   154     None => raise STATE (msg, state)
   153     None => raise STATE (msg, state)
   155   | Some s_sq => Seq.cons s_sq);
   154   | Some s_sq => Seq.cons s_sq);
   156 
   155 
   157 
   156 
   158 fun map_current f (State ({context, facts, mode, goal}, nodes)) =
   157 fun map_current f (State (Node {context, facts, mode, goal}, nodes)) =
   159   State (make_node (f (context, facts, mode, goal)), nodes);
   158   State (make_node (f (context, facts, mode, goal)), nodes);
   160 
   159 
   161 fun init_state thy =
   160 fun init_state thy =
   162   State (make_node (ProofContext.init thy, None, Forward, None), []);
   161   State (make_node (ProofContext.init thy, None, Forward, None), []);
   163 
   162 
   165 
   164 
   166 (** basic proof state operations **)
   165 (** basic proof state operations **)
   167 
   166 
   168 (* context *)
   167 (* context *)
   169 
   168 
   170 fun context_of (State ({context, ...}, _)) = context;
   169 fun context_of (State (Node {context, ...}, _)) = context;
   171 val theory_of = ProofContext.theory_of o context_of;
   170 val theory_of = ProofContext.theory_of o context_of;
   172 val sign_of = ProofContext.sign_of o context_of;
   171 val sign_of = ProofContext.sign_of o context_of;
   173 
   172 
   174 fun map_context f = map_current (fn (ctxt, facts, mode, goal) => (f ctxt, facts, mode, goal));
   173 fun map_context f = map_current (fn (ctxt, facts, mode, goal) => (f ctxt, facts, mode, goal));
   175 
   174 
   176 fun map_context_result f (state as State ({context, facts, mode, goal}, nodes)) =
   175 fun map_context_result f (state as State (Node {context, facts, mode, goal}, nodes)) =
   177   let val (context', result) = f context
   176   let val (context', result) = f context
   178   in (State (make_node (context', facts, mode, goal), nodes), result) end;
   177   in (State (make_node (context', facts, mode, goal), nodes), result) end;
   179 
   178 
   180 
   179 
   181 fun put_data kind f = map_context o ProofContext.put_data kind f;
   180 fun put_data kind f = map_context o ProofContext.put_data kind f;
   188 val assumptions = ProofContext.assumptions o context_of;
   187 val assumptions = ProofContext.assumptions o context_of;
   189 
   188 
   190 
   189 
   191 (* facts *)
   190 (* facts *)
   192 
   191 
   193 fun the_facts (State ({facts = Some facts, ...}, _)) = facts
   192 fun the_facts (State (Node {facts = Some facts, ...}, _)) = facts
   194   | the_facts state = raise STATE ("No current facts available", state);
   193   | the_facts state = raise STATE ("No current facts available", state);
   195 
   194 
   196 fun the_fact state =
   195 fun the_fact state =
   197   (case the_facts state of
   196   (case the_facts state of
   198     [fact] => fact
   197     [fact] => fact
   199   | _ => raise STATE ("Single fact expected", state));
   198   | _ => raise STATE ("Single fact expected", state));
   200 
   199 
   201 fun assert_facts state = (the_facts state; state);
   200 fun assert_facts state = (the_facts state; state);
   202 fun get_facts (State ({facts, ...}, _)) = facts;
   201 fun get_facts (State (Node {facts, ...}, _)) = facts;
   203 
   202 
   204 fun put_facts facts state =
   203 fun put_facts facts state =
   205   state
   204   state
   206   |> map_current (fn (ctxt, _, mode, goal) => (ctxt, facts, mode, goal))
   205   |> map_current (fn (ctxt, _, mode, goal) => (ctxt, facts, mode, goal))
   207   |> put_thms ("facts", if_none facts []);
   206   |> put_thms ("facts", if_none facts []);
   216 fun these_facts (state, ths) = have_facts ths state;
   215 fun these_facts (state, ths) = have_facts ths state;
   217 
   216 
   218 
   217 
   219 (* goal *)
   218 (* goal *)
   220 
   219 
   221 fun find_goal i (state as State ({goal = Some goal, ...}, _)) = (context_of state, (i, goal))
   220 fun find_goal i (state as State (Node {goal = Some goal, ...}, _)) = (context_of state, (i, goal))
   222   | find_goal i (State ({goal = None, ...}, node :: nodes)) =
   221   | find_goal i (State (Node {goal = None, ...}, node :: nodes)) =
   223       find_goal (i + 1) (State (node, nodes))
   222       find_goal (i + 1) (State (node, nodes))
   224   | find_goal _ (state as State (_, [])) = err_malformed "find_goal" state;
   223   | find_goal _ (state as State (_, [])) = err_malformed "find_goal" state;
   225 
   224 
       
   225 fun get_goal state =
       
   226   let val (_, (_, ((_, goal), _))) = find_goal 0 state
       
   227   in goal end;
       
   228 
   226 fun put_goal goal = map_current (fn (ctxt, facts, mode, _) => (ctxt, facts, mode, goal));
   229 fun put_goal goal = map_current (fn (ctxt, facts, mode, _) => (ctxt, facts, mode, goal));
   227 
   230 
   228 fun map_goal f (State ({context, facts, mode, goal = Some goal}, nodes)) =
   231 fun map_goal f (State (Node {context, facts, mode, goal = Some goal}, nodes)) =
   229       State (make_node (context, facts, mode, Some (f goal)), nodes)
   232       State (make_node (context, facts, mode, Some (f goal)), nodes)
   230   | map_goal f (State (nd, node :: nodes)) =
   233   | map_goal f (State (nd, node :: nodes)) =
   231       let val State (node', nodes') = map_goal f (State (node, nodes))
   234       let val State (node', nodes') = map_goal f (State (node, nodes))
   232       in State (nd, node' :: nodes') end
   235       in State (nd, node' :: nodes') end
   233   | map_goal _ state = state;
   236   | map_goal _ state = state;
   234 
   237 
   235 fun goal_facts get state =
   238 fun goal_facts get state =
   236   state
   239   state
   237   |> map_goal (fn (result, (_, thm)) => (result, (get state, thm)));
   240   |> map_goal (fn ((result, (_, thm)), f) => ((result, (get state, thm)), f));
   238 
   241 
   239 fun use_facts state =
   242 fun use_facts state =
   240   state
   243   state
   241   |> goal_facts the_facts
   244   |> goal_facts the_facts
   242   |> reset_facts;
   245   |> reset_facts;
   243 
   246 
   244 
   247 
   245 (* mode *)
   248 (* mode *)
   246 
   249 
   247 fun get_mode (State ({mode, ...}, _)) = mode;
   250 fun get_mode (State (Node {mode, ...}, _)) = mode;
   248 fun put_mode mode = map_current (fn (ctxt, facts, _, goal) => (ctxt, facts, mode, goal));
   251 fun put_mode mode = map_current (fn (ctxt, facts, _, goal) => (ctxt, facts, mode, goal));
   249 
   252 
   250 val enter_forward = put_mode Forward;
   253 val enter_forward = put_mode Forward;
   251 val enter_forward_chain = put_mode ForwardChain;
   254 val enter_forward_chain = put_mode ForwardChain;
   252 val enter_backward = put_mode Backward;
   255 val enter_backward = put_mode Backward;
   290 
   293 
   291 fun print_facts _ None = ()
   294 fun print_facts _ None = ()
   292   | print_facts s (Some ths) =
   295   | print_facts s (Some ths) =
   293       Pretty.writeln (Pretty.big_list (s ^ " facts:") (map pretty_thm ths));
   296       Pretty.writeln (Pretty.big_list (s ^ " facts:") (map pretty_thm ths));
   294 
   297 
   295 fun print_state (state as State ({context, facts, mode, goal = _}, nodes)) =
   298 fun print_state (state as State (Node {context, facts, mode, goal = _}, nodes)) =
   296   let
   299   let
   297     val ref (_, _, begin_goal) = Goals.current_goals_markers;
   300     val ref (_, _, begin_goal) = Goals.current_goals_markers;
   298 
   301 
   299     fun levels_up 0 = ""
   302     fun levels_up 0 = ""
   300       | levels_up 1 = " (1 level up)"
   303       | levels_up 1 = " (1 level up)"
   301       | levels_up i = " (" ^ string_of_int i ^ " levels up)";
   304       | levels_up i = " (" ^ string_of_int i ^ " levels up)";
   302 
   305 
   303     fun print_goal (_, (i, ((kind, name, _), (goal_facts, thm)))) =
   306     fun print_goal (_, (i, (((kind, name, _), (goal_facts, thm)), _))) =
   304       (print_facts "Using" (if null goal_facts then None else Some goal_facts);
   307       (print_facts "Using" (if null goal_facts then None else Some goal_facts);
   305         writeln (kind_name kind ^ " " ^ quote name ^ levels_up (i div 2) ^ ":");
   308         writeln (kind_name kind ^ " " ^ quote name ^ levels_up (i div 2) ^ ":");
   306         Locale.print_goals_marker begin_goal (! goals_limit) thm);
   309         Locale.print_goals_marker begin_goal (! goals_limit) thm);
   307 
   310 
   308     val ctxt_strings = ProofContext.strings_of_context context;
   311     val ctxt_strings = ProofContext.strings_of_context context;
   333 
   336 
   334 fun check_sign sg state =
   337 fun check_sign sg state =
   335   if Sign.subsig (sg, sign_of state) then state
   338   if Sign.subsig (sg, sign_of state) then state
   336   else raise STATE ("Bad signature of result: " ^ Sign.str_of_sg sg, state);
   339   else raise STATE ("Bad signature of result: " ^ Sign.str_of_sg sg, state);
   337 
   340 
   338 fun refine meth_fun (state as State ({context, ...}, _)) =
   341 fun refine meth_fun state =
   339   let
   342   let
   340     val Method meth = meth_fun context;
   343     val Method meth = meth_fun (context_of state);
   341     val (_, (_, (result, (facts, thm)))) = find_goal 0 state;
   344     val (_, (_, ((result, (facts, thm)), f))) = find_goal 0 state;
   342 
   345 
   343     fun refn thm' =
   346     fun refn thm' =
   344       state
   347       state
   345       |> check_sign (Thm.sign_of_thm thm')
   348       |> check_sign (Thm.sign_of_thm thm')
   346       |> map_goal (K (result, (facts, thm')));
   349       |> map_goal (K ((result, (facts, thm')), f));
   347   in Seq.map refn (meth facts thm) end;
   350   in Seq.map refn (meth facts thm) end;
   348 
   351 
   349 
   352 
   350 (* export *)
   353 (* export *)
   351 
   354 
   401 fun RANGE [] _ = all_tac
   404 fun RANGE [] _ = all_tac
   402   | RANGE (tac :: tacs) i = RANGE tacs (i + 1) THEN tac i;
   405   | RANGE (tac :: tacs) i = RANGE tacs (i + 1) THEN tac i;
   403 
   406 
   404 fun export_goal print_rule raw_rule inner state =
   407 fun export_goal print_rule raw_rule inner state =
   405   let
   408   let
   406     val (outer, (_, (result, (facts, thm)))) = find_goal 0 state;
   409     val (outer, (_, ((result, (facts, thm)), f))) = find_goal 0 state;
   407     val (exp, tacs) = export_wrt inner (Some outer);
   410     val (exp, tacs) = export_wrt inner (Some outer);
   408     val rule = exp raw_rule;
   411     val rule = exp raw_rule;
   409     val _ = print_rule rule;
   412     val _ = print_rule rule;
   410     val thmq = FIRSTGOAL (Tactic.rtac rule THEN' RANGE (map #1 tacs)) thm;
   413     val thmq = FIRSTGOAL (Tactic.rtac rule THEN' RANGE (map #1 tacs)) thm;
   411   in Seq.map (fn th => map_goal (K (result, (facts, th))) state) thmq end;
   414   in Seq.map (fn th => map_goal (K ((result, (facts, th)), f)) state) thmq end;
   412 
   415 
   413 
   416 
   414 fun export_thm inner thm =
   417 fun export_thm inner thm =
   415   let val (exp, tacs) = export_wrt inner None in
   418   let val (exp, tacs) = export_wrt inner None in
   416     (case Seq.chop (2, RANGE (map #2 tacs) 1 (exp thm)) of
   419     (case Seq.chop (2, RANGE (map #2 tacs) 1 (exp thm)) of
   571   |> chain;
   574   |> chain;
   572 
   575 
   573 
   576 
   574 (* setup goals *)
   577 (* setup goals *)
   575 
   578 
   576 fun setup_goal opt_block prepp kind name atts raw_propp state =
   579 fun setup_goal opt_block prepp kind after_qed name atts raw_propp state =
   577   let
   580   let
   578     val (state', prop) =
   581     val (state', prop) =
   579       state
   582       state
   580       |> assert_forward_or_chain
   583       |> assert_forward_or_chain
   581       |> enter_forward
   584       |> enter_forward
   587     val revcut_rl = Drule.incr_indexes_wrt [] [] (cprop :: casms) [] Drule.revcut_rl;
   590     val revcut_rl = Drule.incr_indexes_wrt [] [] (cprop :: casms) [] Drule.revcut_rl;
   588     fun cut_asm (casm, thm) = Thm.rotate_rule ~1 1 ((Drule.assume_goal casm COMP revcut_rl) RS thm);
   591     fun cut_asm (casm, thm) = Thm.rotate_rule ~1 1 ((Drule.assume_goal casm COMP revcut_rl) RS thm);
   589     val goal = foldr cut_asm (casms, Drule.mk_triv_goal cprop);
   592     val goal = foldr cut_asm (casms, Drule.mk_triv_goal cprop);
   590   in
   593   in
   591     state'
   594     state'
   592     |> put_goal (Some ((kind atts, (PureThy.default_name name), prop), ([], goal)))
   595     |> put_goal (Some (((kind atts, (PureThy.default_name name), prop), ([], goal)), after_qed))
   593     |> auto_bind_goal prop
   596     |> auto_bind_goal prop
   594     |> (if is_chain state then use_facts else reset_facts)
   597     |> (if is_chain state then use_facts else reset_facts)
   595     |> new_block
   598     |> new_block
   596     |> enter_backward
   599     |> enter_backward
   597   end;
   600   end;
   598 
   601 
   599 
   602 
   600 (*global goals*)
   603 (*global goals*)
   601 fun global_goal prep kind name atts x thy =
   604 fun global_goal prep kind name atts x thy =
   602   setup_goal I prep kind name atts x (init_state thy);
   605   setup_goal I prep kind Seq.single name atts x (init_state thy);
   603 
   606 
   604 val theorem = global_goal ProofContext.bind_propp Theorem;
   607 val theorem = global_goal ProofContext.bind_propp Theorem;
   605 val theorem_i = global_goal ProofContext.bind_propp_i Theorem;
   608 val theorem_i = global_goal ProofContext.bind_propp_i Theorem;
   606 val lemma = global_goal ProofContext.bind_propp Lemma;
   609 val lemma = global_goal ProofContext.bind_propp Lemma;
   607 val lemma_i = global_goal ProofContext.bind_propp_i Lemma;
   610 val lemma_i = global_goal ProofContext.bind_propp_i Lemma;
   608 
   611 
   609 
   612 
   610 (*local goals*)
   613 (*local goals*)
   611 fun local_goal prep kind name atts x =
   614 fun local_goal prep kind f name atts x =
   612   setup_goal open_block prep kind name atts x;
   615   setup_goal open_block prep kind f name atts x;
   613 
   616 
   614 val show   = local_goal ProofContext.bind_propp Goal;
   617 val show   = local_goal ProofContext.bind_propp Goal;
   615 val show_i = local_goal ProofContext.bind_propp_i Goal;
   618 val show_i = local_goal ProofContext.bind_propp_i Goal;
   616 val have   = local_goal ProofContext.bind_propp Aux;
   619 val have   = local_goal ProofContext.bind_propp Aux;
   617 val have_i = local_goal ProofContext.bind_propp_i Aux;
   620 val have_i = local_goal ProofContext.bind_propp_i Aux;
   620 
   623 
   621 (** conclusions **)
   624 (** conclusions **)
   622 
   625 
   623 (* current goal *)
   626 (* current goal *)
   624 
   627 
   625 fun current_goal (State ({context, goal = Some goal, ...}, _)) = (context, goal)
   628 fun current_goal (State (Node {context, goal = Some goal, ...}, _)) = (context, goal)
   626   | current_goal state = raise STATE ("No current goal!", state);
   629   | current_goal state = raise STATE ("No current goal!", state);
   627 
   630 
   628 fun assert_current_goal true (state as State ({goal = None, ...}, _)) =
   631 fun assert_current_goal true (state as State (Node {goal = None, ...}, _)) =
   629       raise STATE ("No goal in this block!", state)
   632       raise STATE ("No goal in this block!", state)
   630   | assert_current_goal false (state as State ({goal = Some _, ...}, _)) =
   633   | assert_current_goal false (state as State (Node {goal = Some _, ...}, _)) =
   631       raise STATE ("Goal present in this block!", state)
   634       raise STATE ("Goal present in this block!", state)
   632   | assert_current_goal _ state = state;
   635   | assert_current_goal _ state = state;
   633 
   636 
   634 fun assert_bottom true (state as State (_, _ :: _)) =
   637 fun assert_bottom true (state as State (_, _ :: _)) =
   635       raise STATE ("Not at bottom of proof!", state)
   638       raise STATE ("Not at bottom of proof!", state)
   650 
   653 
   651 (* local_qed *)
   654 (* local_qed *)
   652 
   655 
   653 fun finish_local (print_result, print_rule) state =
   656 fun finish_local (print_result, print_rule) state =
   654   let
   657   let
   655     val (ctxt, ((kind, name, t), (_, raw_thm))) = current_goal state;
   658     val (ctxt, (((kind, name, t), (_, raw_thm)), after_qed)) = current_goal state;
   656     val result = prep_result state t raw_thm;
   659     val result = prep_result state t raw_thm;
   657     val (atts, opt_solve) =
   660     val (atts, opt_solve) =
   658       (case kind of
   661       (case kind of
   659         Goal atts => (atts, export_goal print_rule result ctxt)
   662         Goal atts => (atts, export_goal print_rule result ctxt)
   660       | Aux atts => (atts, Seq.single)
   663       | Aux atts => (atts, Seq.single)
   664     state
   667     state
   665     |> close_block
   668     |> close_block
   666     |> auto_bind_facts name [t]
   669     |> auto_bind_facts name [t]
   667     |> have_thmss [] name atts [Thm.no_attributes [result]]
   670     |> have_thmss [] name atts [Thm.no_attributes [result]]
   668     |> opt_solve
   671     |> opt_solve
       
   672     |> (Seq.flat o Seq.map after_qed)
   669   end;
   673   end;
   670 
   674 
   671 fun local_qed finalize print state =
   675 fun local_qed finalize print state =
   672   state
   676   state
   673   |> end_proof false
   677   |> end_proof false
   677 
   681 
   678 (* global_qed *)
   682 (* global_qed *)
   679 
   683 
   680 fun finish_global state =
   684 fun finish_global state =
   681   let
   685   let
   682     val (_, ((kind, name, t), (_, raw_thm))) = current_goal state;
   686     val (_, (((kind, name, t), (_, raw_thm)), _)) = current_goal state;   (*ignores after_qed!*)
   683     val result = final_result state (prep_result state t raw_thm);
   687     val result = final_result state (prep_result state t raw_thm);
   684 
   688 
   685     val atts =
   689     val atts =
   686       (case kind of
   690       (case kind of
   687         Theorem atts => atts
   691         Theorem atts => atts