25 val Success = new Properties.Boolean(SUCCESS) |
24 val Success = new Properties.Boolean(SUCCESS) |
26 |
25 |
27 val MEMORY = "memory" |
26 val MEMORY = "memory" |
28 val Memory = new Properties.Boolean(MEMORY) |
27 val Memory = new Properties.Boolean(MEMORY) |
29 |
28 |
30 object Item |
29 object Item { |
31 { |
|
32 case class Data( |
30 case class Data( |
33 serial: Long, markup: String, text: String, |
31 serial: Long, markup: String, text: String, |
34 parent: Long, props: Properties.T, content: XML.Body) |
32 parent: Long, props: Properties.T, content: XML.Body |
35 { |
33 ) { |
36 def memory: Boolean = Memory.unapply(props) getOrElse true |
34 def memory: Boolean = Memory.unapply(props) getOrElse true |
37 } |
35 } |
38 |
36 |
39 def unapply(tree: XML.Tree): Option[(String, Data)] = |
37 def unapply(tree: XML.Tree): Option[(String, Data)] = |
40 tree match { |
38 tree match { |
53 |
51 |
54 /* replies to the prover */ |
52 /* replies to the prover */ |
55 |
53 |
56 case class Answer private[Simplifier_Trace](val name: String, val string: String) |
54 case class Answer private[Simplifier_Trace](val name: String, val string: String) |
57 |
55 |
58 object Answer |
56 object Answer { |
59 { |
57 object step { |
60 object step |
|
61 { |
|
62 val skip = Answer("skip", "Skip") |
58 val skip = Answer("skip", "Skip") |
63 val continue = Answer("continue", "Continue") |
59 val continue = Answer("continue", "Continue") |
64 val continue_trace = Answer("continue_trace", "Continue (with full trace)") |
60 val continue_trace = Answer("continue_trace", "Continue (with full trace)") |
65 val continue_passive = Answer("continue_passive", "Continue (without asking)") |
61 val continue_passive = Answer("continue_passive", "Continue (without asking)") |
66 val continue_disable = Answer("continue_disable", "Continue (without any trace)") |
62 val continue_disable = Answer("continue_disable", "Continue (without any trace)") |
67 |
63 |
68 val all = List(continue, continue_trace, continue_passive, continue_disable, skip) |
64 val all = List(continue, continue_trace, continue_passive, continue_disable, skip) |
69 } |
65 } |
70 |
66 |
71 object hint_fail |
67 object hint_fail { |
72 { |
|
73 val exit = Answer("exit", "Exit") |
68 val exit = Answer("exit", "Exit") |
74 val redo = Answer("redo", "Redo") |
69 val redo = Answer("redo", "Redo") |
75 |
70 |
76 val all = List(redo, exit) |
71 val all = List(redo, exit) |
77 } |
72 } |
96 |
91 |
97 case class Question(data: Item.Data, answers: List[Answer]) |
92 case class Question(data: Item.Data, answers: List[Answer]) |
98 |
93 |
99 case class Context( |
94 case class Context( |
100 last_serial: Long = 0L, |
95 last_serial: Long = 0L, |
101 questions: SortedMap[Long, Question] = SortedMap.empty) |
96 questions: SortedMap[Long, Question] = SortedMap.empty |
102 { |
97 ) { |
103 def +(q: Question): Context = |
98 def +(q: Question): Context = |
104 copy(questions = questions + ((q.data.serial, q))) |
99 copy(questions = questions + ((q.data.serial, q))) |
105 |
100 |
106 def -(s: Long): Context = |
101 def -(s: Long): Context = |
107 copy(questions = questions - s) |
102 copy(questions = questions - s) |
112 |
107 |
113 case class Trace(entries: List[Item.Data]) |
108 case class Trace(entries: List[Item.Data]) |
114 |
109 |
115 case class Index(text: String, content: XML.Body) |
110 case class Index(text: String, content: XML.Body) |
116 |
111 |
117 object Index |
112 object Index { |
118 { |
|
119 def of_data(data: Item.Data): Index = |
113 def of_data(data: Item.Data): Index = |
120 Index(data.text, data.content) |
114 Index(data.text, data.content) |
121 } |
115 } |
122 |
116 |
123 def handle_results(session: Session, id: Document_ID.Command, results: Command.Results): Context = |
117 def handle_results( |
124 { |
118 session: Session, |
|
119 id: Document_ID.Command, |
|
120 results: Command.Results |
|
121 ): Context = { |
125 val slot = Future.promise[Context] |
122 val slot = Future.promise[Context] |
126 the_manager(session).send(Handle_Results(session, id, results, slot)) |
123 the_manager(session).send(Handle_Results(session, id, results, slot)) |
127 slot.join |
124 slot.join |
128 } |
125 } |
129 |
126 |
130 def generate_trace(session: Session, results: Command.Results): Trace = |
127 def generate_trace(session: Session, results: Command.Results): Trace = { |
131 { |
|
132 val slot = Future.promise[Trace] |
128 val slot = Future.promise[Trace] |
133 the_manager(session).send(Generate_Trace(results, slot)) |
129 the_manager(session).send(Generate_Trace(results, slot)) |
134 slot.join |
130 slot.join |
135 } |
131 } |
136 |
132 |
138 the_manager(session).send(Clear_Memory) |
134 the_manager(session).send(Clear_Memory) |
139 |
135 |
140 def send_reply(session: Session, serial: Long, answer: Answer): Unit = |
136 def send_reply(session: Session, serial: Long, answer: Answer): Unit = |
141 the_manager(session).send(Reply(session, serial, answer)) |
137 the_manager(session).send(Reply(session, serial, answer)) |
142 |
138 |
143 def make_manager: Consumer_Thread[Any] = |
139 def make_manager: Consumer_Thread[Any] = { |
144 { |
|
145 var contexts = Map.empty[Document_ID.Command, Context] |
140 var contexts = Map.empty[Document_ID.Command, Context] |
146 |
141 |
147 var memory_children = Map.empty[Long, Set[Long]] |
142 var memory_children = Map.empty[Long, Set[Long]] |
148 var memory = Map.empty[Index, Answer] |
143 var memory = Map.empty[Index, Answer] |
149 |
144 |
151 contexts collectFirst { |
146 contexts collectFirst { |
152 case (id, context) if context.questions contains serial => |
147 case (id, context) if context.questions contains serial => |
153 (id, context.questions(serial)) |
148 (id, context.questions(serial)) |
154 } |
149 } |
155 |
150 |
156 def do_cancel(serial: Long, id: Document_ID.Command): Unit = |
151 def do_cancel(serial: Long, id: Document_ID.Command): Unit = { |
157 { |
|
158 // To save memory, we could try to remove empty contexts at this point. |
152 // To save memory, we could try to remove empty contexts at this point. |
159 // However, if a new serial gets attached to the same command_id after we deleted |
153 // However, if a new serial gets attached to the same command_id after we deleted |
160 // its context, its last_serial counter will start at 0 again, and we'll think the |
154 // its context, its last_serial counter will start at 0 again, and we'll think the |
161 // old serials are actually new |
155 // old serials are actually new |
162 contexts += (id -> (contexts(id) - serial)) |
156 contexts += (id -> (contexts(id) - serial)) |
163 } |
157 } |
164 |
158 |
165 def do_reply(session: Session, serial: Long, answer: Answer): Unit = |
159 def do_reply(session: Session, serial: Long, answer: Answer): Unit = { |
166 { |
|
167 session.protocol_command( |
160 session.protocol_command( |
168 "Simplifier_Trace.reply", Value.Long(serial), answer.name) |
161 "Simplifier_Trace.reply", Value.Long(serial), answer.name) |
169 } |
162 } |
170 |
163 |
171 Consumer_Thread.fork[Any]("Simplifier_Trace.manager", daemon = true)( |
164 Consumer_Thread.fork[Any]("Simplifier_Trace.manager", daemon = true)( |
172 consume = (arg: Any) => |
165 consume = (arg: Any) => { |
173 { |
|
174 arg match { |
166 arg match { |
175 case Handle_Results(session, id, results, slot) => |
167 case Handle_Results(session, id, results, slot) => |
176 var new_context = contexts.getOrElse(id, Context()) |
168 var new_context = contexts.getOrElse(id, Context()) |
177 var new_serial = new_context.last_serial |
169 var new_serial = new_context.last_serial |
178 |
170 |
179 for ((serial, result) <- results.iterator if serial > new_context.last_serial) |
171 for ((serial, result) <- results.iterator if serial > new_context.last_serial) { |
180 { |
|
181 result match { |
172 result match { |
182 case Item(markup, data) => |
173 case Item(markup, data) => |
183 memory_children += |
174 memory_children += |
184 (data.parent -> (memory_children.getOrElse(data.parent, Set.empty) + serial)) |
175 (data.parent -> (memory_children.getOrElse(data.parent, Set.empty) + serial)) |
185 |
176 |
262 memory = Map.empty |
253 memory = Map.empty |
263 |
254 |
264 case Reply(session, serial, answer) => |
255 case Reply(session, serial, answer) => |
265 find_question(serial) match { |
256 find_question(serial) match { |
266 case Some((id, Question(data, _))) => |
257 case Some((id, Question(data, _))) => |
267 if (data.markup == Markup.SIMP_TRACE_STEP && data.memory) |
258 if (data.markup == Markup.SIMP_TRACE_STEP && data.memory) { |
268 { |
|
269 val index = Index.of_data(data) |
259 val index = Index.of_data(data) |
270 memory += (index -> answer) |
260 memory += (index -> answer) |
271 } |
261 } |
272 do_cancel(serial, id) |
262 do_cancel(serial, id) |
273 case None => |
263 case None => |
292 } |
282 } |
293 |
283 |
294 |
284 |
295 /* protocol handler */ |
285 /* protocol handler */ |
296 |
286 |
297 class Handler extends Session.Protocol_Handler |
287 class Handler extends Session.Protocol_Handler { |
298 { |
|
299 private var the_session: Session = null |
288 private var the_session: Session = null |
300 |
289 |
301 override def init(session: Session): Unit = |
290 override def init(session: Session): Unit = { |
302 { |
|
303 try { the_manager(session) } |
291 try { the_manager(session) } |
304 catch { case ERROR(_) => managers.change(map => map + (session -> make_manager)) } |
292 catch { case ERROR(_) => managers.change(map => map + (session -> make_manager)) } |
305 the_session = session |
293 the_session = session |
306 } |
294 } |
307 |
295 |
308 override def exit(): Unit = |
296 override def exit(): Unit = { |
309 { |
|
310 val session = the_session |
297 val session = the_session |
311 if (session != null) { |
298 if (session != null) { |
312 val manager = the_manager(session) |
299 val manager = the_manager(session) |
313 manager.send(Clear_Memory) |
300 manager.send(Clear_Memory) |
314 manager.shutdown() |
301 manager.shutdown() |