wenzelm@32187: (* Title: Pure/goal_display.ML wenzelm@32089: Author: Lawrence C Paulson, Cambridge University Computer Laboratory wenzelm@32089: Author: Makarius wenzelm@32089: wenzelm@32089: Display tactical goal state. wenzelm@32089: *) wenzelm@32089: wenzelm@32187: signature GOAL_DISPLAY = wenzelm@32089: sig wenzelm@32738: val goals_limit: int Unsynchronized.ref wenzelm@32738: val show_consts: bool Unsynchronized.ref wenzelm@32145: val pretty_flexpair: Proof.context -> term * term -> Pretty.T wenzelm@32167: val pretty_goals: Proof.context -> {total: bool, main: bool, maxgoals: int} -> wenzelm@32167: thm -> Pretty.T list wenzelm@32145: val pretty_goals_without_context: int -> thm -> Pretty.T list wenzelm@32089: end; wenzelm@32089: wenzelm@32187: structure Goal_Display: GOAL_DISPLAY = wenzelm@32089: struct wenzelm@32089: wenzelm@32738: val goals_limit = Unsynchronized.ref 10; (*max number of goals to print*) wenzelm@32738: val show_consts = Unsynchronized.ref false; (*true: show consts with types in proof state output*) wenzelm@32089: wenzelm@32145: fun pretty_flexpair ctxt (t, u) = Pretty.block wenzelm@32145: [Syntax.pretty_term ctxt t, Pretty.str " =?=", Pretty.brk 1, Syntax.pretty_term ctxt u]; wenzelm@32089: wenzelm@32089: wenzelm@32089: (*print thm A1,...,An/B in "goal style" -- premises as numbered subgoals*) wenzelm@32089: wenzelm@32089: local wenzelm@32089: wenzelm@32089: fun ins_entry (x, y) = wenzelm@32089: AList.default (op =) (x, []) #> wenzelm@32089: AList.map_entry (op =) x (insert (op =) y); wenzelm@32089: wenzelm@32089: val add_consts = Term.fold_aterms wenzelm@32089: (fn Const (c, T) => ins_entry (T, (c, T)) wenzelm@32089: | _ => I); wenzelm@32089: wenzelm@32089: val add_vars = Term.fold_aterms wenzelm@32089: (fn Free (x, T) => ins_entry (T, (x, ~1)) wenzelm@32089: | Var (xi, T) => ins_entry (T, xi) wenzelm@32089: | _ => I); wenzelm@32089: wenzelm@32089: val add_varsT = Term.fold_atyps wenzelm@32089: (fn TFree (x, S) => ins_entry (S, (x, ~1)) wenzelm@32089: | TVar (xi, S) => ins_entry (S, xi) wenzelm@32089: | _ => I); wenzelm@32089: wenzelm@32089: fun sort_idxs vs = map (apsnd (sort (prod_ord string_ord int_ord))) vs; wenzelm@32089: fun sort_cnsts cs = map (apsnd (sort_wrt fst)) cs; wenzelm@32089: wenzelm@32089: fun consts_of t = sort_cnsts (add_consts t []); wenzelm@32089: fun vars_of t = sort_idxs (add_vars t []); wenzelm@32089: fun varsT_of t = rev (sort_idxs (Term.fold_types add_varsT t [])); wenzelm@32089: wenzelm@32089: in wenzelm@32089: wenzelm@32167: fun pretty_goals ctxt {total, main, maxgoals} state = wenzelm@32089: let wenzelm@32145: val prt_sort = Syntax.pretty_sort ctxt; wenzelm@32145: val prt_typ = Syntax.pretty_typ ctxt; wenzelm@32145: val prt_term = Syntax.pretty_term ctxt; wenzelm@32145: wenzelm@32089: fun prt_atoms prt prtT (X, xs) = Pretty.block wenzelm@32089: [Pretty.block (Pretty.commas (map prt xs)), Pretty.str " ::", wenzelm@32089: Pretty.brk 1, prtT X]; wenzelm@32089: wenzelm@32145: fun prt_var (x, ~1) = prt_term (Syntax.free x) wenzelm@32145: | prt_var xi = prt_term (Syntax.var xi); wenzelm@32089: wenzelm@32145: fun prt_varT (x, ~1) = prt_typ (TFree (x, [])) wenzelm@32145: | prt_varT xi = prt_typ (TVar (xi, [])); wenzelm@32089: wenzelm@32145: val prt_consts = prt_atoms (prt_term o Const) prt_typ; wenzelm@32145: val prt_vars = prt_atoms prt_var prt_typ; wenzelm@32145: val prt_varsT = prt_atoms prt_varT prt_sort; wenzelm@32089: wenzelm@32089: wenzelm@32089: fun pretty_list _ _ [] = [] wenzelm@32089: | pretty_list name prt lst = [Pretty.big_list name (map prt lst)]; wenzelm@32089: wenzelm@32167: fun pretty_subgoal (n, A) = Pretty.markup Markup.subgoal wenzelm@32145: [Pretty.str (" " ^ string_of_int n ^ ". "), prt_term A]; wenzelm@32089: fun pretty_subgoals As = map pretty_subgoal (1 upto length As ~~ As); wenzelm@32089: wenzelm@32145: val pretty_ffpairs = pretty_list "flex-flex pairs:" (pretty_flexpair ctxt); wenzelm@32089: wenzelm@32089: val pretty_consts = pretty_list "constants:" prt_consts o consts_of; wenzelm@32089: val pretty_vars = pretty_list "variables:" prt_vars o vars_of; wenzelm@32089: val pretty_varsT = pretty_list "type variables:" prt_varsT o varsT_of; wenzelm@32089: wenzelm@32089: wenzelm@32089: val {prop, tpairs, ...} = Thm.rep_thm state; wenzelm@32089: val (As, B) = Logic.strip_horn prop; wenzelm@32089: val ngoals = length As; wenzelm@32089: wenzelm@32089: fun pretty_gs (types, sorts) = wenzelm@32145: (if main then [prt_term B] else []) @ wenzelm@32089: (if ngoals = 0 then [Pretty.str "No subgoals!"] wenzelm@32089: else if ngoals > maxgoals then haftmann@33955: pretty_subgoals ((uncurry take) (maxgoals, As)) @ wenzelm@32167: (if total then [Pretty.str ("A total of " ^ string_of_int ngoals ^ " subgoals...")] wenzelm@32089: else []) wenzelm@32089: else pretty_subgoals As) @ wenzelm@32089: pretty_ffpairs tpairs @ wenzelm@32089: (if ! show_consts then pretty_consts prop else []) @ wenzelm@32089: (if types then pretty_vars prop else []) @ wenzelm@32089: (if sorts then pretty_varsT prop else []); wenzelm@32089: in wenzelm@32966: setmp_CRITICAL show_no_free_types true wenzelm@32966: (setmp_CRITICAL show_types (! show_types orelse ! show_sorts orelse ! show_all_types) wenzelm@32966: (setmp_CRITICAL show_sorts false pretty_gs)) wenzelm@32089: (! show_types orelse ! show_sorts orelse ! show_all_types, ! show_sorts) wenzelm@32089: end; wenzelm@32089: wenzelm@32145: fun pretty_goals_without_context n th = wenzelm@32167: pretty_goals (Syntax.init_pretty_global (Thm.theory_of_thm th)) wenzelm@32167: {total = true, main = true, maxgoals = n} th; wenzelm@32089: wenzelm@32089: end; wenzelm@32089: wenzelm@32089: end; wenzelm@32089: