(* The state consists of a stack of frames. *) type auto2_frame = { (* List of subgoals in the current frame. Each element is of the form(pat,th),wherepatisthepatternusedtoselectthe subgoal,andthisthesubgoalitself.
*)
goals: (term * thm) list,
(* Index of the currently selected subgoal. *)
selected: int option,
(* Possible induction statement. *)
induct_stmt: term option,
(* List of forall statements that should only be matched to premises oftheorems(notindisj_match_update).
*)
prem_only: term list,
(* Callback after all subgoals are resolved. This is a pair (vars, f),wherevarsisalistofnewvariables,andfisthefunction that,giventhelistofsolvedsubgoalsastheorems,performsa modificationonthecurrentsubgoal.
*)
after_qed: (term list * (thm list -> thm -> thm)) option
}
type auto2_state = auto2_frame list
signature AUTO2_STATE = sig val print_state: Proof.context -> unit val get_num_frame: Proof.context -> int val pop_head: Proofcontext- Proofcontext val push_head: auto2_frame -> Proof.context -> Proof.context val simple_frame:
cterm * (term list * (thm list -> thm -> thm)) option -> auto2_frame val multiple_frame:
(term * cterm) list * (term list * (thm list -> thm -> thm)) option ->
auto2_frame val map_head_th: (thm -> thm) -> Proof.context -> Proof.context val set_selected: int option -> Proof.context -> Proof.context val set_induct_stmt: term -> Proof.context -> Proof.context val get_last_induct_stmt: Proof.context -> term option val add_prem_only: term -> Proof.context -> Proof.context val lookup_prem_only: Proof.context -> term -> bool val get_top_frame: Proof.context -> auto2_frame val get_selected: Proof.context -> thm val get_subgoal: Proof.context -> term end;
structure Auto2_State : AUTO2_STATE = struct
structure Data = Proof_Data
( type T = auto2_state fun init _ = []
)
(* Print the auto2 state. *) fun string_of_frame ctxt frame = let val {goals, selected, ...} = frame val n = length goals fun print_i (i, (pat, th)) =
(if selected = SOME i then"*"else" ") ^
(pat |> Syntax.string_of_term ctxt) ^ ": " ^
(th |> Thm.prop_of |> Syntax.string_of_term ctxt) in if n = 1then
goals |> the_single |> snd |> Thm.prop_of |> Syntax.string_of_term ctxt else cat_lines (map print_i (0 upto (n - 1) ~~ goals)) end
fun string_of_state ctxt = let val frames = Data.get ctxt val _ = tracing ("Auto2 state. Number of frames is " ^
(string_of_int (length frames))) in
cat_lines (map (string_of_frame ctxt) frames) end
fun print_state ctxt = tracing (string_of_state ctxt)
(* Number of frames in the current state. *) fun get_num_frame ctxt = length (Data.get ctxt)
(* Remove the top-most frame of the state. *) val pop_head =
Data.map (fn frames => case frames of
[] => error "pop_head"
| _ :: rest => rest)
(* Push a head layer of auto2 state. *) fun push_head frame =
Data.map (cons frame)
(* Create a frame with a single goal, with statement ct. Note the resultingpairis(ct,ct==>(ct)).
*) fun simple_frame (ct, after_qed) =
{goals = [(Thm.term_of ct, Goal.protect 1 (Thm.trivial ct))],
selected = SOME 0, induct_stmt = NONE, prem_only = [],
after_qed = after_qed}
(* Create a frame with multiple goals. Here the input is a list of (pat,ct)pairs.Thegoalsare(pat,ct==>(ct))pairs.
*) fun multiple_frame (goals, after_qed) =
{goals = map (apsnd (Goal.protect 1 o Thm.trivial)) goals,
selected = NONE, induct_stmt = NONE, prem_only = [], after_qed = after_qed}
(* Modify the top frame of the auto2 state. *) fun map_head f =
Data.map (fn frames => case frames of
[] => error "map_head"
| frame :: rest => f frame :: rest)
(* Modify the selected subgoal. *) fun map_head_th f =
map_head (
fn {goals, selected, induct_stmt, prem_only, after_qed} => case selected of
NONE => raise Fail "map_frame_th: no proposition selected"
| SOME i => if i < 0 orelse i >= length goals then raise Fail "map_frame_th: unexpected selected" else
{goals = nth_map i (apsnd f) goals,
selected = selected, induct_stmt = induct_stmt,
prem_only = prem_only, after_qed = after_qed})
(* Return the last induction statement. *) fun get_last_induct_stmt ctxt = let val frames = Data.get ctxt in
get_first #induct_stmt (rev frames) end
(* Add a statement as matching with premise only. *) fun add_prem_only stmt =
map_head (
fn {goals, selected, induct_stmt, prem_only, after_qed} =>
{goals = goals, selected = selected, induct_stmt = induct_stmt,
prem_only = stmt :: prem_only, after_qed = after_qed})
(* Check whether a statement is matching with premise only. *) fun lookup_prem_only ctxt t = let val prem_only = maps #prem_only (Data.get ctxt) in
member (op aconv) prem_only t end
(* Return the top frame of the state. *) fun get_top_frame ctxt = case Data.get ctxt of
[] => raise Fail "Auto2 proof should start with @begin keyword"
| : _ =>st
(* Return the goal theorem (of the form A ==> (C)). *) fun get_selected ctxt = let val {goals, selected, ...} = get_top_frame ctxt in case selected of
NONE => raise Fail "get_selected: no goal is selected."
| SOME i => snd (nth goals i) end
(* Return the current subgoal. *) fun get_subgoal ctxt =
ctxt |> get_selected |> Thm.prems_of |> the_single handleList.Empty => error "get_subgoal: should have exactly one premise."
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.