| author | haftmann | 
| Wed, 05 Dec 2007 14:16:14 +0100 | |
| changeset 25542 | ced4104f6c1f | 
| parent 25445 | 01f3686f4304 | 
| child 25847 | 713519ba6860 | 
| permissions | -rw-r--r-- | 
| 21637 | 1  | 
(* Title: Pure/ProofGeneral/proof_general_pgip.ML  | 
2  | 
ID: $Id$  | 
|
3  | 
Author: David Aspinall and Markus Wenzel  | 
|
4  | 
||
5  | 
Isabelle configuration for Proof General using PGIP protocol.  | 
|
| 21940 | 6  | 
See http://proofgeneral.inf.ed.ac.uk/kit  | 
| 21637 | 7  | 
*)  | 
8  | 
||
9  | 
signature PROOF_GENERAL_PGIP =  | 
|
10  | 
sig  | 
|
| 21940 | 11  | 
val init_pgip: bool -> unit (* main PGIP loop with true; fail with false *)  | 
| 21642 | 12  | 
|
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
13  | 
(* These two are just to support the semi-PGIP Emacs mode *)  | 
| 21940 | 14  | 
val init_pgip_channel: (string -> unit) -> unit  | 
15  | 
val process_pgip: string -> unit  | 
|
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
16  | 
|
| 
23435
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
17  | 
(* More message functions... *)  | 
| 
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
18  | 
val nonfatal_error : string -> unit (* recoverable (batch) error: carry on scripting *)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
19  | 
val log_msg : string -> unit (* for internal log messages *)  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
20  | 
val error_with_pos : PgipTypes.displayarea -> PgipTypes.fatality -> Position.T -> string -> unit  | 
| 22159 | 21  | 
|
| 22163 | 22  | 
val get_currently_open_file : unit -> Path.T option (* interface focus *)  | 
| 21637 | 23  | 
end  | 
24  | 
||
25  | 
structure ProofGeneralPgip : PROOF_GENERAL_PGIP =  | 
|
26  | 
struct  | 
|
27  | 
||
28  | 
open Pgip;  | 
|
29  | 
||
| 21949 | 30  | 
|
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
31  | 
(** print mode **)  | 
| 21637 | 32  | 
|
| 22408 | 33  | 
val proof_generalN = "ProofGeneral";  | 
34  | 
val pgmlsymbols_flag = ref true;  | 
|
| 21637 | 35  | 
|
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
36  | 
|
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
37  | 
(* symbol output *)  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
38  | 
|
| 21637 | 39  | 
local  | 
40  | 
||
41  | 
fun xsym_output "\\" = "\\\\"  | 
|
42  | 
| xsym_output s = if Symbol.is_raw s then Symbol.decode_raw s else s;  | 
|
43  | 
||
44  | 
fun pgml_sym s =  | 
|
45  | 
(case Symbol.decode s of  | 
|
46  | 
Symbol.Char s => XML.text s  | 
|
| 22408 | 47  | 
| Symbol.Sym sn =>  | 
48  | 
let val ascii = implode (map xsym_output (Symbol.explode s))  | 
|
49  | 
    in if !pgmlsymbols_flag then XML.element "sym" [("name", sn)] [XML.text ascii]
 | 
|
50  | 
else ascii end  | 
|
51  | 
  | Symbol.Ctrl sn => XML.element "ctrl" [("name", sn)] [XML.text sn] (* FIXME: no such PGML *)
 | 
|
52  | 
| Symbol.Raw raw => raw);  | 
|
| 21637 | 53  | 
|
54  | 
fun pgml_output str =  | 
|
55  | 
let val syms = Symbol.explode str  | 
|
| 23621 | 56  | 
in (implode (map pgml_sym syms), Symbol.length syms) end;  | 
57  | 
||
| 21637 | 58  | 
in  | 
59  | 
||
| 22408 | 60  | 
fun setup_proofgeneral_output () =  | 
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
61  | 
Output.add_mode proof_generalN pgml_output Symbol.encode_raw;  | 
| 21637 | 62  | 
|
63  | 
end;  | 
|
64  | 
||
65  | 
||
66  | 
(* token translations *)  | 
|
67  | 
||
68  | 
local  | 
|
69  | 
||
70  | 
val class_tag = "class"  | 
|
71  | 
val tfree_tag = "tfree"  | 
|
72  | 
val tvar_tag = "tvar"  | 
|
73  | 
val free_tag = "free"  | 
|
74  | 
val bound_tag = "bound"  | 
|
75  | 
val var_tag = "var"  | 
|
76  | 
val skolem_tag = "skolem"  | 
|
77  | 
||
78  | 
fun xml_atom kind x = XML.element "atom" [("kind", kind)] [XML.text x];
 | 
|
79  | 
||
| 21940 | 80  | 
fun tagit kind x =  | 
| 23621 | 81  | 
(xml_atom kind x, Symbol.length (Symbol.explode x));  | 
| 21637 | 82  | 
|
83  | 
fun free_or_skolem x =  | 
|
84  | 
(case try Name.dest_skolem x of  | 
|
85  | 
NONE => tagit free_tag x  | 
|
86  | 
| SOME x' => tagit skolem_tag x');  | 
|
87  | 
||
88  | 
fun var_or_skolem s =  | 
|
| 24244 | 89  | 
(case Lexicon.read_variable s of  | 
| 21637 | 90  | 
SOME (x, i) =>  | 
91  | 
(case try Name.dest_skolem x of  | 
|
92  | 
NONE => tagit var_tag s  | 
|
93  | 
| SOME x' => tagit skolem_tag  | 
|
| 22678 | 94  | 
(setmp show_question_marks true Term.string_of_vname (x', i)))  | 
| 21637 | 95  | 
| NONE => tagit var_tag s);  | 
96  | 
||
97  | 
val proof_general_trans =  | 
|
98  | 
Syntax.tokentrans_mode proof_generalN  | 
|
99  | 
  [("class", tagit class_tag),
 | 
|
100  | 
   ("tfree", tagit tfree_tag),
 | 
|
101  | 
   ("tvar", tagit tvar_tag),
 | 
|
102  | 
   ("free", free_or_skolem),
 | 
|
103  | 
   ("bound", tagit bound_tag),
 | 
|
104  | 
   ("var", var_or_skolem)];
 | 
|
105  | 
||
106  | 
in  | 
|
107  | 
||
| 
24712
 
64ed05609568
proper Sign operations instead of Theory aliases;
 
wenzelm 
parents: 
24614 
diff
changeset
 | 
108  | 
val _ = Context.add_setup (Sign.add_tokentrfuns proof_general_trans);  | 
| 21637 | 109  | 
|
110  | 
end;  | 
|
111  | 
||
112  | 
||
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
113  | 
(* assembling and issuing PGIP packets *)  | 
| 21637 | 114  | 
|
115  | 
val pgip_refid = ref NONE: string option ref;  | 
|
116  | 
val pgip_refseq = ref NONE: int option ref;  | 
|
117  | 
||
118  | 
local  | 
|
119  | 
val pgip_class = "pg"  | 
|
120  | 
val pgip_tag = "Isabelle/Isar"  | 
|
121  | 
val pgip_id = ref ""  | 
|
122  | 
val pgip_seq = ref 0  | 
|
123  | 
fun pgip_serial () = inc pgip_seq  | 
|
124  | 
||
125  | 
fun assemble_pgips pgips =  | 
|
| 21940 | 126  | 
    Pgip { tag = SOME pgip_tag,
 | 
127  | 
class = pgip_class,  | 
|
128  | 
seq = pgip_serial(),  | 
|
129  | 
id = !pgip_id,  | 
|
130  | 
destid = !pgip_refid,  | 
|
131  | 
(* destid=refid since Isabelle only communicates back to sender *)  | 
|
132  | 
refid = !pgip_refid,  | 
|
133  | 
refseq = !pgip_refseq,  | 
|
134  | 
content = pgips }  | 
|
| 21637 | 135  | 
in  | 
136  | 
||
137  | 
fun init_pgip_session_id () =  | 
|
138  | 
pgip_id := getenv "HOSTNAME" ^ "/" ^ getenv "USER" ^ "/" ^  | 
|
139  | 
getenv "ISABELLE_PID" ^ "/" ^ Time.toString (Time.now ())  | 
|
140  | 
||
141  | 
fun matching_pgip_id id = (id = !pgip_id)  | 
|
142  | 
||
| 22590 | 143  | 
val output_xml_fn = ref Output.writeln_default  | 
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
144  | 
fun output_xml s = (!output_xml_fn) (XML.string_of_tree s); (* TODO: string buffer *)  | 
| 21637 | 145  | 
|
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
146  | 
val output_pgips =  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
147  | 
XML.string_of_tree o PgipOutput.output o assemble_pgips o map PgipOutput.output;  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
148  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
149  | 
val output_pgmlterm =  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
150  | 
XML.string_of_tree o Pgml.pgmlterm_to_xml;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
151  | 
|
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
152  | 
val output_pgmltext =  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
153  | 
XML.string_of_tree o Pgml.pgml_to_xml;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
154  | 
|
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
155  | 
|
| 21940 | 156  | 
fun issue_pgip_rawtext str =  | 
| 23723 | 157  | 
output_xml (PgipOutput.output (assemble_pgips [XML.Output str]))  | 
| 21637 | 158  | 
|
159  | 
fun issue_pgips pgipops =  | 
|
160  | 
output_xml (PgipOutput.output (assemble_pgips (map PgipOutput.output pgipops)));  | 
|
161  | 
||
162  | 
fun issue_pgip pgipop =  | 
|
163  | 
output_xml (PgipOutput.output (assemble_pgips [PgipOutput.output pgipop]));  | 
|
164  | 
||
165  | 
end;  | 
|
166  | 
||
167  | 
||
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
168  | 
fun pgml area terms = Pgml.Pgml { version=NONE,systemid=NONE,
 | 
| 23801 | 169  | 
area=SOME area, content=terms }  | 
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
170  | 
|
| 21637 | 171  | 
(** messages and notification **)  | 
172  | 
||
173  | 
local  | 
|
174  | 
val delay_msgs = ref false (*true: accumulate messages*)  | 
|
175  | 
val delayed_msgs = ref []  | 
|
176  | 
||
177  | 
fun queue_or_issue pgip =  | 
|
| 21940 | 178  | 
if ! delay_msgs then  | 
179  | 
delayed_msgs := pgip :: ! delayed_msgs  | 
|
180  | 
else issue_pgip pgip  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
181  | 
|
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
182  | 
fun wrap_pgml area s =  | 
| 23801 | 183  | 
if String.isPrefix "<pgml" s then  | 
184  | 
XML.Output s (* already pgml outermost *)  | 
|
185  | 
else  | 
|
186  | 
Pgml.pgml_to_xml (pgml area [Pgml.Raw (XML.Output s)]) (* mixed *)  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
187  | 
|
| 21637 | 188  | 
in  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
189  | 
fun normalmsg area s =  | 
| 21940 | 190  | 
let  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
191  | 
val content = wrap_pgml area s  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
192  | 
            val pgip = Normalresponse { content=[content] }
 | 
| 21940 | 193  | 
in  | 
194  | 
queue_or_issue pgip  | 
|
195  | 
end  | 
|
| 21637 | 196  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
197  | 
fun errormsg area fatality s =  | 
| 21940 | 198  | 
let  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
199  | 
val content = wrap_pgml area s  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
200  | 
            val pgip = Errorresponse { fatality=fatality,
 | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
201  | 
location=NONE,  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
202  | 
content=[content] }  | 
| 21940 | 203  | 
in  | 
204  | 
queue_or_issue pgip  | 
|
205  | 
end  | 
|
| 21637 | 206  | 
|
| 22159 | 207  | 
(* Error responses with useful locations *)  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
208  | 
fun error_with_pos area fatality pos s =  | 
| 22159 | 209  | 
let  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
210  | 
val content = wrap_pgml area s  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
211  | 
              val pgip = Errorresponse { fatality=fatality,
 | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
212  | 
location=SOME (PgipIsabelle.location_of_position pos),  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
213  | 
content=[content] }  | 
| 22159 | 214  | 
in  | 
215  | 
queue_or_issue pgip  | 
|
216  | 
end  | 
|
217  | 
||
| 21637 | 218  | 
fun start_delay_msgs () = (set delay_msgs; delayed_msgs := [])  | 
219  | 
fun end_delayed_msgs () = (reset delay_msgs; ! delayed_msgs)  | 
|
220  | 
end;  | 
|
221  | 
||
222  | 
(* NB: all of the standard error/message functions now expect already-escaped text.  | 
|
223  | 
FIXME: this may cause us problems now we're generating trees; on the other  | 
|
| 21940 | 224  | 
hand the output functions were tuned some time ago, so it ought to be  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
225  | 
enough to use XML.Output always above. *)  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
226  | 
(* NB 2: all of standard functions print strings terminated with new lines, but we don't  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
227  | 
add new lines explicitly in PGIP: they are left implicit. It means that PGIP messages  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
228  | 
can't be written without newlines. *)  | 
| 21637 | 229  | 
|
230  | 
fun setup_messages () =  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
231  | 
(Output.writeln_fn := (fn s => normalmsg Message s);  | 
| 23840 | 232  | 
Output.priority_fn := (fn s => normalmsg Status s);  | 
233  | 
Output.tracing_fn := (fn s => normalmsg Tracing s);  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
234  | 
Output.warning_fn := (fn s => errormsg Message Warning s);  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
235  | 
Output.error_fn := (fn s => errormsg Message Fatal s);  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
236  | 
Output.debug_fn := (fn s => errormsg Message Debug s));  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
237  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
238  | 
fun panic s = (errormsg Message Panic ("## SYSTEM EXIT ##\n" ^ s); exit 1);
 | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
239  | 
fun nonfatal_error s = errormsg Message Nonfatal s;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
240  | 
fun log_msg s = errormsg Message Log s;  | 
| 
21983
 
9fb029d1189b
Use Isar toplevel print_exn_fn for generating error responses instead of Output.error_msg.
 
aspinall 
parents: 
21972 
diff
changeset
 | 
241  | 
|
| 21637 | 242  | 
|
243  | 
(* immediate messages *)  | 
|
244  | 
||
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
245  | 
fun tell_clear_goals () =  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
246  | 
    issue_pgip (Normalresponse { content = [Pgml.pgml_to_xml (pgml Display [])] })
 | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
247  | 
fun tell_clear_response () =  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
248  | 
    issue_pgip (Normalresponse { content = [Pgml.pgml_to_xml (pgml Message [])] })
 | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
249  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
250  | 
fun tell_file_loaded completed path =  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
251  | 
    issue_pgip (Informfileloaded {url=PgipTypes.pgipurl_of_path path,
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
252  | 
completed=completed})  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
253  | 
fun tell_file_outdated completed path =  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
254  | 
    issue_pgip (Informfileoutdated {url=PgipTypes.pgipurl_of_path path,
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
255  | 
completed=completed})  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
256  | 
fun tell_file_retracted completed path =  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
257  | 
    issue_pgip (Informfileretracted {url=PgipTypes.pgipurl_of_path path,
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
258  | 
completed=completed})  | 
| 21637 | 259  | 
|
260  | 
||
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
261  | 
(* common markup *)  | 
| 21637 | 262  | 
|
263  | 
local  | 
|
264  | 
||
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
265  | 
val no_text = chr 0;  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
266  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
267  | 
val pgmlterms_no_text= [Pgml.Raw (XML.Output no_text)]  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
268  | 
|
| 
23641
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
269  | 
fun split_markup text =  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
270  | 
(case space_explode no_text text of  | 
| 
 
d6f9d3acffaa
toplevel prompt/print_state: proper markup, removed hooks;
 
wenzelm 
parents: 
23621 
diff
changeset
 | 
271  | 
[bg, en] => (bg, en)  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
272  | 
  | _ => (error ("Internal error: failed to split XML markup:\n" ^ text); ("", "")));
 | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
273  | 
|
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
274  | 
|
| 23801 | 275  | 
fun block_markup markup =  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
276  | 
let  | 
| 23801 | 277  | 
      val pgml = Pgml.Box { orient = NONE, 
 | 
278  | 
indent = Markup.get_int markup Markup.indentN,  | 
|
279  | 
content = pgmlterms_no_text }  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
280  | 
in split_markup (output_pgmlterm pgml) end;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
281  | 
|
| 23801 | 282  | 
fun break_markup markup =  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
283  | 
let  | 
| 23801 | 284  | 
      val pgml = Pgml.Break { mandatory = NONE,
 | 
285  | 
indent = Markup.get_int markup Markup.widthN }  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
286  | 
in (output_pgmlterm pgml, "") end;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
287  | 
|
| 23801 | 288  | 
fun fbreak_markup markup =  | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
289  | 
let  | 
| 23801 | 290  | 
      val pgml = Pgml.Break { mandatory = SOME true, indent = NONE }
 | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
291  | 
in (output_pgmlterm pgml, "") end;  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
292  | 
|
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
293  | 
val state_markup =  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
294  | 
split_markup (output_pgmltext (pgml PgipTypes.Display pgmlterms_no_text))  | 
| 21637 | 295  | 
|
| 23801 | 296  | 
fun proof_general_markup (markup as (name, _)) =  | 
297  | 
if name = Markup.blockN then block_markup markup  | 
|
298  | 
else if name = Markup.breakN then break_markup markup  | 
|
299  | 
else if name = Markup.fbreakN then fbreak_markup markup  | 
|
300  | 
(* else if name = Markup.classN then class_markup markup  | 
|
301  | 
else if name = Markup.tyconN then tycon_markup markup  | 
|
302  | 
else if name = Markup.constN then const_markup markup  | 
|
303  | 
else if name = Markup.axiomN then axiom_markup markup  | 
|
304  | 
else if name = Markup.sortN then sort_markup markup  | 
|
305  | 
else if name = Markup.typN then typ_markup markup  | 
|
306  | 
else if name = Markup.termN then term_markup markup  | 
|
307  | 
else if name = Markup.keywordN then keyword_markup markup  | 
|
308  | 
else if name = Markup.commandN then command_markup markup  | 
|
309  | 
else if name = Markup.promptN then prompt_markup markup *)  | 
|
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
310  | 
else if name = Markup.stateN then state_markup  | 
| 
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
311  | 
(* else if name = Markup.subgoalN then subgoal_markup () *)  | 
| 23801 | 312  | 
   else ("", "");
 | 
| 21637 | 313  | 
|
314  | 
in  | 
|
315  | 
||
| 23702 | 316  | 
val _ = Markup.add_mode proof_generalN proof_general_markup;  | 
| 21637 | 317  | 
|
318  | 
end;  | 
|
319  | 
||
320  | 
||
321  | 
(* theory loader actions *)  | 
|
322  | 
||
323  | 
local  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
324  | 
(* da: TODO: PGIP has a completed flag so the prover can indicate to the  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
325  | 
interface which files are busy performing a particular action.  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
326  | 
To make use of this we need to adjust the hook in thy_info.ML  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
327  | 
(may actually be difficult to tell the interface *which* action is in  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
328  | 
progress, but we could add a generic "Lock" action which uses  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
329  | 
informfileloaded: the broker/UI should not infer too much from incomplete  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
330  | 
operations).  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
331  | 
*)  | 
| 21637 | 332  | 
fun trace_action action name =  | 
333  | 
if action = ThyInfo.Update then  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
334  | 
List.app (tell_file_loaded true) (ThyInfo.loaded_files name)  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
335  | 
else if action = ThyInfo.Outdate then  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
336  | 
List.app (tell_file_outdated true) (ThyInfo.loaded_files name)  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
337  | 
else if action = ThyInfo.Remove then  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
338  | 
List.app (tell_file_retracted true) (ThyInfo.loaded_files name)  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
339  | 
else ()  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
340  | 
|
| 21637 | 341  | 
|
342  | 
in  | 
|
343  | 
fun setup_thy_loader () = ThyInfo.add_hook trace_action;  | 
|
344  | 
fun sync_thy_loader () = List.app (trace_action ThyInfo.Update) (ThyInfo.names ());  | 
|
345  | 
end;  | 
|
346  | 
||
347  | 
||
| 21949 | 348  | 
(* get informed about files *)  | 
| 21637 | 349  | 
|
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
350  | 
val thy_name = Path.implode o #1 o Path.split_ext o Path.base;  | 
| 21637 | 351  | 
|
352  | 
val inform_file_retracted = ThyInfo.if_known_thy ThyInfo.remove_thy o thy_name;  | 
|
353  | 
val inform_file_processed = ThyInfo.if_known_thy ThyInfo.touch_child_thys o thy_name;  | 
|
354  | 
||
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
355  | 
fun proper_inform_file_processed path state =  | 
| 
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
356  | 
let val name = thy_name path in  | 
| 21637 | 357  | 
if Toplevel.is_toplevel state andalso ThyInfo.known_thy name then  | 
358  | 
(ThyInfo.touch_child_thys name;  | 
|
| 24079 | 359  | 
ThyInfo.register_thy name handle ERROR msg =>  | 
| 23913 | 360  | 
(warning (cat_lines [msg, "Failed to register theory: " ^ quote name]);  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
361  | 
tell_file_retracted true (Path.base path)))  | 
| 21637 | 362  | 
else raise Toplevel.UNDEF  | 
363  | 
end;  | 
|
364  | 
||
365  | 
||
366  | 
(* restart top-level loop (keeps most state information) *)  | 
|
367  | 
||
368  | 
val welcome = priority o Session.welcome;  | 
|
369  | 
||
370  | 
fun restart () =  | 
|
371  | 
(sync_thy_loader ();  | 
|
372  | 
tell_clear_goals ();  | 
|
373  | 
tell_clear_response ();  | 
|
374  | 
welcome ();  | 
|
375  | 
raise Toplevel.RESTART)  | 
|
376  | 
||
377  | 
||
378  | 
(* theorem dependency output *)  | 
|
| 22408 | 379  | 
|
380  | 
val show_theorem_dependencies = ref false;  | 
|
381  | 
||
| 21637 | 382  | 
local  | 
383  | 
||
384  | 
val spaces_quote = space_implode " " o map quote;  | 
|
385  | 
||
386  | 
fun thm_deps_message (thms, deps) =  | 
|
| 21940 | 387  | 
let  | 
388  | 
        val valuethms = XML.Elem("value",[("name", "thms")],[XML.Text thms])
 | 
|
389  | 
        val valuedeps = XML.Elem("value",[("name", "deps")],[XML.Text deps])
 | 
|
| 21637 | 390  | 
in  | 
| 21940 | 391  | 
        issue_pgip (Metainforesponse {attrs=[("infotype", "isabelle_theorem_dependencies")],
 | 
392  | 
content=[valuethms,valuedeps]})  | 
|
| 21637 | 393  | 
end  | 
394  | 
||
| 21969 | 395  | 
fun tell_thm_deps ths =  | 
| 22408 | 396  | 
if !show_theorem_dependencies then  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
397  | 
let  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
398  | 
val names = map PureThy.get_name_hint (filter PureThy.has_name_hint ths);  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
399  | 
val deps = (Symtab.keys (fold Proofterm.thms_of_proof'  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
400  | 
(map Thm.proof_of ths) Symtab.empty))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
401  | 
in  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
402  | 
if null names orelse null deps then ()  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
403  | 
else thm_deps_message (spaces_quote names, spaces_quote deps)  | 
| 22225 | 404  | 
end  | 
405  | 
else ()  | 
|
| 21637 | 406  | 
|
407  | 
in  | 
|
408  | 
||
409  | 
fun setup_present_hook () =  | 
|
410  | 
Present.add_hook (fn _ => fn res => tell_thm_deps (maps #2 res));  | 
|
411  | 
||
412  | 
end;  | 
|
413  | 
||
414  | 
(** lexicalstructure element with keywords (PGIP version of elisp keywords file) **)  | 
|
415  | 
||
| 21940 | 416  | 
fun lexicalstructure_keywords () =  | 
| 21637 | 417  | 
let val commands = OuterSyntax.dest_keywords ()  | 
| 21940 | 418  | 
fun category_of k = if k mem commands then "major" else "minor"  | 
| 21637 | 419  | 
(* NB: we might filter to only include words like elisp case (OuterSyntax.is_keyword). *)  | 
| 21940 | 420  | 
fun keyword_elt (keyword,help,kind,_) =  | 
421  | 
            XML.Elem("keyword", [("word", keyword), ("category", category_of kind)],
 | 
|
422  | 
                     [XML.Elem("shorthelp", [], [XML.Text help])])
 | 
|
423  | 
in  | 
|
| 21637 | 424  | 
(* Also, note we don't call init_outer_syntax here to add interface commands,  | 
425  | 
but they should never appear in scripts anyway so it shouldn't matter *)  | 
|
426  | 
            Lexicalstructure {content = map keyword_elt (OuterSyntax.dest_parsers()) }
 | 
|
427  | 
end  | 
|
428  | 
||
429  | 
(* TODO: we can issue a lexicalstructure/keyword when the syntax gets extended dynamically;  | 
|
430  | 
hooks needed in outer_syntax.ML to do that. *)  | 
|
431  | 
||
432  | 
||
433  | 
(* Configuration: GUI config, proverinfo messages *)  | 
|
434  | 
||
435  | 
local  | 
|
436  | 
val isabellewww = "http://isabelle.in.tum.de/"  | 
|
437  | 
val staticconfig = "~~/lib/ProofGeneral/pgip_isar.xml"  | 
|
| 21940 | 438  | 
fun orenv v d = case getenv v of "" => d | s => s  | 
| 21637 | 439  | 
fun config_file() = orenv "ISABELLE_PGIPCONFIG" staticconfig  | 
440  | 
fun isabelle_www() = orenv "ISABELLE_HOMEPAGE" isabellewww  | 
|
441  | 
in  | 
|
442  | 
fun send_pgip_config () =  | 
|
443  | 
let  | 
|
| 
21858
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
21655 
diff
changeset
 | 
444  | 
val path = Path.explode (config_file())  | 
| 21940 | 445  | 
val ex = File.exists path  | 
| 21637 | 446  | 
|
| 21940 | 447  | 
val wwwpage =  | 
448  | 
(Url.explode (isabelle_www()))  | 
|
| 21969 | 449  | 
handle ERROR _ =>  | 
| 
22699
 
938c1011ac94
removed unused Output.panic hook -- internal to PG wrapper;
 
wenzelm 
parents: 
22678 
diff
changeset
 | 
450  | 
                   (panic ("Error in URL in environment variable ISABELLE_HOMEPAGE.");
 | 
| 21940 | 451  | 
Url.explode isabellewww)  | 
452  | 
||
453  | 
val proverinfo =  | 
|
| 21637 | 454  | 
            Proverinfo { name = "Isabelle",
 | 
| 21940 | 455  | 
version = version,  | 
456  | 
instance = Session.name(),  | 
|
457  | 
descr = "The Isabelle/Isar theorem prover",  | 
|
458  | 
url = wwwpage,  | 
|
459  | 
filenameextns = ".thy;" }  | 
|
| 21637 | 460  | 
in  | 
| 21940 | 461  | 
if ex then  | 
462  | 
(issue_pgip proverinfo;  | 
|
463  | 
issue_pgip_rawtext (File.read path);  | 
|
464  | 
issue_pgip (lexicalstructure_keywords()))  | 
|
| 
22699
 
938c1011ac94
removed unused Output.panic hook -- internal to PG wrapper;
 
wenzelm 
parents: 
22678 
diff
changeset
 | 
465  | 
        else panic ("PGIP configuration file \"" ^ config_file() ^ "\" not found")
 | 
| 21637 | 466  | 
end;  | 
467  | 
end  | 
|
468  | 
||
469  | 
||
| 
22216
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
470  | 
(* Preferences: tweak for PGIP interfaces *)  | 
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
471  | 
|
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
472  | 
val preferences = ref Preferences.preferences;  | 
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
473  | 
|
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
474  | 
fun setup_preferences_tweak() =  | 
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
475  | 
preferences :=  | 
| 
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
476  | 
     (!preferences |> Preferences.set_default ("show-question-marks","false")
 | 
| 22408 | 477  | 
|> Preferences.remove "show-question-marks" (* we use markup, not ?s *)  | 
| 22590 | 478  | 
|> Preferences.remove "theorem-dependencies" (* set internally *)  | 
479  | 
|> Preferences.remove "full-proofs") (* set internally *)  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
480  | 
|
| 21637 | 481  | 
|
482  | 
||
483  | 
(* Sending commands to Isar *)  | 
|
484  | 
||
485  | 
fun isarcmd s =  | 
|
486  | 
s |> OuterSyntax.scan |> OuterSyntax.read  | 
|
| 23681 | 487  | 
(*|> map (Toplevel.position Position.none o #3)*)  | 
| 
21885
 
5a11263bd8cf
Remove obsolete prefixes from error and warning messages.
 
aspinall 
parents: 
21867 
diff
changeset
 | 
488  | 
|> map #3  | 
| 
 
5a11263bd8cf
Remove obsolete prefixes from error and warning messages.
 
aspinall 
parents: 
21867 
diff
changeset
 | 
489  | 
|> Toplevel.>>>;  | 
| 21637 | 490  | 
|
| 21940 | 491  | 
(* TODO:  | 
| 
21885
 
5a11263bd8cf
Remove obsolete prefixes from error and warning messages.
 
aspinall 
parents: 
21867 
diff
changeset
 | 
492  | 
- apply a command given a transition function, e.g. IsarCmd.undo.  | 
| 
 
5a11263bd8cf
Remove obsolete prefixes from error and warning messages.
 
aspinall 
parents: 
21867 
diff
changeset
 | 
493  | 
- fix position from path of currently open file [line numbers risk garbling though].  | 
| 
 
5a11263bd8cf
Remove obsolete prefixes from error and warning messages.
 
aspinall 
parents: 
21867 
diff
changeset
 | 
494  | 
*)  | 
| 21637 | 495  | 
|
496  | 
(* load an arbitrary file (must be .thy or .ML) *)  | 
|
497  | 
||
498  | 
fun use_thy_or_ml_file file =  | 
|
499  | 
let  | 
|
| 
21858
 
05f57309170c
avoid conflict with Alice keywords: renamed pack -> implode, unpack -> explode, any -> many, avoided assert;
 
wenzelm 
parents: 
21655 
diff
changeset
 | 
500  | 
val (path,extn) = Path.split_ext (Path.explode file)  | 
| 21637 | 501  | 
in  | 
502  | 
case extn of  | 
|
| 21940 | 503  | 
            "" => isarcmd ("use_thy " ^ quote (Path.implode path))
 | 
504  | 
          | "thy" => isarcmd ("use_thy " ^ quote (Path.implode path))
 | 
|
| 21637 | 505  | 
          | "ML" => isarcmd ("use " ^ quote file)
 | 
| 22028 | 506  | 
          | other => error ("Don't know how to read a file with extension " ^ quote other)
 | 
| 21637 | 507  | 
end  | 
508  | 
||
509  | 
||
| 21867 | 510  | 
(******* PGIP actions *******)  | 
| 21637 | 511  | 
|
512  | 
||
| 21940 | 513  | 
(* Responses to each of the PGIP input commands.  | 
| 21637 | 514  | 
These are programmed uniformly for extensibility. *)  | 
515  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
516  | 
fun askpgip (Askpgip _) =  | 
| 
23435
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
517  | 
(issue_pgip  | 
| 
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
518  | 
         (Usespgip { version = PgipIsabelle.isabelle_pgip_version_supported,
 | 
| 
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
519  | 
pgipelems = PgipIsabelle.accepted_inputs });  | 
| 
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
520  | 
send_pgip_config())  | 
| 21637 | 521  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
522  | 
fun askpgml (Askpgml _) =  | 
| 21637 | 523  | 
issue_pgip  | 
| 21940 | 524  | 
        (Usespgml { version = PgipIsabelle.isabelle_pgml_version_supported })
 | 
| 21637 | 525  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
526  | 
fun askprefs (Askprefs _) =  | 
| 21940 | 527  | 
let  | 
528  | 
        fun preference_of {name, descr, default, pgiptype, get, set } =
 | 
|
529  | 
            { name = name, descr = SOME descr, default = SOME default,
 | 
|
530  | 
pgiptype = pgiptype }  | 
|
| 21637 | 531  | 
in  | 
| 21940 | 532  | 
List.app (fn (prefcat, prefs) =>  | 
533  | 
                     issue_pgip (Hasprefs {prefcategory=SOME prefcat,
 | 
|
534  | 
prefs=map preference_of prefs}))  | 
|
| 
22216
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
535  | 
(!preferences)  | 
| 21940 | 536  | 
end  | 
| 21637 | 537  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
538  | 
fun askconfig (Askconfig _) = () (* TODO: add config response *)  | 
| 21637 | 539  | 
|
540  | 
local  | 
|
| 21940 | 541  | 
fun lookuppref pref =  | 
542  | 
case AList.lookup (op =)  | 
|
543  | 
(map (fn p => (#name p,p))  | 
|
| 
22216
 
c3f5aa951a68
Tweak preferences for PGIP interfaces. Make <askids> return theory successors instead of parents (ideally should be content elements).
 
aspinall 
parents: 
22171 
diff
changeset
 | 
544  | 
(maps snd (!preferences))) pref of  | 
| 21940 | 545  | 
            NONE => error ("Unknown prover preference: " ^ quote pref)
 | 
546  | 
| SOME p => p  | 
|
| 21637 | 547  | 
in  | 
| 21940 | 548  | 
fun setpref (Setpref vs) =  | 
549  | 
let  | 
|
550  | 
val name = #name vs  | 
|
551  | 
val value = #value vs  | 
|
552  | 
val set = #set (lookuppref name)  | 
|
| 21637 | 553  | 
in  | 
| 21940 | 554  | 
set value  | 
| 21637 | 555  | 
end  | 
556  | 
||
| 21902 | 557  | 
fun getpref (Getpref vs) =  | 
| 21940 | 558  | 
let  | 
559  | 
val name = #name vs  | 
|
560  | 
val get = #get (lookuppref name)  | 
|
561  | 
in  | 
|
| 21637 | 562  | 
        issue_pgip (Prefval {name=name, value=get ()})
 | 
563  | 
end  | 
|
564  | 
end  | 
|
565  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
566  | 
fun proverinit _ = restart ()  | 
| 21637 | 567  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
568  | 
fun proverexit _ = isarcmd "quit"  | 
| 21637 | 569  | 
|
| 22408 | 570  | 
fun set_proverflag_quiet b =  | 
571  | 
isarcmd (if b then "disable_pr" else "enable_pr")  | 
|
| 21637 | 572  | 
|
| 22408 | 573  | 
fun set_proverflag_pgmlsymbols b =  | 
574  | 
(pgmlsymbols_flag := b;  | 
|
| 24614 | 575  | 
NAMED_CRITICAL "print_mode" (fn () =>  | 
576  | 
change print_mode  | 
|
| 22590 | 577  | 
(fn mode =>  | 
| 24614 | 578  | 
remove (op =) Symbol.xsymbolsN mode @ (if b then [Symbol.xsymbolsN] else []))))  | 
| 22408 | 579  | 
|
580  | 
fun set_proverflag_thmdeps b =  | 
|
581  | 
(show_theorem_dependencies := b;  | 
|
| 25223 | 582  | 
Proofterm.proofs := (if b then 1 else 2))  | 
| 21637 | 583  | 
|
| 22408 | 584  | 
fun setproverflag (Setproverflag vs) =  | 
585  | 
let  | 
|
| 22590 | 586  | 
val flagname = #flagname vs  | 
587  | 
val value = #value vs  | 
|
| 22408 | 588  | 
in  | 
| 22590 | 589  | 
(case flagname of  | 
590  | 
"quiet" => set_proverflag_quiet value  | 
|
591  | 
| "pgmlsymbols" => set_proverflag_pgmlsymbols value  | 
|
592  | 
| "metainfo:thmdeps" => set_proverflag_thmdeps value  | 
|
| 
23435
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
593  | 
           | _ => log_msg ("Unrecognised prover control flag: " ^ 
 | 
| 23801 | 594  | 
(quote flagname) ^ " ignored."))  | 
| 22408 | 595  | 
end  | 
596  | 
||
| 21637 | 597  | 
|
| 21940 | 598  | 
fun dostep (Dostep vs) =  | 
599  | 
let  | 
|
600  | 
val text = #text vs  | 
|
601  | 
in  | 
|
602  | 
isarcmd text  | 
|
| 21637 | 603  | 
end  | 
604  | 
||
| 21902 | 605  | 
fun undostep (Undostep vs) =  | 
| 21940 | 606  | 
let  | 
607  | 
val times = #times vs  | 
|
608  | 
in  | 
|
609  | 
        isarcmd ("undos_proof " ^ Int.toString times)
 | 
|
| 21637 | 610  | 
end  | 
611  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
612  | 
fun redostep _ = isarcmd "redo"  | 
| 21940 | 613  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
614  | 
fun abortgoal _ = isarcmd "kill" (* was: ProofGeneral.kill_proof *)  | 
| 21637 | 615  | 
|
616  | 
||
| 21867 | 617  | 
(*** PGIP identifier tables ***)  | 
618  | 
||
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
619  | 
(* TODO: these ones should be triggered by hooks after a  | 
| 22159 | 620  | 
declaration addition/removal, to be sent automatically. *)  | 
| 21867 | 621  | 
|
| 22159 | 622  | 
fun addids t  = issue_pgip (Addids {idtables = [t]})
 | 
623  | 
fun delids t  = issue_pgip (Delids {idtables = [t]})
 | 
|
| 21867 | 624  | 
|
| 21940 | 625  | 
fun askids (Askids vs) =  | 
| 21637 | 626  | 
let  | 
| 21940 | 627  | 
val url = #url vs (* ask for identifiers within a file *)  | 
628  | 
val thyname = #thyname vs (* ask for identifiers within a theory *)  | 
|
629  | 
val objtype = #objtype vs (* ask for identifiers of a particular type *)  | 
|
| 21867 | 630  | 
|
| 21940 | 631  | 
        fun idtable ty ctx ids = {objtype=ty,context=ctx,ids=ids}
 | 
| 21867 | 632  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
633  | 
        fun setids t = issue_pgip (Setids {idtables = [t]})
 | 
| 22159 | 634  | 
|
| 22225 | 635  | 
(* fake one-level nested "subtheories" by picking apart names. *)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
636  | 
val thms_of_thy =  | 
| 
22243
 
0f24888c8591
proper use of NameSpace.is_qualified (avoids compatibility issues of the SML B library);
 
wenzelm 
parents: 
22228 
diff
changeset
 | 
637  | 
map fst o NameSpace.extern_table o PureThy.theorems_of o ThyInfo.get_theory  | 
| 
 
0f24888c8591
proper use of NameSpace.is_qualified (avoids compatibility issues of the SML B library);
 
wenzelm 
parents: 
22228 
diff
changeset
 | 
638  | 
val immed_thms_of_thy = filter_out NameSpace.is_qualified o thms_of_thy  | 
| 22225 | 639  | 
fun thy_prefix s = case space_explode NameSpace.separator s of  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
640  | 
x::_::_ => SOME x (* String.find? *)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
641  | 
| _ => NONE  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
642  | 
fun subthys_of_thy s =  | 
| 23178 | 643  | 
List.foldl (fn (NONE,xs) => xs | (SOME x,xs) => insert op= x xs) []  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
644  | 
(map thy_prefix (thms_of_thy s))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
645  | 
fun subthms_of_thy thy =  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
646  | 
(case thy_prefix thy of  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
647  | 
NONE => immed_thms_of_thy thy  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
648  | 
| SOME prf => filter (String.isPrefix (unprefix (prf ^ NameSpace.separator) thy))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
649  | 
(thms_of_thy prf))  | 
| 22225 | 650  | 
val qualified_thms_of_thy = (* for global query with single response *)  | 
| 22590 | 651  | 
(map fst) o NameSpace.dest_table o PureThy.theorems_of o ThyInfo.get_theory;  | 
| 
22249
 
5460a5e4caa2
askids/qualified_thms_of_thy: version which returns names in domain of get_thm
 
aspinall 
parents: 
22243 
diff
changeset
 | 
652  | 
(* da: this version is equivalent to my previous, but splits up theorem sets with names  | 
| 
 
5460a5e4caa2
askids/qualified_thms_of_thy: version which returns names in domain of get_thm
 
aspinall 
parents: 
22243 
diff
changeset
 | 
653  | 
that I can't get to access later with get_thm. Anyway, would rather use sets.  | 
| 
 
5460a5e4caa2
askids/qualified_thms_of_thy: version which returns names in domain of get_thm
 
aspinall 
parents: 
22243 
diff
changeset
 | 
654  | 
Is above right way to get qualified names in that case? Filtering required again?  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
655  | 
map PureThy.get_name_hint o filter PureThy.has_name_hint o  | 
| 
22249
 
5460a5e4caa2
askids/qualified_thms_of_thy: version which returns names in domain of get_thm
 
aspinall 
parents: 
22243 
diff
changeset
 | 
656  | 
map snd o PureThy.thms_of o ThyInfo.get_theory; *)  | 
| 
 
5460a5e4caa2
askids/qualified_thms_of_thy: version which returns names in domain of get_thm
 
aspinall 
parents: 
22243 
diff
changeset
 | 
657  | 
in  | 
| 21940 | 658  | 
case (thyname,objtype) of  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
659  | 
(NONE, NONE) =>  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
660  | 
setids (idtable ObjFile NONE (ThyInfo.names())) (*FIXME: uris*)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
661  | 
| (NONE, SOME ObjFile) =>  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
662  | 
setids (idtable ObjFile NONE (ThyInfo.names())) (*FIXME: uris*)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
663  | 
| (SOME fi, SOME ObjFile) =>  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
664  | 
setids (idtable ObjTheory (SOME fi) [fi]) (* TODO: check exists *)  | 
| 22225 | 665  | 
| (NONE, SOME ObjTheory) =>  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
666  | 
setids (idtable ObjTheory NONE (ThyInfo.names()))  | 
| 22225 | 667  | 
| (SOME thy, SOME ObjTheory) =>  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
668  | 
setids (idtable ObjTheory (SOME thy) (subthys_of_thy thy))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
669  | 
| (SOME thy, SOME ObjTheorem) =>  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
670  | 
setids (idtable ObjTheorem (SOME thy) (subthms_of_thy thy))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
671  | 
| (NONE, SOME ObjTheorem) =>  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
672  | 
(* A large query, but not unreasonable. ~5000 results for HOL.*)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
673  | 
(* Several setids should be allowed, but Eclipse code is currently broken:  | 
| 23226 | 674  | 
List.app (fn thy => setids (idtable ObjTheorem (SOME thy) (subthms_of_thy thy)))  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
675  | 
(ThyInfo.names()) *)  | 
| 22225 | 676  | 
setids (idtable ObjTheorem NONE (* this one gives ~7000 for HOL *)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
677  | 
(maps qualified_thms_of_thy (ThyInfo.names())))  | 
| 22225 | 678  | 
         | _ => warning ("askids: ignored argument combination")
 | 
| 21637 | 679  | 
end  | 
680  | 
||
| 22159 | 681  | 
fun askrefs (Askrefs vs) =  | 
682  | 
let  | 
|
683  | 
val url = #url vs (* ask for references of a file (i.e. immediate pre-requisites) *)  | 
|
684  | 
val thyname = #thyname vs (* ask for references of a theory (other theories) *)  | 
|
685  | 
val objtype = #objtype vs (* ask for references of a particular type... *)  | 
|
686  | 
val name = #name vs (* ... with this name *)  | 
|
687  | 
||
688  | 
        fun idtable ty ctx ids = {objtype=ty,context=ctx,ids=ids}
 | 
|
689  | 
||
690  | 
val thms_of_thy = map fst o PureThy.thms_of o ThyInfo.get_theory  | 
|
691  | 
||
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
692  | 
val thy_name = Path.implode o #1 o Path.split_ext o Path.base  | 
| 22159 | 693  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
694  | 
fun filerefs f =  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
695  | 
let val thy = thy_name f  | 
| 
24189
 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 
wenzelm 
parents: 
24079 
diff
changeset
 | 
696  | 
val filerefs = #uses (ThyLoad.deps_thy (Path.dir f) thy)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
697  | 
in  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
698  | 
                issue_pgip (Setrefs {url=url, thyname=NONE, objtype=SOME PgipTypes.ObjFile,
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
699  | 
name=NONE, idtables=[], fileurls=filerefs})  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
700  | 
end  | 
| 22159 | 701  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
702  | 
fun thyrefs thy =  | 
| 
24189
 
1fa9852643a3
simplified ThyLoad.deps_thy etc.: discontinued attached ML files;
 
wenzelm 
parents: 
24079 
diff
changeset
 | 
703  | 
let val thyrefs = #imports (ThyLoad.deps_thy Path.current thy)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
704  | 
in  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
705  | 
                issue_pgip (Setrefs {url=url, thyname=thyname, objtype=SOME PgipTypes.ObjTheory,
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
706  | 
                                     name=NONE, idtables=[{context=NONE, objtype=PgipTypes.ObjTheory,
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
707  | 
ids=thyrefs}], fileurls=[]})  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
708  | 
end  | 
| 22159 | 709  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
710  | 
fun thmrefs thmname =  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
711  | 
let  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
712  | 
(* TODO: interim: this is probably not right.  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
713  | 
What we want is mapping onto simple PGIP name/context model. *)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
714  | 
val ctx = Toplevel.context_of (Toplevel.get_state()) (* NB: raises UNDEF *)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
715  | 
val thy = Context.theory_of_proof ctx  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
716  | 
val ths = [PureThy.get_thm thy (PureThy.Name thmname)]  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
717  | 
val deps = filter_out (equal "")  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
718  | 
(Symtab.keys (fold Proofterm.thms_of_proof  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
719  | 
(map Thm.proof_of ths) Symtab.empty))  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
720  | 
in  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
721  | 
if null deps then ()  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
722  | 
                else issue_pgip (Setrefs {url=url, thyname=thyname, name=name,
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
723  | 
objtype=SOME PgipTypes.ObjTheorem,  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
724  | 
                                          idtables=[{context=NONE, objtype=PgipTypes.ObjTheorem,
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
725  | 
ids=deps}], fileurls=[]})  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
726  | 
end  | 
| 22159 | 727  | 
in  | 
728  | 
case (url,thyname,objtype,name) of  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
729  | 
(SOME file, NONE, _, _) => filerefs file  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
730  | 
| (_,SOME thy,_,_) => thyrefs thy  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
731  | 
| (_,_,SOME PgipTypes.ObjTheorem,SOME thmname) => thmrefs thmname  | 
| 22159 | 732  | 
          | _  => error ("Unimplemented/invalid case of <askrefs>")
 | 
733  | 
end  | 
|
734  | 
||
735  | 
||
736  | 
||
| 21940 | 737  | 
fun showid (Showid vs) =  | 
| 21637 | 738  | 
let  | 
| 21940 | 739  | 
val thyname = #thyname vs  | 
740  | 
val objtype = #objtype vs  | 
|
741  | 
val name = #name vs  | 
|
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
742  | 
|
| 21940 | 743  | 
val topthy = Toplevel.theory_of o Toplevel.get_state  | 
| 21637 | 744  | 
|
| 22590 | 745  | 
fun splitthy id =  | 
746  | 
let val comps = NameSpace.explode id  | 
|
747  | 
in case comps of  | 
|
748  | 
(thy::(rest as _::_)) => (ThyInfo.get_theory thy, space_implode "." rest)  | 
|
749  | 
| [plainid] => (topthy(),plainid)  | 
|
750  | 
| _ => raise Toplevel.UNDEF (* assert false *)  | 
|
751  | 
end  | 
|
752  | 
||
| 21637 | 753  | 
|
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
754  | 
fun idvalue strings =  | 
| 
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
755  | 
            issue_pgip (Idvalue { thyname=thyname, objtype=objtype, name=name, 
 | 
| 
23759
 
90bccef65004
Fix nested PGIP messages.  Update for schema simplifications.
 
aspinall 
parents: 
23723 
diff
changeset
 | 
756  | 
                                  text=[XML.Elem("pgml",[],
 | 
| 23723 | 757  | 
map XML.Output strings)] })  | 
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
758  | 
|
| 22590 | 759  | 
fun string_of_thm th = Output.output  | 
760  | 
(Pretty.string_of  | 
|
761  | 
(Display.pretty_thm_aux  | 
|
762  | 
(Sign.pp (Thm.theory_of_thm th))  | 
|
763  | 
false (* quote *)  | 
|
764  | 
false (* show hyps *)  | 
|
765  | 
[] (* asms *)  | 
|
766  | 
th))  | 
|
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
767  | 
|
| 
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
768  | 
fun strings_of_thm (thy, name) = map string_of_thm (get_thms thy (Name name))  | 
| 
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
769  | 
|
| 22590 | 770  | 
val string_of_thy = Output.output o  | 
771  | 
Pretty.string_of o (ProofDisplay.pretty_full_theory false)  | 
|
| 21940 | 772  | 
in  | 
773  | 
case (thyname, objtype) of  | 
|
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
774  | 
(_,ObjTheory) => idvalue [string_of_thy (ThyInfo.get_theory name)]  | 
| 
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
775  | 
| (SOME thy, ObjTheorem) => idvalue (strings_of_thm (ThyInfo.get_theory thy, name))  | 
| 
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
776  | 
| (NONE, ObjTheorem) => idvalue (strings_of_thm (splitthy name))  | 
| 21940 | 777  | 
          | (_, ot) => error ("Cannot show objects of type "^(PgipTypes.name_of_objtype ot))
 | 
| 21637 | 778  | 
end  | 
779  | 
||
| 21867 | 780  | 
(*** Inspecting state ***)  | 
781  | 
||
| 21940 | 782  | 
(* The file which is currently being processed interactively.  | 
| 21637 | 783  | 
In the pre-PGIP code, this was informed to Isabelle and the theory loader  | 
784  | 
on completion, but that allows for circularity in case we read  | 
|
785  | 
ourselves. So PGIP opens the filename at the start of a script.  | 
|
786  | 
We ought to prevent problems by modifying the theory loader to know  | 
|
| 21940 | 787  | 
about this special status, but for now we just keep a local reference.  | 
788  | 
*)  | 
|
| 21637 | 789  | 
|
790  | 
val currently_open_file = ref (NONE : pgipurl option)  | 
|
791  | 
||
| 22163 | 792  | 
fun get_currently_open_file () = ! currently_open_file;  | 
793  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
794  | 
fun askguise _ =  | 
| 21637 | 795  | 
(* The "guise" is the PGIP abstraction of the prover's state.  | 
796  | 
The <informguise> message is merely used for consistency checking. *)  | 
|
| 21940 | 797  | 
let  | 
798  | 
val openfile = !currently_open_file  | 
|
| 21637 | 799  | 
|
| 21940 | 800  | 
val topthy = Toplevel.theory_of o Toplevel.get_state  | 
801  | 
val topthy_name = Context.theory_name o topthy  | 
|
| 21637 | 802  | 
|
| 21940 | 803  | 
val opentheory = SOME (topthy_name()) handle Toplevel.UNDEF => NONE  | 
| 21637 | 804  | 
|
| 21940 | 805  | 
fun topproofpos () = try Toplevel.proof_position_of (Isar.state ());  | 
806  | 
val openproofpos = topproofpos()  | 
|
| 21637 | 807  | 
in  | 
808  | 
        issue_pgip (Informguise { file = openfile,
 | 
|
| 21940 | 809  | 
theory = opentheory,  | 
810  | 
(* would be nice to get thm name... *)  | 
|
811  | 
theorem = NONE,  | 
|
812  | 
proofpos = openproofpos })  | 
|
| 21637 | 813  | 
end  | 
814  | 
||
| 21902 | 815  | 
fun parsescript (Parsescript vs) =  | 
| 21637 | 816  | 
let  | 
| 21940 | 817  | 
val text = #text vs  | 
818  | 
val systemdata = #systemdata vs  | 
|
819  | 
val location = #location vs (* TODO: extract position *)  | 
|
| 21637 | 820  | 
|
| 21867 | 821  | 
val _ = start_delay_msgs () (* gather parsing errs/warns *)  | 
| 25274 | 822  | 
val doc = PgipParser.pgip_parser Position.none text  | 
| 21637 | 823  | 
val errs = end_delayed_msgs ()  | 
824  | 
||
| 21940 | 825  | 
val sysattrs = PgipTypes.opt_attr "systemdata" systemdata  | 
826  | 
val locattrs = PgipTypes.attrs_of_location location  | 
|
| 21637 | 827  | 
in  | 
828  | 
        issue_pgip (Parseresult { attrs= sysattrs@locattrs,
 | 
|
| 21940 | 829  | 
doc = doc,  | 
830  | 
errs = map PgipOutput.output errs })  | 
|
| 21637 | 831  | 
end  | 
832  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
833  | 
fun showproofstate _ = isarcmd "pr"  | 
| 21637 | 834  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
835  | 
fun showctxt _ = isarcmd "print_context"  | 
| 21637 | 836  | 
|
| 21902 | 837  | 
fun searchtheorems (Searchtheorems vs) =  | 
| 21940 | 838  | 
let  | 
839  | 
val arg = #arg vs  | 
|
| 21637 | 840  | 
in  | 
| 21969 | 841  | 
        isarcmd ("find_theorems " ^ arg)
 | 
| 21637 | 842  | 
end  | 
843  | 
||
| 21940 | 844  | 
fun setlinewidth (Setlinewidth vs) =  | 
845  | 
let  | 
|
846  | 
val width = #width vs  | 
|
| 21637 | 847  | 
in  | 
| 21940 | 848  | 
        isarcmd ("pretty_setmargin " ^ Int.toString width) (* FIXME: conversion back/forth! *)
 | 
| 21637 | 849  | 
end  | 
850  | 
||
| 21902 | 851  | 
fun viewdoc (Viewdoc vs) =  | 
| 21940 | 852  | 
let  | 
853  | 
val arg = #arg vs  | 
|
854  | 
in  | 
|
855  | 
        isarcmd ("print_" ^ arg)   (* FIXME: isatool doc?.  Return URLs, maybe? *)
 | 
|
| 21637 | 856  | 
end  | 
857  | 
||
| 21867 | 858  | 
(*** Theory ***)  | 
859  | 
||
| 21902 | 860  | 
fun doitem (Doitem vs) =  | 
| 21637 | 861  | 
let  | 
| 21940 | 862  | 
val text = #text vs  | 
| 21637 | 863  | 
in  | 
| 21940 | 864  | 
isarcmd text  | 
| 21637 | 865  | 
end  | 
866  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
867  | 
fun undoitem _ =  | 
| 
21972
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
868  | 
isarcmd "undo"  | 
| 21637 | 869  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
870  | 
fun redoitem _ =  | 
| 
21972
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
871  | 
isarcmd "redo"  | 
| 21637 | 872  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
873  | 
fun aborttheory _ =  | 
| 
21972
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
874  | 
isarcmd "kill" (* was: "init_toplevel" *)  | 
| 21637 | 875  | 
|
| 21902 | 876  | 
fun retracttheory (Retracttheory vs) =  | 
| 21940 | 877  | 
let  | 
878  | 
val thyname = #thyname vs  | 
|
| 21637 | 879  | 
in  | 
| 21940 | 880  | 
        isarcmd ("kill_thy " ^ quote thyname)
 | 
| 21637 | 881  | 
end  | 
882  | 
||
| 21867 | 883  | 
|
884  | 
(*** Files ***)  | 
|
885  | 
||
886  | 
(* Path management: we allow theory files to have dependencies in  | 
|
887  | 
their own directory, but when we change directory for a new file we  | 
|
888  | 
remove the path. Leaving it there can cause confusion with  | 
|
889  | 
difference in batch mode.  | 
|
| 21940 | 890  | 
NB: PGIP does not assume that the prover has a load path.  | 
| 21867 | 891  | 
*)  | 
892  | 
||
893  | 
local  | 
|
894  | 
val current_working_dir = ref (NONE : string option)  | 
|
895  | 
in  | 
|
| 21940 | 896  | 
fun changecwd_dir newdirpath =  | 
897  | 
let  | 
|
| 21867 | 898  | 
val newdir = File.platform_path newdirpath  | 
| 21940 | 899  | 
in  | 
| 21867 | 900  | 
(case (!current_working_dir) of  | 
901  | 
NONE => ()  | 
|
902  | 
| SOME dir => ThyLoad.del_path dir;  | 
|
903  | 
ThyLoad.add_path newdir;  | 
|
904  | 
current_working_dir := SOME newdir)  | 
|
905  | 
end  | 
|
906  | 
end  | 
|
907  | 
||
| 21940 | 908  | 
fun changecwd (Changecwd vs) =  | 
909  | 
let  | 
|
910  | 
val url = #url vs  | 
|
911  | 
val newdir = PgipTypes.path_of_pgipurl url  | 
|
| 21867 | 912  | 
in  | 
| 21940 | 913  | 
changecwd_dir url  | 
| 21867 | 914  | 
end  | 
915  | 
||
| 21902 | 916  | 
fun openfile (Openfile vs) =  | 
| 21940 | 917  | 
let  | 
| 21867 | 918  | 
val url = #url vs  | 
919  | 
val filepath = PgipTypes.path_of_pgipurl url  | 
|
920  | 
val filedir = Path.dir filepath  | 
|
921  | 
val thy_name = Path.implode o #1 o Path.split_ext o Path.base  | 
|
922  | 
val openfile_retract = Output.no_warnings (ThyInfo.if_known_thy ThyInfo.remove_thy) o thy_name;  | 
|
923  | 
in  | 
|
924  | 
case !currently_open_file of  | 
|
| 22028 | 925  | 
          SOME f => raise PGIP ("<openfile> when a file is already open!\nCurrently open file: " ^
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
926  | 
PgipTypes.string_of_pgipurl url)  | 
| 21867 | 927  | 
| NONE => (openfile_retract filepath;  | 
| 21940 | 928  | 
changecwd_dir filedir;  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
929  | 
                   priority ("Working in file: " ^ PgipTypes.string_of_pgipurl url);
 | 
| 21940 | 930  | 
currently_open_file := SOME url)  | 
| 21867 | 931  | 
end  | 
932  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
933  | 
fun closefile _ =  | 
| 21867 | 934  | 
case !currently_open_file of  | 
| 
22042
 
64f8f5433f30
Cleanup message model: add info fatality level.  Add informfileoutdated and some use of completed flag.
 
aspinall 
parents: 
22028 
diff
changeset
 | 
935  | 
SOME f => (proper_inform_file_processed f (Isar.state());  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
936  | 
                   priority ("Finished working in file: " ^ PgipTypes.string_of_pgipurl f);
 | 
| 21867 | 937  | 
currently_open_file := NONE)  | 
938  | 
      | NONE => raise PGIP ("<closefile> when no file is open!")
 | 
|
939  | 
||
| 21940 | 940  | 
fun loadfile (Loadfile vs) =  | 
941  | 
let  | 
|
942  | 
val url = #url vs  | 
|
943  | 
in  | 
|
| 
22171
 
58f554f51f0d
Let <loadfile> execute even while a file is open interactively.
 
aspinall 
parents: 
22163 
diff
changeset
 | 
944  | 
(* da: this doesn't seem to cause a problem, batch loading uses  | 
| 
 
58f554f51f0d
Let <loadfile> execute even while a file is open interactively.
 
aspinall 
parents: 
22163 
diff
changeset
 | 
945  | 
a different state context. Of course confusion is still possible,  | 
| 
 
58f554f51f0d
Let <loadfile> execute even while a file is open interactively.
 
aspinall 
parents: 
22163 
diff
changeset
 | 
946  | 
e.g. file loaded depends on open file which is not yet saved. *)  | 
| 
 
58f554f51f0d
Let <loadfile> execute even while a file is open interactively.
 
aspinall 
parents: 
22163 
diff
changeset
 | 
947  | 
(* case !currently_open_file of  | 
| 22028 | 948  | 
            SOME f => raise PGIP ("<loadfile> when a file is open!\nCurrently open file: " ^
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
949  | 
PgipTypes.string_of_pgipurl url)  | 
| 
22171
 
58f554f51f0d
Let <loadfile> execute even while a file is open interactively.
 
aspinall 
parents: 
22163 
diff
changeset
 | 
950  | 
| NONE => *)  | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
951  | 
use_thy_or_ml_file (File.platform_path url)  | 
| 21637 | 952  | 
end  | 
953  | 
||
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
954  | 
fun abortfile _ =  | 
| 21637 | 955  | 
case !currently_open_file of  | 
956  | 
SOME f => (isarcmd "init_toplevel";  | 
|
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
957  | 
                   priority ("Aborted working in file: " ^
 | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
958  | 
PgipTypes.string_of_pgipurl f);  | 
| 21940 | 959  | 
currently_open_file := NONE)  | 
| 21637 | 960  | 
      | NONE => raise PGIP ("<abortfile> when no file is open!")
 | 
961  | 
||
| 21940 | 962  | 
fun retractfile (Retractfile vs) =  | 
963  | 
let  | 
|
964  | 
val url = #url vs  | 
|
| 21637 | 965  | 
in  | 
| 21940 | 966  | 
case !currently_open_file of  | 
| 21637 | 967  | 
            SOME f => raise PGIP ("<retractfile> when a file is open!")
 | 
| 22028 | 968  | 
          | NONE => (priority ("Retracting file: " ^ PgipTypes.string_of_pgipurl url);
 | 
| 
22228
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
969  | 
(* TODO: next should be in thy loader, here just for testing *)  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
970  | 
let  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
971  | 
val name = thy_name url  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
972  | 
in List.app (tell_file_retracted false) (ThyInfo.loaded_files name) end;  | 
| 
 
7c27195a4afc
proper use of PureThy.has_name_hint instead of hard-wired string'';
 
wenzelm 
parents: 
22225 
diff
changeset
 | 
973  | 
inform_file_retracted url)  | 
| 21637 | 974  | 
end  | 
975  | 
||
976  | 
||
| 21867 | 977  | 
(*** System ***)  | 
| 21637 | 978  | 
|
| 21902 | 979  | 
fun systemcmd (Systemcmd vs) =  | 
| 21940 | 980  | 
let  | 
| 21637 | 981  | 
val arg = #arg vs  | 
982  | 
in  | 
|
983  | 
isarcmd arg  | 
|
984  | 
end  | 
|
985  | 
||
986  | 
exception PGIP_QUIT;  | 
|
| 
23834
 
ad6ad61332fa
avoid redundant variables in patterns (which made Alice vomit);
 
wenzelm 
parents: 
23801 
diff
changeset
 | 
987  | 
fun quitpgip _ = raise PGIP_QUIT  | 
| 21637 | 988  | 
|
| 21902 | 989  | 
fun process_input inp = case inp  | 
990  | 
of Pgip.Askpgip _ => askpgip inp  | 
|
991  | 
| Pgip.Askpgml _ => askpgml inp  | 
|
| 21940 | 992  | 
| Pgip.Askprefs _ => askprefs inp  | 
| 21902 | 993  | 
| Pgip.Askconfig _ => askconfig inp  | 
994  | 
| Pgip.Getpref _ => getpref inp  | 
|
995  | 
| Pgip.Setpref _ => setpref inp  | 
|
996  | 
| Pgip.Proverinit _ => proverinit inp  | 
|
997  | 
| Pgip.Proverexit _ => proverexit inp  | 
|
| 22408 | 998  | 
| Pgip.Setproverflag _ => setproverflag inp  | 
| 21902 | 999  | 
| Pgip.Dostep _ => dostep inp  | 
1000  | 
| Pgip.Undostep _ => undostep inp  | 
|
1001  | 
| Pgip.Redostep _ => redostep inp  | 
|
| 
23435
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
1002  | 
| Pgip.Forget _ => error "<forget> not implemented by Isabelle"  | 
| 
 
061f28854017
Remove dedicated flag setting elements in favour of setproverflag.  Restore displayconfig response in askpgip.
 
aspinall 
parents: 
23226 
diff
changeset
 | 
1003  | 
| Pgip.Restoregoal _ => error "<restoregoal> not implemented by Isabelle"  | 
| 21902 | 1004  | 
| Pgip.Abortgoal _ => abortgoal inp  | 
1005  | 
| Pgip.Askids _ => askids inp  | 
|
| 22159 | 1006  | 
| Pgip.Askrefs _ => askrefs inp  | 
| 21902 | 1007  | 
| Pgip.Showid _ => showid inp  | 
1008  | 
| Pgip.Askguise _ => askguise inp  | 
|
1009  | 
| Pgip.Parsescript _ => parsescript inp  | 
|
1010  | 
| Pgip.Showproofstate _ => showproofstate inp  | 
|
1011  | 
| Pgip.Showctxt _ => showctxt inp  | 
|
1012  | 
| Pgip.Searchtheorems _ => searchtheorems inp  | 
|
1013  | 
| Pgip.Setlinewidth _ => setlinewidth inp  | 
|
1014  | 
| Pgip.Viewdoc _ => viewdoc inp  | 
|
1015  | 
| Pgip.Doitem _ => doitem inp  | 
|
1016  | 
| Pgip.Undoitem _ => undoitem inp  | 
|
1017  | 
| Pgip.Redoitem _ => redoitem inp  | 
|
1018  | 
| Pgip.Aborttheory _ => aborttheory inp  | 
|
1019  | 
| Pgip.Retracttheory _ => retracttheory inp  | 
|
1020  | 
| Pgip.Loadfile _ => loadfile inp  | 
|
1021  | 
| Pgip.Openfile _ => openfile inp  | 
|
1022  | 
| Pgip.Closefile _ => closefile inp  | 
|
1023  | 
| Pgip.Abortfile _ => abortfile inp  | 
|
1024  | 
| Pgip.Retractfile _ => retractfile inp  | 
|
1025  | 
| Pgip.Changecwd _ => changecwd inp  | 
|
1026  | 
| Pgip.Systemcmd _ => systemcmd inp  | 
|
1027  | 
| Pgip.Quitpgip _ => quitpgip inp  | 
|
| 21637 | 1028  | 
|
1029  | 
||
| 21940 | 1030  | 
fun process_pgip_element pgipxml =  | 
| 21637 | 1031  | 
case pgipxml of  | 
| 21969 | 1032  | 
xml as (XML.Elem elem) =>  | 
| 21940 | 1033  | 
(case Pgip.input elem of  | 
1034  | 
             NONE => warning ("Unrecognized PGIP command, ignored: \n" ^
 | 
|
1035  | 
(XML.string_of_tree xml))  | 
|
1036  | 
| SOME inp => (process_input inp)) (* errors later; packet discarded *)  | 
|
| 21969 | 1037  | 
| XML.Text t => ignored_text_warning t  | 
| 23723 | 1038  | 
| XML.Output t => ignored_text_warning t  | 
| 21637 | 1039  | 
and ignored_text_warning t =  | 
| 21940 | 1040  | 
if size (Symbol.strip_blanks t) > 0 then  | 
1041  | 
           warning ("Ignored text in PGIP packet: \n" ^ t)
 | 
|
| 21637 | 1042  | 
else ()  | 
1043  | 
||
1044  | 
fun process_pgip_tree xml =  | 
|
1045  | 
(pgip_refid := NONE;  | 
|
1046  | 
pgip_refseq := NONE;  | 
|
1047  | 
(case xml of  | 
|
1048  | 
          XML.Elem ("pgip", attrs, pgips) =>
 | 
|
1049  | 
(let  | 
|
1050  | 
val class = PgipTypes.get_attr "class" attrs  | 
|
1051  | 
val dest = PgipTypes.get_attr_opt "destid" attrs  | 
|
| 21940 | 1052  | 
val seq = PgipTypes.read_pgipnat (PgipTypes.get_attr "seq" attrs)  | 
| 21637 | 1053  | 
(* Respond to prover broadcasts, or messages for us. Ignore rest *)  | 
| 21940 | 1054  | 
val processit =  | 
1055  | 
case dest of  | 
|
| 21637 | 1056  | 
NONE => class = "pa"  | 
| 21940 | 1057  | 
| SOME id => matching_pgip_id id  | 
1058  | 
in if processit then  | 
|
1059  | 
(pgip_refid := PgipTypes.get_attr_opt "id" attrs;  | 
|
1060  | 
pgip_refseq := SOME seq;  | 
|
1061  | 
List.app process_pgip_element pgips;  | 
|
1062  | 
(* return true to indicate <ready/> *)  | 
|
1063  | 
true)  | 
|
1064  | 
else  | 
|
1065  | 
(* no response to ignored messages. *)  | 
|
1066  | 
false  | 
|
| 21637 | 1067  | 
end)  | 
1068  | 
| _ => raise PGIP "Invalid PGIP packet received")  | 
|
1069  | 
handle PGIP msg =>  | 
|
1070  | 
(Output.error_msg ((msg ^ "\nPGIP error occured in XML text below:\n") ^  | 
|
| 21940 | 1071  | 
(XML.string_of_tree xml));  | 
1072  | 
true))  | 
|
| 21637 | 1073  | 
|
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1074  | 
(* External input *)  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1075  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1076  | 
val process_pgip_plain = K () o process_pgip_tree o XML.tree_of_string  | 
| 21637 | 1077  | 
|
1078  | 
(* PGIP loop: process PGIP input only *)  | 
|
1079  | 
||
1080  | 
local  | 
|
1081  | 
||
1082  | 
exception XML_PARSE  | 
|
1083  | 
||
1084  | 
fun loop ready src =  | 
|
1085  | 
let  | 
|
1086  | 
val _ = if ready then issue_pgip (Ready ()) else ()  | 
|
| 21969 | 1087  | 
val pgipo =  | 
1088  | 
(case try Source.get_single src of  | 
|
1089  | 
SOME pgipo => pgipo  | 
|
1090  | 
| NONE => raise XML_PARSE)  | 
|
| 21637 | 1091  | 
in  | 
1092  | 
case pgipo of  | 
|
1093  | 
NONE => ()  | 
|
1094  | 
| SOME (pgip,src') =>  | 
|
1095  | 
let  | 
|
| 21940 | 1096  | 
val ready' = (process_pgip_tree pgip)  | 
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
1097  | 
handle PGIP_QUIT => raise PGIP_QUIT  | 
| 22590 | 1098  | 
| e => (handler (e,SOME src'); true)  | 
| 21637 | 1099  | 
in  | 
1100  | 
loop ready' src'  | 
|
1101  | 
end  | 
|
1102  | 
end handle e => handler (e,SOME src) (* error in XML parse or Ready issue *)  | 
|
1103  | 
||
1104  | 
and handler (e,srco) =  | 
|
1105  | 
case (e,srco) of  | 
|
1106  | 
(XML_PARSE,SOME src) =>  | 
|
| 
22699
 
938c1011ac94
removed unused Output.panic hook -- internal to PG wrapper;
 
wenzelm 
parents: 
22678 
diff
changeset
 | 
1107  | 
panic "Invalid XML input, aborting" (* TODO: attempt recovery *)  | 
| 21940 | 1108  | 
| (Interrupt,SOME src) =>  | 
1109  | 
(Output.error_msg "Interrupt during PGIP processing"; loop true src)  | 
|
1110  | 
| (Toplevel.UNDEF,SOME src) =>  | 
|
1111  | 
(Output.error_msg "No working context defined"; loop true src)  | 
|
1112  | 
| (e,SOME src) =>  | 
|
1113  | 
(Output.error_msg (Toplevel.exn_message e); loop true src)  | 
|
| 
22337
 
d4599c206446
Fix <pgipquit>.  Remove unused pgmlatomsN.  Make showid match askids.  Use string functions for showid, avoiding printwrap kludge.
 
aspinall 
parents: 
22249 
diff
changeset
 | 
1114  | 
| (PGIP_QUIT,_) => ()  | 
| 21637 | 1115  | 
| (_,NONE) => ()  | 
1116  | 
in  | 
|
1117  | 
(* TODO: add socket interface *)  | 
|
1118  | 
||
1119  | 
val xmlP = XML.scan_comment_whspc |-- XML.parse_elem >> single  | 
|
1120  | 
||
1121  | 
val tty_src = Source.set_prompt "" (Source.source Symbol.stopper xmlP NONE Source.tty)  | 
|
1122  | 
||
1123  | 
fun pgip_toplevel x = loop true x  | 
|
1124  | 
end  | 
|
1125  | 
||
1126  | 
||
| 
21972
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
1127  | 
(* Extra command for embedding prover-control inside document (obscure/debug usage). *)  | 
| 21637 | 1128  | 
|
| 24867 | 1129  | 
fun init_outer_syntax () =  | 
| 
21972
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
1130  | 
OuterSyntax.improper_command "ProofGeneral.process_pgip" "(internal)" OuterKeyword.control  | 
| 
 
1b68312c4cf0
Initialise parser at startup.  Remove some obsolete ProofGeneral.XXX outer syntax, mapping PGIP commands directly to Isar.
 
aspinall 
parents: 
21970 
diff
changeset
 | 
1131  | 
(OuterParse.text >> (Toplevel.no_timing oo  | 
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1132  | 
(fn txt => Toplevel.imperative (fn () => process_pgip_plain txt))));  | 
| 21637 | 1133  | 
|
1134  | 
||
1135  | 
(* init *)  | 
|
1136  | 
||
1137  | 
val initialized = ref false;  | 
|
1138  | 
||
| 
22699
 
938c1011ac94
removed unused Output.panic hook -- internal to PG wrapper;
 
wenzelm 
parents: 
22678 
diff
changeset
 | 
1139  | 
fun init_pgip false = panic "No Proof General interface support for Isabelle/classic mode."  | 
| 21969 | 1140  | 
| init_pgip true =  | 
1141  | 
(! initialized orelse  | 
|
| 
25445
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1142  | 
(setup_preferences_tweak ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1143  | 
setup_proofgeneral_output ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1144  | 
setup_messages ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1145  | 
Output.no_warnings init_outer_syntax ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1146  | 
setup_thy_loader ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1147  | 
setup_present_hook ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1148  | 
init_pgip_session_id ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1149  | 
welcome ();  | 
| 
 
01f3686f4304
Init outer syntax after message setup to avoid spurious output.
 
aspinall 
parents: 
25275 
diff
changeset
 | 
1150  | 
set initialized);  | 
| 21969 | 1151  | 
sync_thy_loader ();  | 
1152  | 
change print_mode (cons proof_generalN o remove (op =) proof_generalN);  | 
|
1153  | 
pgip_toplevel tty_src);  | 
|
| 21637 | 1154  | 
|
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1155  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1156  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1157  | 
(** Out-of-loop PGIP commands (for Emacs hybrid mode) **)  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1158  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1159  | 
local  | 
| 22590 | 1160  | 
val pgip_output_channel = ref Output.writeln_default  | 
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1161  | 
in  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1162  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1163  | 
(* Set recipient for PGIP results *)  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1164  | 
fun init_pgip_channel writefn =  | 
| 21940 | 1165  | 
(init_pgip_session_id();  | 
1166  | 
pgip_output_channel := writefn)  | 
|
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1167  | 
|
| 21940 | 1168  | 
(* Process a PGIP command.  | 
1169  | 
This works for preferences but not generally guaranteed  | 
|
| 
21649
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1170  | 
because we haven't done full setup here (e.g., no pgml mode) *)  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1171  | 
fun process_pgip str =  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1172  | 
setmp output_xml_fn (!pgip_output_channel) process_pgip_plain str  | 
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1173  | 
|
| 
 
40e6fdd26f82
Support PGIP communication for preferences in Emacs mode.
 
aspinall 
parents: 
21646 
diff
changeset
 | 
1174  | 
end  | 
| 21637 | 1175  | 
|
1176  | 
end;  |