wenzelm@18140
|
1 |
(* Title: Pure/Isar/element.ML
|
wenzelm@18140
|
2 |
ID: $Id$
|
wenzelm@18140
|
3 |
Author: Makarius
|
wenzelm@18140
|
4 |
|
wenzelm@18140
|
5 |
Explicit data structures for some Isar language elements.
|
wenzelm@18140
|
6 |
*)
|
wenzelm@18140
|
7 |
|
wenzelm@18140
|
8 |
signature ELEMENT =
|
wenzelm@18140
|
9 |
sig
|
wenzelm@19259
|
10 |
datatype ('typ, 'term) stmt =
|
wenzelm@19259
|
11 |
Shows of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
|
wenzelm@19259
|
12 |
Obtains of (string * ((string * 'typ option) list * 'term list)) list
|
wenzelm@19259
|
13 |
type statement (*= (string, string) stmt*)
|
wenzelm@19259
|
14 |
type statement_i (*= (typ, term) stmt*)
|
wenzelm@18140
|
15 |
datatype ('typ, 'term, 'fact) ctxt =
|
wenzelm@18669
|
16 |
Fixes of (string * 'typ option * mixfix) list |
|
wenzelm@18140
|
17 |
Constrains of (string * 'typ) list |
|
wenzelm@18140
|
18 |
Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
|
wenzelm@18140
|
19 |
Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
|
wenzelm@18140
|
20 |
Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list
|
wenzelm@18140
|
21 |
type context (*= (string, string, thmref) ctxt*)
|
wenzelm@18140
|
22 |
type context_i (*= (typ, term, thm list) ctxt*)
|
wenzelm@18140
|
23 |
val map_ctxt: {name: string -> string,
|
wenzelm@18669
|
24 |
var: string * mixfix -> string * mixfix,
|
wenzelm@18140
|
25 |
typ: 'typ -> 'a, term: 'term -> 'b, fact: 'fact -> 'c,
|
wenzelm@18140
|
26 |
attrib: Attrib.src -> Attrib.src} -> ('typ, 'term, 'fact) ctxt -> ('a, 'b, 'c) ctxt
|
wenzelm@18140
|
27 |
val map_ctxt_values: (typ -> typ) -> (term -> term) -> (thm -> thm) -> context_i -> context_i
|
wenzelm@18140
|
28 |
val rename: (string * (string * mixfix option)) list -> string -> string
|
wenzelm@18669
|
29 |
val rename_var: (string * (string * mixfix option)) list -> string * mixfix -> string * mixfix
|
wenzelm@18140
|
30 |
val rename_term: (string * (string * mixfix option)) list -> term -> term
|
wenzelm@18140
|
31 |
val rename_thm: (string * (string * mixfix option)) list -> thm -> thm
|
wenzelm@18140
|
32 |
val rename_ctxt: (string * (string * mixfix option)) list -> context_i -> context_i
|
wenzelm@18140
|
33 |
val instT_type: typ Symtab.table -> typ -> typ
|
wenzelm@18140
|
34 |
val instT_term: typ Symtab.table -> term -> term
|
wenzelm@18140
|
35 |
val instT_thm: theory -> typ Symtab.table -> thm -> thm
|
wenzelm@18140
|
36 |
val instT_ctxt: theory -> typ Symtab.table -> context_i -> context_i
|
wenzelm@18140
|
37 |
val inst_term: typ Symtab.table * term Symtab.table -> term -> term
|
wenzelm@18140
|
38 |
val inst_thm: theory -> typ Symtab.table * term Symtab.table -> thm -> thm
|
wenzelm@18140
|
39 |
val inst_ctxt: theory -> typ Symtab.table * term Symtab.table -> context_i -> context_i
|
wenzelm@19259
|
40 |
val pretty_stmt: ProofContext.context -> statement_i -> Pretty.T list
|
wenzelm@19259
|
41 |
val pretty_ctxt: ProofContext.context -> context_i -> Pretty.T list
|
wenzelm@19267
|
42 |
val pretty_statement: ProofContext.context -> string -> thm -> Pretty.T
|
wenzelm@18140
|
43 |
end;
|
wenzelm@18140
|
44 |
|
wenzelm@18140
|
45 |
structure Element: ELEMENT =
|
wenzelm@18140
|
46 |
struct
|
wenzelm@18140
|
47 |
|
wenzelm@19259
|
48 |
|
wenzelm@19259
|
49 |
(** conclusions **)
|
wenzelm@19259
|
50 |
|
wenzelm@19259
|
51 |
datatype ('typ, 'term) stmt =
|
wenzelm@19259
|
52 |
Shows of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
|
wenzelm@19259
|
53 |
Obtains of (string * ((string * 'typ option) list * 'term list)) list;
|
wenzelm@19259
|
54 |
|
wenzelm@19259
|
55 |
type statement = (string, string) stmt;
|
wenzelm@19259
|
56 |
type statement_i = (typ, term) stmt;
|
wenzelm@19259
|
57 |
|
wenzelm@19259
|
58 |
|
wenzelm@19259
|
59 |
|
wenzelm@18140
|
60 |
(** context elements **)
|
wenzelm@18140
|
61 |
|
wenzelm@18140
|
62 |
(* datatype ctxt *)
|
wenzelm@18140
|
63 |
|
wenzelm@18140
|
64 |
datatype ('typ, 'term, 'fact) ctxt =
|
wenzelm@18669
|
65 |
Fixes of (string * 'typ option * mixfix) list |
|
wenzelm@18140
|
66 |
Constrains of (string * 'typ) list |
|
wenzelm@18140
|
67 |
Assumes of ((string * Attrib.src list) * ('term * ('term list * 'term list)) list) list |
|
wenzelm@18140
|
68 |
Defines of ((string * Attrib.src list) * ('term * 'term list)) list |
|
wenzelm@18140
|
69 |
Notes of ((string * Attrib.src list) * ('fact * Attrib.src list) list) list;
|
wenzelm@18140
|
70 |
|
wenzelm@18140
|
71 |
type context = (string, string, thmref) ctxt;
|
wenzelm@18140
|
72 |
type context_i = (typ, term, thm list) ctxt;
|
wenzelm@18140
|
73 |
|
wenzelm@18140
|
74 |
fun map_ctxt {name, var, typ, term, fact, attrib} =
|
wenzelm@18140
|
75 |
fn Fixes fixes => Fixes (fixes |> map (fn (x, T, mx) =>
|
wenzelm@18140
|
76 |
let val (x', mx') = var (x, mx) in (x', Option.map typ T, mx') end))
|
wenzelm@18669
|
77 |
| Constrains xs => Constrains (xs |> map (fn (x, T) => (#1 (var (x, NoSyn)), typ T)))
|
wenzelm@18140
|
78 |
| Assumes asms => Assumes (asms |> map (fn ((a, atts), propps) =>
|
wenzelm@18140
|
79 |
((name a, map attrib atts), propps |> map (fn (t, (ps, qs)) =>
|
wenzelm@18140
|
80 |
(term t, (map term ps, map term qs))))))
|
wenzelm@18140
|
81 |
| Defines defs => Defines (defs |> map (fn ((a, atts), (t, ps)) =>
|
wenzelm@18140
|
82 |
((name a, map attrib atts), (term t, map term ps))))
|
wenzelm@18140
|
83 |
| Notes facts => Notes (facts |> map (fn ((a, atts), bs) =>
|
wenzelm@18140
|
84 |
((name a, map attrib atts), bs |> map (fn (ths, btts) => (fact ths, map attrib btts)))));
|
wenzelm@18140
|
85 |
|
wenzelm@18140
|
86 |
fun map_ctxt_values typ term thm = map_ctxt
|
wenzelm@18140
|
87 |
{name = I, var = I, typ = typ, term = term, fact = map thm,
|
wenzelm@18140
|
88 |
attrib = Args.map_values I typ term thm};
|
wenzelm@18140
|
89 |
|
wenzelm@18140
|
90 |
|
wenzelm@18140
|
91 |
|
wenzelm@18140
|
92 |
(** logical operations **)
|
wenzelm@18140
|
93 |
|
wenzelm@18140
|
94 |
(* derived rules *)
|
wenzelm@18140
|
95 |
|
wenzelm@18140
|
96 |
fun instantiate_tfrees thy subst =
|
wenzelm@18140
|
97 |
let
|
wenzelm@18140
|
98 |
val certT = Thm.ctyp_of thy;
|
wenzelm@18140
|
99 |
fun inst vs (a, T) = AList.lookup (op =) vs a
|
wenzelm@18140
|
100 |
|> Option.map (fn v => (certT (TVar v), certT T));
|
wenzelm@18140
|
101 |
in
|
wenzelm@18140
|
102 |
Drule.tvars_intr_list (map fst subst) #->
|
wenzelm@19482
|
103 |
(fn vs => Thm.instantiate (map_filter (inst vs) subst, []))
|
wenzelm@18140
|
104 |
end;
|
wenzelm@18140
|
105 |
|
wenzelm@18140
|
106 |
fun instantiate_frees thy subst =
|
wenzelm@18140
|
107 |
let val cert = Thm.cterm_of thy in
|
wenzelm@18140
|
108 |
Drule.forall_intr_list (map (cert o Free o fst) subst) #>
|
wenzelm@18140
|
109 |
Drule.forall_elim_list (map (cert o snd) subst)
|
wenzelm@18140
|
110 |
end;
|
wenzelm@18140
|
111 |
|
wenzelm@18140
|
112 |
fun hyps_rule rule th =
|
wenzelm@18140
|
113 |
let
|
wenzelm@18140
|
114 |
val cterm_rule = Thm.reflexive #> rule #> Thm.cprop_of #> Drule.dest_equals #> #1;
|
wenzelm@18140
|
115 |
val {hyps, ...} = Thm.crep_thm th;
|
wenzelm@18140
|
116 |
in
|
wenzelm@18140
|
117 |
Drule.implies_elim_list
|
wenzelm@18140
|
118 |
(rule (Drule.implies_intr_list hyps th))
|
wenzelm@18140
|
119 |
(map (Thm.assume o cterm_rule) hyps)
|
wenzelm@18140
|
120 |
end;
|
wenzelm@18140
|
121 |
|
wenzelm@18140
|
122 |
|
wenzelm@18140
|
123 |
(* renaming *)
|
wenzelm@18140
|
124 |
|
wenzelm@18140
|
125 |
fun rename ren x =
|
wenzelm@18140
|
126 |
(case AList.lookup (op =) ren (x: string) of
|
wenzelm@18140
|
127 |
NONE => x
|
wenzelm@18140
|
128 |
| SOME (x', _) => x');
|
wenzelm@18140
|
129 |
|
wenzelm@18140
|
130 |
fun rename_var ren (x, mx) =
|
wenzelm@18669
|
131 |
(case (AList.lookup (op =) ren (x: string), mx) of
|
wenzelm@18140
|
132 |
(NONE, _) => (x, mx)
|
wenzelm@18669
|
133 |
| (SOME (x', NONE), Structure) => (x', mx)
|
wenzelm@18669
|
134 |
| (SOME (x', SOME _), Structure) =>
|
wenzelm@18669
|
135 |
error ("Attempt to change syntax of structure parameter " ^ quote x)
|
wenzelm@18669
|
136 |
| (SOME (x', NONE), _) => (x', NoSyn)
|
wenzelm@18669
|
137 |
| (SOME (x', SOME mx'), _) => (x', mx'));
|
wenzelm@18140
|
138 |
|
wenzelm@18140
|
139 |
fun rename_term ren (Free (x, T)) = Free (rename ren x, T)
|
wenzelm@18140
|
140 |
| rename_term ren (t $ u) = rename_term ren t $ rename_term ren u
|
wenzelm@18140
|
141 |
| rename_term ren (Abs (x, T, t)) = Abs (x, T, rename_term ren t)
|
wenzelm@18140
|
142 |
| rename_term _ a = a;
|
wenzelm@18140
|
143 |
|
wenzelm@18140
|
144 |
fun rename_thm ren th =
|
wenzelm@18140
|
145 |
let
|
wenzelm@18140
|
146 |
val subst = Drule.frees_of th
|
wenzelm@19482
|
147 |
|> map_filter (fn (x, T) =>
|
wenzelm@18140
|
148 |
let val x' = rename ren x
|
wenzelm@18140
|
149 |
in if x = x' then NONE else SOME ((x, T), (Free (x', T))) end);
|
wenzelm@18140
|
150 |
in
|
wenzelm@18140
|
151 |
if null subst then th
|
wenzelm@18140
|
152 |
else th |> hyps_rule (instantiate_frees (Thm.theory_of_thm th) subst)
|
wenzelm@18140
|
153 |
end;
|
wenzelm@18140
|
154 |
|
wenzelm@18140
|
155 |
fun rename_ctxt ren =
|
wenzelm@18140
|
156 |
map_ctxt_values I (rename_term ren) (rename_thm ren)
|
wenzelm@18140
|
157 |
#> map_ctxt {name = I, typ = I, term = I, fact = I, attrib = I, var = rename_var ren};
|
wenzelm@18140
|
158 |
|
wenzelm@18140
|
159 |
|
wenzelm@18140
|
160 |
(* type instantiation *)
|
wenzelm@18140
|
161 |
|
wenzelm@18140
|
162 |
fun instT_type env =
|
wenzelm@18140
|
163 |
if Symtab.is_empty env then I
|
wenzelm@18140
|
164 |
else Term.map_type_tfree (fn (x, S) => the_default (TFree (x, S)) (Symtab.lookup env x));
|
wenzelm@18140
|
165 |
|
wenzelm@18140
|
166 |
fun instT_term env =
|
wenzelm@18140
|
167 |
if Symtab.is_empty env then I
|
wenzelm@18140
|
168 |
else Term.map_term_types (instT_type env);
|
wenzelm@18140
|
169 |
|
wenzelm@18140
|
170 |
fun instT_subst env th =
|
wenzelm@18140
|
171 |
Drule.tfrees_of th
|
wenzelm@19482
|
172 |
|> map_filter (fn (a, S) =>
|
wenzelm@18140
|
173 |
let
|
wenzelm@18140
|
174 |
val T = TFree (a, S);
|
wenzelm@18140
|
175 |
val T' = the_default T (Symtab.lookup env a);
|
wenzelm@18140
|
176 |
in if T = T' then NONE else SOME (a, T') end);
|
wenzelm@18140
|
177 |
|
wenzelm@18140
|
178 |
fun instT_thm thy env th =
|
wenzelm@18140
|
179 |
if Symtab.is_empty env then th
|
wenzelm@18140
|
180 |
else
|
wenzelm@18140
|
181 |
let val subst = instT_subst env th
|
wenzelm@18140
|
182 |
in if null subst then th else th |> hyps_rule (instantiate_tfrees thy subst) end;
|
wenzelm@18140
|
183 |
|
wenzelm@18140
|
184 |
fun instT_ctxt thy env =
|
wenzelm@18140
|
185 |
map_ctxt_values (instT_type env) (instT_term env) (instT_thm thy env);
|
wenzelm@18140
|
186 |
|
wenzelm@18140
|
187 |
|
wenzelm@18140
|
188 |
(* type and term instantiation *)
|
wenzelm@18140
|
189 |
|
wenzelm@18140
|
190 |
fun inst_term (envT, env) =
|
wenzelm@18140
|
191 |
if Symtab.is_empty env then instT_term envT
|
wenzelm@18140
|
192 |
else
|
wenzelm@18140
|
193 |
let
|
wenzelm@18140
|
194 |
val instT = instT_type envT;
|
wenzelm@18140
|
195 |
fun inst (Const (x, T)) = Const (x, instT T)
|
wenzelm@18140
|
196 |
| inst (Free (x, T)) =
|
wenzelm@18140
|
197 |
(case Symtab.lookup env x of
|
wenzelm@18140
|
198 |
NONE => Free (x, instT T)
|
wenzelm@18140
|
199 |
| SOME t => t)
|
wenzelm@18140
|
200 |
| inst (Var (xi, T)) = Var (xi, instT T)
|
wenzelm@18140
|
201 |
| inst (b as Bound _) = b
|
wenzelm@18140
|
202 |
| inst (Abs (x, T, t)) = Abs (x, instT T, inst t)
|
wenzelm@18140
|
203 |
| inst (t $ u) = inst t $ inst u;
|
wenzelm@18140
|
204 |
in Envir.beta_norm o inst end;
|
wenzelm@18140
|
205 |
|
wenzelm@18140
|
206 |
fun inst_thm thy (envT, env) th =
|
wenzelm@18140
|
207 |
if Symtab.is_empty env then instT_thm thy envT th
|
wenzelm@18140
|
208 |
else
|
wenzelm@18140
|
209 |
let
|
wenzelm@18140
|
210 |
val substT = instT_subst envT th;
|
wenzelm@18140
|
211 |
val subst = Drule.frees_of th
|
wenzelm@19482
|
212 |
|> map_filter (fn (x, T) =>
|
wenzelm@18140
|
213 |
let
|
wenzelm@18140
|
214 |
val T' = instT_type envT T;
|
wenzelm@18140
|
215 |
val t = Free (x, T');
|
wenzelm@18140
|
216 |
val t' = the_default t (Symtab.lookup env x);
|
wenzelm@18140
|
217 |
in if t aconv t' then NONE else SOME ((x, T'), t') end);
|
wenzelm@18140
|
218 |
in
|
wenzelm@18140
|
219 |
if null substT andalso null subst then th
|
wenzelm@18140
|
220 |
else th |> hyps_rule
|
wenzelm@18140
|
221 |
(instantiate_tfrees thy substT #>
|
wenzelm@18140
|
222 |
instantiate_frees thy subst #>
|
wenzelm@18140
|
223 |
Drule.fconv_rule (Thm.beta_conversion true))
|
wenzelm@18140
|
224 |
end;
|
wenzelm@18140
|
225 |
|
wenzelm@18140
|
226 |
fun inst_ctxt thy envs =
|
wenzelm@18140
|
227 |
map_ctxt_values (instT_type (#1 envs)) (inst_term envs) (inst_thm thy envs);
|
wenzelm@18140
|
228 |
|
wenzelm@18894
|
229 |
|
wenzelm@18894
|
230 |
|
wenzelm@19259
|
231 |
(** pretty printing **)
|
wenzelm@19259
|
232 |
|
wenzelm@19267
|
233 |
fun pretty_items _ _ [] = []
|
wenzelm@19267
|
234 |
| pretty_items keyword sep (x :: ys) =
|
wenzelm@19267
|
235 |
Pretty.block [Pretty.keyword keyword, Pretty.brk 1, x] ::
|
wenzelm@19267
|
236 |
map (fn y => Pretty.block [Pretty.str " ", Pretty.keyword sep, Pretty.brk 1, y]) ys;
|
wenzelm@19259
|
237 |
|
wenzelm@19259
|
238 |
fun pretty_name_atts ctxt (name, atts) sep =
|
wenzelm@19259
|
239 |
if name = "" andalso null atts then []
|
wenzelm@19259
|
240 |
else [Pretty.block (Pretty.breaks (Pretty.str (ProofContext.extern_thm ctxt name) ::
|
wenzelm@19259
|
241 |
Args.pretty_attribs ctxt atts @ [Pretty.str sep]))];
|
wenzelm@19259
|
242 |
|
wenzelm@19259
|
243 |
|
wenzelm@19259
|
244 |
(* pretty_stmt *)
|
wenzelm@19259
|
245 |
|
wenzelm@19259
|
246 |
fun pretty_stmt ctxt =
|
wenzelm@19259
|
247 |
let
|
wenzelm@19259
|
248 |
val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
|
wenzelm@19259
|
249 |
val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
|
wenzelm@19267
|
250 |
val prt_terms = separate (Pretty.keyword "and") o map prt_term;
|
wenzelm@19259
|
251 |
val prt_name_atts = pretty_name_atts ctxt;
|
wenzelm@19259
|
252 |
|
wenzelm@19259
|
253 |
fun prt_show (a, ts) =
|
wenzelm@19267
|
254 |
Pretty.block (Pretty.breaks (prt_name_atts a ":" @ prt_terms (map fst ts)));
|
wenzelm@19259
|
255 |
|
wenzelm@19259
|
256 |
fun prt_var (x, SOME T) = Pretty.block [Pretty.str (x ^ " ::"), Pretty.brk 1, prt_typ T]
|
wenzelm@19259
|
257 |
| prt_var (x, NONE) = Pretty.str x;
|
wenzelm@19259
|
258 |
|
wenzelm@19267
|
259 |
fun prt_obtain (_, ([], ts)) = Pretty.block (Pretty.breaks (prt_terms ts))
|
wenzelm@19259
|
260 |
| prt_obtain (_, (xs, ts)) = Pretty.block (Pretty.breaks
|
wenzelm@19267
|
261 |
(map prt_var xs @ [Pretty.keyword "where"] @ prt_terms ts));
|
wenzelm@19259
|
262 |
in
|
wenzelm@19267
|
263 |
fn Shows shows => pretty_items "shows" "and" (map prt_show shows)
|
wenzelm@19267
|
264 |
| Obtains obtains => pretty_items "obtains" "|" (map prt_obtain obtains)
|
wenzelm@19259
|
265 |
end;
|
wenzelm@19259
|
266 |
|
wenzelm@18894
|
267 |
|
wenzelm@19259
|
268 |
(* pretty_ctxt *)
|
wenzelm@19259
|
269 |
|
wenzelm@19259
|
270 |
fun pretty_ctxt ctxt =
|
wenzelm@19259
|
271 |
let
|
wenzelm@19259
|
272 |
val prt_typ = Pretty.quote o ProofContext.pretty_typ ctxt;
|
wenzelm@19259
|
273 |
val prt_term = Pretty.quote o ProofContext.pretty_term ctxt;
|
wenzelm@19259
|
274 |
val prt_thm = Pretty.backquote o ProofContext.pretty_thm ctxt;
|
wenzelm@19259
|
275 |
val prt_name_atts = pretty_name_atts ctxt;
|
wenzelm@19259
|
276 |
|
wenzelm@19267
|
277 |
fun prt_mixfix NoSyn = []
|
wenzelm@19267
|
278 |
| prt_mixfix mx = [Pretty.brk 2, Syntax.pretty_mixfix mx];
|
wenzelm@19267
|
279 |
|
wenzelm@19259
|
280 |
fun prt_fix (x, SOME T, mx) = Pretty.block (Pretty.str (x ^ " ::") :: Pretty.brk 1 ::
|
wenzelm@19259
|
281 |
prt_typ T :: Pretty.brk 1 :: prt_mixfix mx)
|
wenzelm@19259
|
282 |
| prt_fix (x, NONE, mx) = Pretty.block (Pretty.str x :: Pretty.brk 1 :: prt_mixfix mx);
|
wenzelm@19259
|
283 |
fun prt_constrain (x, T) = prt_fix (x, SOME T, NoSyn);
|
wenzelm@18894
|
284 |
|
wenzelm@19259
|
285 |
fun prt_asm (a, ts) =
|
wenzelm@19259
|
286 |
Pretty.block (Pretty.breaks (prt_name_atts a ":" @ map (prt_term o fst) ts));
|
wenzelm@19259
|
287 |
fun prt_def (a, (t, _)) =
|
wenzelm@19259
|
288 |
Pretty.block (Pretty.breaks (prt_name_atts a ":" @ [prt_term t]));
|
wenzelm@19259
|
289 |
|
wenzelm@19259
|
290 |
fun prt_fact (ths, []) = map prt_thm ths
|
wenzelm@19259
|
291 |
| prt_fact (ths, atts) = Pretty.enclose "(" ")"
|
wenzelm@19259
|
292 |
(Pretty.breaks (map prt_thm ths)) :: Args.pretty_attribs ctxt atts;
|
wenzelm@19259
|
293 |
fun prt_note (a, ths) =
|
wenzelm@19482
|
294 |
Pretty.block (Pretty.breaks (flat (prt_name_atts a "=" :: map prt_fact ths)));
|
wenzelm@19259
|
295 |
in
|
wenzelm@19267
|
296 |
fn Fixes fixes => pretty_items "fixes" "and" (map prt_fix fixes)
|
wenzelm@19267
|
297 |
| Constrains xs => pretty_items "constrains" "and" (map prt_constrain xs)
|
wenzelm@19267
|
298 |
| Assumes asms => pretty_items "assumes" "and" (map prt_asm asms)
|
wenzelm@19267
|
299 |
| Defines defs => pretty_items "defines" "and" (map prt_def defs)
|
wenzelm@19267
|
300 |
| Notes facts => pretty_items "notes" "and" (map prt_note facts)
|
wenzelm@19259
|
301 |
end;
|
wenzelm@18894
|
302 |
|
wenzelm@19267
|
303 |
|
wenzelm@19267
|
304 |
(* pretty_statement *)
|
wenzelm@19267
|
305 |
|
wenzelm@19267
|
306 |
local
|
wenzelm@19267
|
307 |
|
wenzelm@19267
|
308 |
fun thm_name kind th prts =
|
wenzelm@19267
|
309 |
let val head =
|
wenzelm@19267
|
310 |
(case #1 (Thm.get_name_tags th) of
|
wenzelm@19267
|
311 |
"" => Pretty.command kind
|
wenzelm@19267
|
312 |
| a => Pretty.block [Pretty.command kind, Pretty.brk 1, Pretty.str (Sign.base_name a ^ ":")])
|
wenzelm@19267
|
313 |
in Pretty.block (Pretty.fbreaks (head :: prts)) end;
|
wenzelm@19267
|
314 |
|
wenzelm@19267
|
315 |
fun obtain prop ctxt =
|
wenzelm@19267
|
316 |
let
|
wenzelm@19267
|
317 |
val xs = ProofContext.rename_frees ctxt [] (Logic.strip_params prop);
|
wenzelm@19267
|
318 |
val args = rev (map Free xs);
|
wenzelm@19267
|
319 |
val As = Logic.strip_assums_hyp prop |> map (fn t => Term.subst_bounds (args, t));
|
wenzelm@19267
|
320 |
val ctxt' = ctxt |> fold ProofContext.declare_term args;
|
wenzelm@19267
|
321 |
in (("", (map (apsnd SOME) xs, As)), ctxt') end;
|
wenzelm@19267
|
322 |
|
wenzelm@19267
|
323 |
in
|
wenzelm@19267
|
324 |
|
wenzelm@19267
|
325 |
fun pretty_statement ctxt kind raw_th =
|
wenzelm@19267
|
326 |
let
|
wenzelm@19267
|
327 |
val thy = ProofContext.theory_of ctxt;
|
wenzelm@19267
|
328 |
val th = Goal.norm_hhf raw_th;
|
wenzelm@19267
|
329 |
|
wenzelm@19267
|
330 |
fun standard_thesis t =
|
wenzelm@19267
|
331 |
let
|
wenzelm@19267
|
332 |
val C = ObjectLogic.drop_judgment thy (Thm.concl_of th);
|
wenzelm@19466
|
333 |
val C' = Var ((AutoBind.thesisN, Thm.maxidx_of th + 1), Term.fastype_of C);
|
wenzelm@19267
|
334 |
in Term.subst_atomic [(C, C')] t end;
|
wenzelm@19267
|
335 |
|
wenzelm@19267
|
336 |
val raw_prop =
|
wenzelm@19267
|
337 |
Thm.prop_of th
|
wenzelm@19267
|
338 |
|> singleton (ProofContext.monomorphic ctxt)
|
wenzelm@19267
|
339 |
|> K (ObjectLogic.is_elim th) ? standard_thesis
|
wenzelm@19267
|
340 |
|> Term.zero_var_indexes;
|
wenzelm@19267
|
341 |
|
wenzelm@19267
|
342 |
val vars = Term.add_vars raw_prop [];
|
wenzelm@19267
|
343 |
val frees = ProofContext.rename_frees ctxt [raw_prop] (map (apfst fst) vars);
|
wenzelm@19305
|
344 |
val fixes = rev (filter_out (fn (x, _) => x = AutoBind.thesisN) frees);
|
wenzelm@19267
|
345 |
|
wenzelm@19267
|
346 |
val prop = Term.instantiate ([], vars ~~ map Free frees) raw_prop;
|
wenzelm@19267
|
347 |
val (prems, concl) = Logic.strip_horn prop;
|
wenzelm@19267
|
348 |
val thesis = ObjectLogic.fixed_judgment thy AutoBind.thesisN;
|
wenzelm@19267
|
349 |
val (asms, cases) = take_suffix (fn prem => thesis aconv Logic.strip_assums_concl prem) prems;
|
wenzelm@19267
|
350 |
in
|
wenzelm@19267
|
351 |
pretty_ctxt ctxt (Fixes (map (fn (x, T) => (x, SOME T, NoSyn)) fixes)) @
|
wenzelm@19267
|
352 |
pretty_ctxt ctxt (Assumes (map (fn t => (("", []), [(t, ([], []))])) asms)) @
|
wenzelm@19267
|
353 |
pretty_stmt ctxt
|
wenzelm@19267
|
354 |
(if null cases then Shows [(("", []), [(concl, ([], []))])]
|
wenzelm@19267
|
355 |
else Obtains (#1 (fold_map obtain cases (ctxt |> ProofContext.declare_term prop))))
|
wenzelm@19267
|
356 |
end |> thm_name kind raw_th;
|
wenzelm@19267
|
357 |
|
wenzelm@18140
|
358 |
end;
|
wenzelm@19267
|
359 |
|
wenzelm@19267
|
360 |
end;
|