author | berghofe |
Fri, 09 Jul 2004 16:29:10 +0200 | |
changeset 15030 | 1be2cce95318 |
parent 15010 | 72fbe711e414 |
child 15134 | d3fa5e1d6e4d |
permissions | -rw-r--r-- |
12780 | 1 |
(* Title: Pure/proof_general.ML |
12778 | 2 |
ID: $Id$ |
14675 | 3 |
Author: David Aspinall and Markus Wenzel |
12778 | 4 |
|
14566 | 5 |
Isabelle configuration for Proof General (see http://proofgeneral.inf.ed.ac.uk). |
12778 | 6 |
*) |
7 |
||
8 |
signature PROOF_GENERAL = |
|
9 |
sig |
|
10 |
val setup: (theory -> theory) list |
|
11 |
val update_thy_only: string -> unit |
|
12 |
val try_update_thy_only: string -> unit |
|
13391 | 13 |
val inform_file_retracted: string -> unit |
12778 | 14 |
val inform_file_processed: string -> unit |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
15 |
val options: (string * (string * (string * (unit -> string) * (string -> unit)))) list ref |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
16 |
val process_pgip: string -> unit |
12778 | 17 |
val thms_containing: string list -> unit |
18 |
val help: unit -> unit |
|
19 |
val show_context: unit -> theory |
|
20 |
val kill_goal: unit -> unit |
|
21 |
val repeat_undo: int -> unit |
|
22 |
val isa_restart: unit -> unit |
|
12833 | 23 |
val full_proofs: bool -> unit |
12778 | 24 |
val init: bool -> unit |
25 |
val write_keywords: string -> unit |
|
26 |
end; |
|
27 |
||
28 |
structure ProofGeneral: PROOF_GENERAL = |
|
29 |
struct |
|
30 |
||
31 |
(* print modes *) |
|
32 |
||
33 |
val proof_generalN = "ProofGeneral"; |
|
34 |
val xsymbolsN = "xsymbols"; |
|
13538 | 35 |
val thm_depsN = "thm_deps"; |
12778 | 36 |
|
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
37 |
val pgml_version_supported = "1.0"; |
12778 | 38 |
val pgmlN = "PGML"; |
39 |
fun pgml () = pgmlN mem_string ! print_mode; |
|
40 |
||
41 |
||
42 |
(* text output *) |
|
43 |
||
44 |
local |
|
45 |
||
14827 | 46 |
fun xsym_output "\\" = "\\\\" |
47 |
| xsym_output s = if Symbol.is_raw s then Symbol.decode_raw s else s; |
|
48 |
||
12778 | 49 |
fun xsymbols_output s = |
14992 | 50 |
if Symbol.chars_only s then Symbol.default_output s |
51 |
else if Output.has_mode xsymbolsN then |
|
12778 | 52 |
let val syms = Symbol.explode s |
14827 | 53 |
in (implode (map xsym_output syms), real (Symbol.length syms)) end |
14992 | 54 |
else Symbol.symbol_output s; |
12778 | 55 |
|
56 |
fun pgml_output (s, len) = |
|
57 |
if pgml () then (XML.text s, len) |
|
58 |
else (s, len); |
|
59 |
||
60 |
in |
|
61 |
||
14827 | 62 |
fun setup_xsymbols_output () = Output.add_mode proof_generalN |
14973 | 63 |
(pgml_output o xsymbols_output, Symbol.default_indent, Symbol.encode_raw); |
12778 | 64 |
|
65 |
end; |
|
66 |
||
67 |
||
68 |
(* token translations *) |
|
69 |
||
70 |
local |
|
71 |
||
72 |
val end_tag = oct_char "350"; |
|
73 |
val class_tag = ("class", oct_char "351"); |
|
74 |
val tfree_tag = ("tfree", oct_char "352"); |
|
75 |
val tvar_tag = ("tvar", oct_char "353"); |
|
76 |
val free_tag = ("free", oct_char "354"); |
|
77 |
val bound_tag = ("bound", oct_char "355"); |
|
78 |
val var_tag = ("var", oct_char "356"); |
|
79 |
val skolem_tag = ("skolem", oct_char "357"); |
|
80 |
||
81 |
fun xml_atom kind x = XML.element "atom" [("kind", kind)] [XML.text x]; |
|
82 |
||
83 |
fun tagit (kind, bg_tag) x = |
|
84 |
(if pgml () then xml_atom kind x else bg_tag ^ x ^ end_tag, |
|
85 |
real (Symbol.length (Symbol.explode x))); |
|
86 |
||
87 |
fun free_or_skolem x = |
|
88 |
(case try Syntax.dest_skolem x of |
|
89 |
None => tagit free_tag x |
|
90 |
| Some x' => tagit skolem_tag x'); |
|
91 |
||
92 |
fun var_or_skolem s = |
|
93 |
(case Syntax.read_var s of |
|
94 |
Var ((x, i), _) => |
|
95 |
(case try Syntax.dest_skolem x of |
|
96 |
None => tagit var_tag s |
|
97 |
| Some x' => tagit skolem_tag (Syntax.string_of_vname (x', i))) |
|
98 |
| _ => tagit var_tag s); |
|
99 |
||
100 |
val proof_general_trans = |
|
101 |
Syntax.tokentrans_mode proof_generalN |
|
102 |
[("class", tagit class_tag), |
|
103 |
("tfree", tagit tfree_tag), |
|
104 |
("tvar", tagit tvar_tag), |
|
105 |
("free", free_or_skolem), |
|
106 |
("bound", tagit bound_tag), |
|
107 |
("var", var_or_skolem)]; |
|
108 |
||
109 |
in val setup = [Theory.add_tokentrfuns proof_general_trans] end; |
|
110 |
||
111 |
||
112 |
(* messages and notification *) |
|
113 |
||
114 |
local |
|
115 |
||
116 |
fun decorated_output bg en prfx = |
|
117 |
writeln_default o enclose bg en o prefix_lines prfx; |
|
118 |
||
119 |
fun message kind bg en prfx s = |
|
120 |
if pgml () then writeln_default (XML.element kind [] [prefix_lines prfx s]) |
|
121 |
else decorated_output bg en prfx s; |
|
122 |
||
13526 | 123 |
in |
12778 | 124 |
|
13526 | 125 |
val notify = message "notify" (oct_char "360") (oct_char "361") ""; |
12778 | 126 |
|
127 |
fun setup_messages () = |
|
128 |
(writeln_fn := message "output" "" "" ""; |
|
129 |
priority_fn := message "information" (oct_char "360") (oct_char "361") ""; |
|
130 |
tracing_fn := message "tracing" (oct_char "360" ^ oct_char "375") (oct_char "361") ""; |
|
131 |
warning_fn := message "warning" (oct_char "362") (oct_char "363") "### "; |
|
132 |
error_fn := message "error" (oct_char "364") (oct_char "365") "*** "); |
|
133 |
||
134 |
fun tell_clear_goals () = notify "Proof General, please clear the goals buffer."; |
|
135 |
fun tell_clear_response () = notify "Proof General, please clear the response buffer."; |
|
136 |
fun tell_file msg path = notify ("Proof General, " ^ msg ^ " " ^ quote (File.sysify_path path)); |
|
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
137 |
val tell_unlock = tell_file "you can unlock the file"; |
12778 | 138 |
|
139 |
end; |
|
140 |
||
141 |
||
142 |
(* theory / proof state output *) |
|
143 |
||
144 |
local |
|
145 |
||
146 |
fun tmp_markers f = |
|
147 |
setmp Display.current_goals_markers (oct_char "366", oct_char "367", "") f (); |
|
148 |
||
149 |
fun statedisplay prts = |
|
150 |
writeln_default (XML.element "statedisplay" [] [Pretty.string_of (Pretty.chunks prts)]); |
|
151 |
||
152 |
fun print_current_goals n m st = |
|
153 |
if pgml () then statedisplay (Display.pretty_current_goals n m st) |
|
154 |
else tmp_markers (fn () => Display.print_current_goals_default n m st); |
|
155 |
||
156 |
fun print_state b st = |
|
157 |
if pgml () then statedisplay (Toplevel.pretty_state b st) |
|
158 |
else tmp_markers (fn () => Toplevel.print_state_default b st); |
|
159 |
||
160 |
in |
|
161 |
||
162 |
fun setup_state () = |
|
163 |
(Display.print_current_goals_fn := print_current_goals; |
|
164 |
Toplevel.print_state_fn := print_state; |
|
165 |
Toplevel.prompt_state_fn := (suffix (oct_char "372") o Toplevel.prompt_state_default)); |
|
166 |
||
167 |
end; |
|
168 |
||
169 |
||
13538 | 170 |
(* theorem dependency output *) |
13526 | 171 |
|
172 |
local |
|
173 |
||
13545 | 174 |
val spaces_quote = space_implode " " o map quote; |
175 |
||
13526 | 176 |
fun tell_thm_deps ths = |
13538 | 177 |
conditional (thm_depsN mem_string ! print_mode) (fn () => |
178 |
let |
|
13545 | 179 |
val names = map Thm.name_of_thm ths \ ""; |
180 |
val deps = Symtab.keys (foldl (uncurry Proofterm.thms_of_proof) |
|
181 |
(Symtab.empty, map Thm.proof_of ths)) \ ""; |
|
13538 | 182 |
in |
13545 | 183 |
if null names orelse null deps then () |
184 |
else notify ("Proof General, theorem dependencies of " ^ spaces_quote names ^ " are " |
|
185 |
^ spaces_quote deps) |
|
13538 | 186 |
end); |
13526 | 187 |
|
188 |
in |
|
189 |
||
190 |
fun setup_present_hook () = |
|
191 |
Present.add_hook (fn _ => fn res => tell_thm_deps (flat (map #2 res))); |
|
192 |
||
193 |
end; |
|
194 |
||
195 |
||
12778 | 196 |
(* theory loader actions *) |
197 |
||
198 |
local |
|
199 |
||
200 |
fun add_master_files name files = |
|
201 |
let val masters = [ThyLoad.thy_path name, ThyLoad.ml_path name] |
|
202 |
in masters @ gen_rems (op = o pairself Path.base) (files, masters) end; |
|
203 |
||
204 |
fun trace_action action name = |
|
205 |
if action = ThyInfo.Update then |
|
206 |
seq (tell_file "this file is loaded:") (ThyInfo.loaded_files name) |
|
207 |
else if action = ThyInfo.Outdate orelse action = ThyInfo.Remove then |
|
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
208 |
seq tell_unlock (add_master_files name (ThyInfo.loaded_files name)) |
12778 | 209 |
else (); |
210 |
||
211 |
in |
|
212 |
fun setup_thy_loader () = ThyInfo.add_hook trace_action; |
|
213 |
fun sync_thy_loader () = seq (trace_action ThyInfo.Update) (ThyInfo.names ()); |
|
214 |
end; |
|
215 |
||
216 |
||
217 |
(* prepare theory context *) |
|
218 |
||
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
219 |
val thy_name = Path.pack o #1 o Path.split_ext o Path.base o Path.unpack; |
12778 | 220 |
val update_thy_only = setmp MetaSimplifier.trace_simp false ThyInfo.update_thy_only; |
221 |
||
222 |
fun which_context () = |
|
223 |
(case Context.get_context () of |
|
224 |
Some thy => " Using current (dynamic!) one: " ^ |
|
225 |
(case try PureThy.get_name thy of Some name => quote name | None => "<unnamed>") |
|
226 |
| None => ""); |
|
227 |
||
228 |
fun try_update_thy_only file = |
|
229 |
ThyLoad.cond_add_path (Path.dir (Path.unpack file)) (fn () => |
|
230 |
let val name = thy_name file in |
|
231 |
if is_some (ThyLoad.check_file (ThyLoad.thy_path name)) then update_thy_only name |
|
232 |
else warning ("Unkown theory context of ML file." ^ which_context ()) |
|
233 |
end) (); |
|
234 |
||
235 |
||
236 |
(* get informed about files *) |
|
237 |
||
13391 | 238 |
val inform_file_retracted = ThyInfo.if_known_thy ThyInfo.remove_thy o thy_name; |
239 |
val inform_file_processed = ThyInfo.if_known_thy ThyInfo.touch_child_thys o thy_name; |
|
12778 | 240 |
|
241 |
fun proper_inform_file_processed file state = |
|
242 |
let val name = thy_name file in |
|
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
243 |
if Toplevel.is_toplevel state andalso ThyInfo.known_thy name then |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
244 |
(ThyInfo.touch_child_thys name; |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
245 |
transform_error ThyInfo.pretend_use_thy_only name handle ERROR_MESSAGE msg => |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
246 |
(warning msg; warning ("Failed to register theory: " ^ quote name); |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
247 |
tell_unlock (Path.base (Path.unpack file)))) |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
248 |
else raise Toplevel.UNDEF |
12778 | 249 |
end; |
250 |
||
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
251 |
fun vacuous_inform_file_processed file state = |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
252 |
(warning ("No theory " ^ quote (thy_name file)); |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
253 |
tell_unlock (Path.base (Path.unpack file))); |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
254 |
|
12778 | 255 |
|
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
256 |
(* options *) |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
257 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
258 |
fun nat_option r = ("nat", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
259 |
(fn () => string_of_int (!r)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
260 |
(fn s => (case Syntax.read_nat s of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
261 |
None => error "nat_option: illegal value" |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
262 |
| Some i => r := i))); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
263 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
264 |
fun bool_option r = ("boolean", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
265 |
(fn () => Bool.toString (!r)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
266 |
(fn "false" => r := false | "true" => r := true |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
267 |
| _ => error "bool_option: illegal value")); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
268 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
269 |
val proof_option = ("boolean", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
270 |
(fn () => Bool.toString (!proofs >= 2)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
271 |
(fn "false" => proofs := 1 | "true" => proofs := 2 |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
272 |
| _ => error "proof_option: illegal value")); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
273 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
274 |
val thm_deps_option = ("boolean", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
275 |
(fn () => Bool.toString ("thm_deps" mem !print_mode)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
276 |
(fn "false" => print_mode := Library.gen_rems (op =) (!print_mode, ["thm_deps"]) |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
277 |
| "true" => print_mode := (["thm_deps"] @ !print_mode) |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
278 |
| _ => error "thm_deps_option: illegal value")); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
279 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
280 |
val print_depth_option = ("nat", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
281 |
(fn () => "10"), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
282 |
(fn s => (case Syntax.read_nat s of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
283 |
None => error "print_depth_option: illegal value" |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
284 |
| Some i => print_depth i))); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
285 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
286 |
val options = ref |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
287 |
[("show-types", ("Whether to show types in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
288 |
bool_option show_types)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
289 |
("show-sorts", ("Whether to show sorts in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
290 |
bool_option show_sorts)), |
14707 | 291 |
("show-structs", ("Whether to show implicit structures in Isabelle.", |
292 |
bool_option show_structs)), |
|
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
293 |
("show-consts", ("Whether to show types of consts in Isabelle goals.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
294 |
bool_option show_consts)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
295 |
("long-names", ("Whether to show fully qualified names in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
296 |
bool_option long_names)), |
13884 | 297 |
("show-brackets", ("Whether to show full bracketing in Isabelle.", |
298 |
bool_option show_brackets)), |
|
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
299 |
("eta-contract", ("Whether to print terms eta-contracted in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
300 |
bool_option Syntax.eta_contract)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
301 |
("trace-simplifier", ("Whether to trace the Simplifier in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
302 |
bool_option trace_simp)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
303 |
("trace-rules", ("Whether to trace the standard rules in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
304 |
bool_option trace_rules)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
305 |
("quick-and-dirty", ("Whether to take a few short cuts occasionally.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
306 |
bool_option quick_and_dirty)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
307 |
("full-proofs", ("Whether to record full proof objects internally.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
308 |
proof_option)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
309 |
("trace-unification", ("Whether to output error diagnostics during unification.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
310 |
bool_option Pattern.trace_unify_fail)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
311 |
("show-main-goal", ("Whether to show main goal.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
312 |
bool_option Proof.show_main_goal)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
313 |
("global-timing", ("Whether to enable timing in Isabelle.", |
14827 | 314 |
bool_option Output.timing)), |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
315 |
("theorem-dependencies", ("Whether to track theorem dependencies within Proof General.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
316 |
thm_deps_option)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
317 |
("goals-limit", ("Setting for maximum number of goals printed in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
318 |
nat_option goals_limit)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
319 |
("prems-limit", ("Setting for maximum number of premises printed in Isabelle/Isar.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
320 |
nat_option ProofContext.prems_limit)), |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
321 |
("print-depth", ("Setting for the ML print depth in Isabelle.", |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
322 |
print_depth_option))]; |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
323 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
324 |
|
14675 | 325 |
(* sending PGIP commands to the interface *) |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
326 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
327 |
fun issue_pgip pgips = notify (XML.element "pgip" [] pgips); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
328 |
|
14725 | 329 |
fun usespgml () = |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
330 |
issue_pgip [XML.element "usespgml" [("version", pgml_version_supported)] []]; |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
331 |
|
14675 | 332 |
(*NB: the default returned here is actually the current value, so |
333 |
repeated uses of <askprefs> will not work correctly*) |
|
14725 | 334 |
fun show_options () = issue_pgip (map |
14568 | 335 |
(fn (name, (descr, (ty, get, _))) => (XML.element "oldhaspref" |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
336 |
[("type", ty), ("descr", descr), ("default", get ())] [name])) (!options)); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
337 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
338 |
fun set_option name value = (case assoc (!options, name) of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
339 |
None => warning ("Unknown option: " ^ quote name) |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
340 |
| Some (_, (_, _, set)) => set value); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
341 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
342 |
fun get_option name = (case assoc (!options, name) of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
343 |
None => warning ("Unknown option: " ^ quote name) |
14725 | 344 |
| Some (_, (_, get, _)) => |
345 |
issue_pgip [XML.element "prefval" [("name", name)] [get ()]]); |
|
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
346 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
347 |
|
14675 | 348 |
(* processing PGIP commands from the interface *) |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
349 |
|
14675 | 350 |
(*FIXME: matching on attributes is a bit too strict here*) |
13728
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
351 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
352 |
fun process_pgip_element pgip = (case pgip of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
353 |
XML.Elem ("askpgml", _, []) => usespgml () |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
354 |
| XML.Elem ("askprefs", _, []) => show_options () |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
355 |
| XML.Elem ("getpref", [("name", name)], []) => get_option name |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
356 |
| XML.Elem ("setpref", [("name", name)], [XML.Text value]) => |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
357 |
set_option name value |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
358 |
| XML.Elem (e, _, _) => warning ("Unrecognized PGIP command: " ^ e) |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
359 |
| XML.Text t => warning ("Unrecognized PGIP command:\n" ^ t)); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
360 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
361 |
fun process_pgip s = (case XML.tree_of_string s of |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
362 |
XML.Elem ("pgip", _, pgips) => seq process_pgip_element pgips |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
363 |
| _ => warning ("Invalid PGIP packet received\n" ^ s)); |
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
364 |
|
8004e56204fd
Added some functions for processing PGIP (thanks to David Aspinall).
berghofe
parents:
13646
diff
changeset
|
365 |
|
12778 | 366 |
(* misc commands for ProofGeneral/isa *) |
367 |
||
368 |
fun thms_containing ss = |
|
13284 | 369 |
ProofContext.print_thms_containing (ProofContext.init (the_context ())) None ss; |
12778 | 370 |
|
371 |
val welcome = priority o Session.welcome; |
|
372 |
val help = welcome; |
|
373 |
val show_context = Context.the_context; |
|
374 |
||
375 |
fun kill_goal () = (Goals.reset_goals (); tell_clear_goals ()); |
|
376 |
||
377 |
fun no_print_goals f = setmp Display.print_current_goals_fn (fn _ => fn _ => fn _ => ()) f; |
|
378 |
||
379 |
fun repeat_undo 0 = () |
|
380 |
| repeat_undo 1 = undo () |
|
381 |
| repeat_undo n = (no_print_goals undo (); repeat_undo (n - 1)); |
|
382 |
||
383 |
||
384 |
(* restart top-level loop (keeps most state information) *) |
|
385 |
||
386 |
local |
|
387 |
||
388 |
fun restart isar = |
|
389 |
(if isar then tell_clear_goals () else kill_goal (); |
|
390 |
tell_clear_response (); |
|
391 |
welcome ()); |
|
392 |
||
393 |
in |
|
394 |
||
395 |
fun isa_restart () = restart false; |
|
396 |
fun isar_restart () = (sync_thy_loader (); restart true; raise Toplevel.RESTART); |
|
397 |
||
398 |
end; |
|
399 |
||
400 |
||
12833 | 401 |
fun full_proofs true = proofs := 2 |
402 |
| full_proofs false = proofs := 1; |
|
403 |
||
404 |
||
12778 | 405 |
(* outer syntax *) |
406 |
||
407 |
local structure P = OuterParse and K = OuterSyntax.Keyword in |
|
408 |
||
409 |
val undoP = |
|
410 |
OuterSyntax.improper_command "ProofGeneral.undo" "(internal)" K.control |
|
411 |
(Scan.succeed (Toplevel.no_timing o IsarCmd.undo)); |
|
412 |
||
413 |
val context_thy_onlyP = |
|
414 |
OuterSyntax.improper_command "ProofGeneral.context_thy_only" "(internal)" K.control |
|
415 |
(P.name >> (Toplevel.no_timing oo IsarThy.init_context update_thy_only)); |
|
416 |
||
417 |
val try_context_thy_onlyP = |
|
418 |
OuterSyntax.improper_command "ProofGeneral.try_context_thy_only" "(internal)" K.control |
|
419 |
(P.name >> (Toplevel.no_timing oo |
|
420 |
(Toplevel.imperative (K ()) oo IsarThy.init_context try_update_thy_only))); |
|
421 |
||
422 |
val restartP = |
|
423 |
OuterSyntax.improper_command "ProofGeneral.restart" "(internal)" K.control |
|
424 |
(P.opt_unit >> (Toplevel.no_timing oo K (Toplevel.imperative isar_restart))); |
|
425 |
||
426 |
val kill_proofP = |
|
427 |
OuterSyntax.improper_command "ProofGeneral.kill_proof" "(internal)" K.control |
|
428 |
(Scan.succeed (Toplevel.no_timing o IsarCmd.kill_proof_notify tell_clear_goals)); |
|
429 |
||
430 |
val inform_file_processedP = |
|
431 |
OuterSyntax.improper_command "ProofGeneral.inform_file_processed" "(internal)" K.control |
|
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
432 |
(P.name >> (fn file => Toplevel.no_timing o |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
433 |
Toplevel.keep (vacuous_inform_file_processed file) o |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
434 |
Toplevel.kill o |
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
435 |
Toplevel.keep (proper_inform_file_processed file))); |
12778 | 436 |
|
437 |
val inform_file_retractedP = |
|
438 |
OuterSyntax.improper_command "ProofGeneral.inform_file_retracted" "(internal)" K.control |
|
439 |
(P.name >> (Toplevel.no_timing oo |
|
14902
bef0dc694c48
Path.split_ext; more robust inform_file_processed;
wenzelm
parents:
14880
diff
changeset
|
440 |
(fn file => Toplevel.imperative (fn () => inform_file_retracted file)))); |
12778 | 441 |
|
14725 | 442 |
val process_pgipP = |
443 |
OuterSyntax.improper_command "ProofGeneral.process_pgip" "(internal)" K.control |
|
444 |
(P.text >> (Toplevel.no_timing oo |
|
445 |
(fn txt => Toplevel.imperative (fn () => process_pgip txt)))); |
|
446 |
||
12778 | 447 |
fun init_outer_syntax () = OuterSyntax.add_parsers |
14675 | 448 |
[undoP, restartP, kill_proofP, context_thy_onlyP, try_context_thy_onlyP, |
14725 | 449 |
inform_file_processedP, inform_file_retractedP, process_pgipP]; |
12778 | 450 |
|
451 |
end; |
|
452 |
||
453 |
||
454 |
(* init *) |
|
455 |
||
456 |
val initialized = ref false; |
|
457 |
||
458 |
fun init isar = |
|
459 |
(conditional (not (! initialized)) (fn () => |
|
460 |
(if isar then setmp warning_fn (K ()) init_outer_syntax () else (); |
|
461 |
setup_xsymbols_output (); |
|
462 |
setup_messages (); |
|
463 |
setup_state (); |
|
464 |
setup_thy_loader (); |
|
13526 | 465 |
setup_present_hook (); |
12778 | 466 |
set initialized; ())); |
467 |
sync_thy_loader (); |
|
468 |
print_mode := proof_generalN :: (! print_mode \ proof_generalN); |
|
469 |
set quick_and_dirty; |
|
470 |
ThmDeps.enable (); |
|
471 |
if isar then ml_prompts "ML> " "ML# " |
|
472 |
else ml_prompts ("> " ^ oct_char "372") ("- " ^ oct_char "373"); |
|
473 |
if isar then (welcome (); Isar.sync_main ()) else isa_restart ()); |
|
474 |
||
475 |
||
476 |
||
477 |
(** generate keyword classification file **) |
|
478 |
||
479 |
local |
|
480 |
||
481 |
val regexp_meta = explode ".*+?[]^$"; |
|
482 |
val regexp_quote = implode o map (fn c => if c mem regexp_meta then "\\\\" ^ c else c) o explode; |
|
483 |
||
484 |
fun defconst name strs = |
|
485 |
"\n(defconst isar-keywords-" ^ name ^ |
|
486 |
"\n '(" ^ space_implode "\n " (map (quote o regexp_quote) strs) ^ "))\n"; |
|
487 |
||
488 |
fun make_elisp_commands commands kind = |
|
489 |
defconst kind (mapfilter (fn (c, _, k, _) => if k = kind then Some c else None) commands); |
|
490 |
||
491 |
fun make_elisp_syntax (keywords, commands) = |
|
492 |
";;\n\ |
|
493 |
\;; Keyword classification tables for Isabelle/Isar.\n\ |
|
494 |
\;; This file was generated by " ^ Session.name () ^ " -- DO NOT EDIT!\n\ |
|
495 |
\;;\n\ |
|
496 |
\;; $" ^ "Id$\n\ |
|
497 |
\;;\n" ^ |
|
498 |
defconst "major" (map #1 commands) ^ |
|
14675 | 499 |
defconst "minor" (filter Syntax.is_ascii_identifier keywords) ^ |
12778 | 500 |
implode (map (make_elisp_commands commands) OuterSyntax.Keyword.kinds) ^ |
501 |
"\n(provide 'isar-keywords)\n"; |
|
502 |
||
503 |
in |
|
504 |
||
505 |
fun write_keywords s = |
|
506 |
(init_outer_syntax (); |
|
507 |
File.write (Path.unpack ("isar-keywords" ^ (if s = "" then "" else "-" ^ s) ^".el")) |
|
508 |
(make_elisp_syntax (OuterSyntax.dest_keywords (), OuterSyntax.dest_parsers ()))); |
|
509 |
||
510 |
end; |
|
511 |
||
512 |
end; |