29 |
29 |
30 class Prover(isabelle_system: IsabelleSystem, logic: String) extends Actor |
30 class Prover(isabelle_system: IsabelleSystem, logic: String) extends Actor |
31 { |
31 { |
32 /* prover process */ |
32 /* prover process */ |
33 |
33 |
34 private var process: Isar with IsarDocument= null |
34 |
35 |
35 private val process = |
36 { |
36 { |
37 val results = new EventBus[IsabelleProcess.Result] + handle_result |
37 val results = new EventBus[IsabelleProcess.Result] + handle_result |
38 results.logger = Log.log(Log.ERROR, null, _) |
38 results.logger = Log.log(Log.ERROR, null, _) |
39 process = new Isar(isabelle_system, results, "-m", "xsymbols", logic) with IsarDocument |
39 new IsabelleProcess(isabelle_system, results, "-m", "xsymbols", logic) with IsarDocument |
40 } |
40 } |
41 |
41 |
42 def stop() { process.kill } |
42 def stop() { process.kill } |
43 |
43 |
44 |
44 |
45 /* document state information */ |
45 /* document state information */ |
46 |
46 |
47 private val states = new mutable.HashMap[IsarDocument.State_ID, Command] |
47 private val states = new mutable.HashMap[IsarDocument.State_ID, Command] with |
48 private val commands = new mutable.HashMap[IsarDocument.Command_ID, Command] |
48 mutable.SynchronizedMap[IsarDocument.State_ID, Command] |
49 private val document0 = Isabelle.plugin.id() |
49 private val commands = new mutable.HashMap[IsarDocument.Command_ID, Command] with |
50 private var document_versions = List((document0, ProofDocument.empty)) |
50 mutable.SynchronizedMap[IsarDocument.Command_ID, Command] |
51 |
51 private val document_id0 = Isabelle.plugin.id() |
52 def get_id = document_versions.head._1 |
52 private var document_versions = List((document_id0, ProofDocument.empty)) |
|
53 |
|
54 def document_id = document_versions.head._1 |
53 def document = document_versions.head._2 |
55 def document = document_versions.head._2 |
54 |
56 |
55 private var initialized = false |
57 private var initialized = false |
56 |
58 |
57 |
59 |
58 /* outer syntax keywords */ |
60 /* outer syntax keywords */ |
59 |
61 |
60 val decl_info = new EventBus[(String, String)] |
62 val decl_info = new EventBus[(String, String)] |
61 |
63 |
62 private val keyword_decls = new mutable.HashSet[String] { |
64 private val keyword_decls = |
|
65 new mutable.HashSet[String] with mutable.SynchronizedSet[String] { |
63 override def +=(name: String) = { |
66 override def +=(name: String) = { |
64 decl_info.event(name, OuterKeyword.MINOR) |
67 decl_info.event(name, OuterKeyword.MINOR) |
65 super.+=(name) |
68 super.+=(name) |
66 } |
69 } |
67 } |
70 } |
68 private val command_decls = new mutable.HashMap[String, String] { |
71 private val command_decls = |
|
72 new mutable.HashMap[String, String] with mutable.SynchronizedMap[String, String] { |
69 override def +=(entry: (String, String)) = { |
73 override def +=(entry: (String, String)) = { |
70 decl_info.event(entry) |
74 decl_info.event(entry) |
71 super.+=(entry) |
75 super.+=(entry) |
72 } |
76 } |
73 } |
77 } |
91 |
95 |
92 val activated = new EventBus[Unit] |
96 val activated = new EventBus[Unit] |
93 val output_info = new EventBus[String] |
97 val output_info = new EventBus[String] |
94 var change_receiver = null: Actor |
98 var change_receiver = null: Actor |
95 |
99 |
96 def command_change(c: Command) = this ! c |
|
97 |
|
98 private def handle_result(result: IsabelleProcess.Result) |
100 private def handle_result(result: IsabelleProcess.Result) |
99 { |
101 { |
|
102 def command_change(c: Command) = this ! c |
100 val (running, command) = |
103 val (running, command) = |
101 result.props.find(p => p._1 == Markup.ID) match { |
104 result.props.find(p => p._1 == Markup.ID) match { |
102 case None => (false, null) |
105 case None => (false, null) |
103 case Some((_, id)) => |
106 case Some((_, id)) => |
104 if (commands.contains(id)) (false, commands(id)) |
107 if (commands.contains(id)) (false, commands(id)) |
105 else if (states.contains(id)) (true, states(id)) |
108 else if (states.contains(id)) (true, states(id)) |
106 else (false, null) |
109 else (false, null) |
107 } |
110 } |
108 |
111 |
109 if (result.kind == IsabelleProcess.Kind.STDOUT || result.kind == IsabelleProcess.Kind.STDIN) |
112 if (result.kind == IsabelleProcess.Kind.STDOUT || result.kind == IsabelleProcess.Kind.STDIN) |
110 Swing.now { output_info.event(result.result) } |
113 output_info.event(result.toString) |
111 else if (result.kind == IsabelleProcess.Kind.WRITELN && !initialized) { // FIXME !? |
114 else if (result.kind == IsabelleProcess.Kind.WRITELN && !initialized) { // FIXME !? |
112 initialized = true |
115 initialized = true |
113 Swing.now { this ! ProverEvents.Activate } |
116 Swing.now { this ! ProverEvents.Activate } |
114 } |
117 } |
115 else { |
118 else { |
141 keyword_decls += name |
144 keyword_decls += name |
142 |
145 |
143 // document edits |
146 // document edits |
144 case XML.Elem(Markup.EDITS, (Markup.ID, doc_id) :: _, edits) |
147 case XML.Elem(Markup.EDITS, (Markup.ID, doc_id) :: _, edits) |
145 if document_versions.contains(doc_id) => |
148 if document_versions.contains(doc_id) => |
|
149 output_info.event(result.toString) |
146 for { |
150 for { |
147 XML.Elem(Markup.EDIT, (Markup.ID, cmd_id) :: (Markup.STATE, state_id) :: _, _) |
151 XML.Elem(Markup.EDIT, (Markup.ID, cmd_id) :: (Markup.STATE, state_id) :: _, _) |
148 <- edits |
152 <- edits |
149 if (commands.contains(cmd_id)) |
|
150 } { |
153 } { |
|
154 if (commands.contains(cmd_id)) { |
151 val cmd = commands(cmd_id) |
155 val cmd = commands(cmd_id) |
152 if (cmd.state_id != null) states -= cmd.state_id |
156 if (cmd.state_id != null) states -= cmd.state_id |
153 states(cmd_id) = cmd |
157 states(cmd_id) = cmd |
154 cmd.state_id = state_id |
158 cmd.state_id = state_id |
155 cmd.status = Command.Status.UNPROCESSED |
159 cmd.status = Command.Status.UNPROCESSED |
156 command_change(cmd) |
160 command_change(cmd) |
157 } |
161 } |
158 |
162 |
|
163 } |
159 // command status |
164 // command status |
160 case XML.Elem(Markup.UNPROCESSED, _, _) |
165 case XML.Elem(Markup.UNPROCESSED, _, _) |
161 if command != null => |
166 if command != null => |
|
167 output_info.event(result.toString) |
162 command.status = Command.Status.UNPROCESSED |
168 command.status = Command.Status.UNPROCESSED |
163 command_change(command) |
169 command_change(command) |
164 case XML.Elem(Markup.FINISHED, _, _) |
170 case XML.Elem(Markup.FINISHED, _, _) |
165 if command != null => |
171 if command != null => |
|
172 output_info.event(result.toString) |
166 command.status = Command.Status.FINISHED |
173 command.status = Command.Status.FINISHED |
167 command_change(command) |
174 command_change(command) |
168 case XML.Elem(Markup.FAILED, _, _) |
175 case XML.Elem(Markup.FAILED, _, _) |
169 if command != null => |
176 if command != null => |
|
177 output_info.event(result.toString) |
170 command.status = Command.Status.FAILED |
178 command.status = Command.Status.FAILED |
171 command_change(command) |
179 command_change(command) |
172 |
180 |
173 // other markup |
181 // other markup |
174 case XML.Elem(kind, |
182 case XML.Elem(kind, |
203 import ProverEvents._ |
211 import ProverEvents._ |
204 loop { |
212 loop { |
205 react { |
213 react { |
206 case Activate => { |
214 case Activate => { |
207 val (doc, structure_change) = document.activate |
215 val (doc, structure_change) = document.activate |
208 val old_id = get_id |
216 val old_id = document_id |
209 val doc_id = Isabelle.plugin.id() |
217 val doc_id = Isabelle.plugin.id() |
210 document_versions ::= (doc_id, doc) |
218 document_versions ::= (doc_id, doc) |
211 edit_document(old_id, doc_id, structure_change) |
219 edit_document(old_id, doc_id, structure_change) |
212 } |
220 } |
213 case SetIsCommandKeyword(f) => { |
221 case SetIsCommandKeyword(f) => { |
214 val old_id = get_id |
222 val old_id = document_id |
215 val doc_id = Isabelle.plugin.id() |
223 val doc_id = Isabelle.plugin.id() |
216 document_versions ::= (doc_id, document.set_command_keyword(f)) |
224 document_versions ::= (doc_id, document.set_command_keyword(f)) |
217 edit_document(old_id, doc_id, StructureChange(None, Nil, Nil)) |
225 edit_document(old_id, doc_id, StructureChange(None, Nil, Nil)) |
218 } |
226 } |
219 case change: Text.Change => { |
227 case change: Text.Change => { |
220 val (doc, structure_change) = document.text_changed(change) |
228 val (doc, structure_change) = document.text_changed(change) |
221 val old_id = get_id |
229 val old_id = document_id |
222 val doc_id = Isabelle.plugin.id() |
230 val doc_id = Isabelle.plugin.id() |
223 document_versions ::= (doc_id, doc) |
231 document_versions ::= (doc_id, doc) |
224 edit_document(old_id, doc_id, structure_change) |
232 edit_document(old_id, doc_id, structure_change) |
225 } |
233 } |
226 case command: Command => { |
234 case command: Command => { |
233 |
241 |
234 def set_document(change_receiver: Actor, path: String) { |
242 def set_document(change_receiver: Actor, path: String) { |
235 this.change_receiver = change_receiver |
243 this.change_receiver = change_receiver |
236 this ! ProverEvents.SetIsCommandKeyword(command_decls.contains) |
244 this ! ProverEvents.SetIsCommandKeyword(command_decls.contains) |
237 process.ML("()") // FIXME force initial writeln |
245 process.ML("()") // FIXME force initial writeln |
238 process.begin_document(document0, path) |
246 process.begin_document(document_id0, path) |
239 } |
247 } |
240 |
248 |
241 private def edit_document(old_id: String, document_id: String, changes: StructureChange) = Swing.now |
249 private def edit_document(old_id: String, document_id: String, changes: StructureChange) = Swing.now |
242 { |
250 { |
243 val removes = |
251 val removes = |
244 for (cmd <- changes.removed_commands) yield { |
252 for (cmd <- changes.removed_commands) yield { |
245 commands -= cmd.id |
253 commands -= cmd.id |
246 if (cmd.state_id != null) states -= cmd.state_id |
254 if (cmd.state_id != null) states -= cmd.state_id |
247 (document.commands.prev(cmd).map(_.id).getOrElse(document0)) -> None |
255 (document.commands.prev(cmd).map(_.id).getOrElse(document_id0)) -> None |
248 } |
256 } |
249 val inserts = |
257 val inserts = |
250 for (cmd <- changes.added_commands) yield { |
258 for (cmd <- changes.added_commands) yield { |
251 commands += (cmd.id -> cmd) |
259 commands += (cmd.id -> cmd) |
252 process.define_command(cmd.id, isabelle_system.symbols.encode(cmd.content)) |
260 process.define_command(cmd.id, isabelle_system.symbols.encode(cmd.content)) |
253 (document.commands.prev(cmd).map(_.id).getOrElse(document0)) -> Some(cmd.id) |
261 (document.commands.prev(cmd).map(_.id).getOrElse(document_id0)) -> Some(cmd.id) |
254 } |
262 } |
255 process.edit_document(old_id, document_id, removes.reverse ++ inserts) |
263 process.edit_document(old_id, document_id, removes.reverse ++ inserts) |
256 } |
264 } |
257 } |
265 } |