privateval read_theory_cache = new WeakHashMap[Session.Read_Theory_Key, WeakReference[Document.Snapshot]]
def read_theory(name: String, unicode_symbols: Boolean = false): Document.Snapshot =
read_theory_cache.synchronized { val key = Session.Read_Theory_Key(name, unicode_symbols)
Option(read_theory_cache.get(key)).map(_.get) match { case Some(snapshot: Document.Snapshot) => snapshot case _ => val maybe_snapshot =
using(open_session_context()) { session_context =>
Build.read_theory(session_context.theory(name),
unicode_symbols = unicode_symbols,
migrate_file = (a: String) => session.resources.append_path("", Path.explode(a)))
}
maybe_snapshot.map(_.snippet_commands) match { case Some(List(_)) =>
read_theory_cache.put(key, new WeakReference(maybe_snapshot.get))
maybe_snapshot.get case _ => error("Failed to load theory " + quote(name) + " from session database")
}
}
}
/* global flags */
@volatile var timing: Boolean = false
@volatile var verbose: Boolean = false
/* dynamic session options */
def load_delay: Time = session_options.seconds("editor_load_delay") def input_delay: Time = session_options.seconds("editor_input_delay") def generated_input_delay: Time = session_options.seconds("editor_generated_input_delay") def output_delay: Time = session_options.seconds("editor_output_delay") def consolidate_delay: Time = session_options.seconds("editor_consolidate_delay") def prune_delay: Time = session_options.seconds("editor_prune_delay") def prune_size: Int = session_options.int("editor_prune_size") def update_delay: Time = session_options.seconds("editor_update_delay") def document_delay: Time = session_options.seconds("editor_document_delay") def chart_delay: Time = session_options.seconds("editor_chart_delay") def syslog_limit: Int = session_options.int("editor_syslog_limit") def reparse_limit: Int = session_options.int("editor_reparse_limit")
/* dispatcher */
privateval dispatcher =
Consumer_Thread.fork[() => Unit]("Session.dispatcher", daemon = true) { case e => e(); true }
def assert_dispatcher[A](body: => A): A = {
assert(dispatcher.check_thread())
body
}
def require_dispatcher[A](body: => A): A = {
require(dispatcher.check_thread(), "not on dispatcher thread")
body
}
def send_dispatcher(body: => Unit): Unit = { if (dispatcher.check_thread()) body else dispatcher.send(() => body)
}
def send_wait_dispatcher(body: => Unit): Unit = { if (dispatcher.check_thread()) body else dispatcher.send_wait(() => body)
}
/* outlets */
val finished_theories = new Session.Outlet[Document.Snapshot](dispatcher) val command_timings = new Session.Outlet[Session.Command_Timing](dispatcher) val runtime_statistics = new Session.Outlet[Session.Runtime_Statistics](dispatcher) val task_statistics = new Session.Outlet[Session.Task_Statistics](dispatcher) val global_options = new Session.Outlet[Session.Global_Options](dispatcher) val caret_focus = new Session.Outlet[Session.Caret_Focus.type](dispatcher) val raw_edits = new Session.Outlet[Session.Raw_Edits](dispatcher) val commands_changed = new Session.Outlet[Session.Commands_Changed](dispatcher) val phase_changed = new Session.Outlet[Session.Phase](dispatcher) val syslog_messages = new Session.Outlet[Prover.Output](dispatcher) val raw_output_messages = new Session.Outlet[Prover.Output](dispatcher) val trace_events = new Session.Outlet[Simplifier_Trace.Event.type](dispatcher) val debugger_updates = new Session.Outlet[Debugger.Update.type](dispatcher)
val all_messages = new Session.Outlet[Prover.Message](dispatcher) // potential bottle-neck!
privateval manager: Consumer_Thread[Any] = { /* global state */ val global_state = Synchronized(Document.State.init)
/* raw edits */
def handle_raw_edits(
doc_blobs: Document.Blobs = Document.Blobs.empty,
edits: List[Document.Edit_Text] = Nil,
consolidate: List[Document.Node.Name] = Nil): Unit = {
//{{{
require(prover.defined, "prover process not defined (handle_raw_edits)")
if (edits.nonEmpty) prover.get.discontinue_execution()
val previous = global_state.value.history.tip.version val version = Future.promise[Document.Version]
global_state.change(_.continue_history(previous, edits, version))
def handle_output(output: Prover.Output): Unit = {
//{{{ def bad_output(): Unit = { if (verbose)
Output.warning("Ignoring bad prover output: " + output.message.toString)
}
def change_command(f: Document.State => (Command.State, Document.State)): Unit = { try { val st = global_state.change_result(f) if (!st.command.span.is_theory) {
change_buffer.invoke(false, Nil, List(st.command))
}
} catch { case _: Document.State.Fail => bad_output() }
}
output match { case msg: Prover.Protocol_Output => val handled = protocol_handlers.invoke(msg) if (!handled) {
msg.properties match { case Protocol.Command_Timing(state_id, props) if prover.defined => val message = XML.elem(Markup(Markup.Command_Timing.name, props))
change_command(_.accumulate(state_id, cache.elem(message), cache))
command_timings.post(Session.Command_Timing(state_id, props))
case Markup.Task_Statistics(props) =>
task_statistics.post(Session.Task_Statistics(props))
case Protocol.Export(args) if args.id.isDefined && Value.Long.unapply(args.id.get).isDefined => val id = Value.Long.unapply(args.id.get).get val entry = Export.Entry.make(Sessions.DRAFT, args, msg.chunk, cache)
change_command(_.add_export(id, (args.serial, entry)))
case Protocol.Loading_Theory(node_name, id, commands) => val blobs_info = build_blobs_info(node_name) try {
global_state.change(_.begin_theory(node_name, id, commands, msg.text, blobs_info))
} catch { case _: Document.State.Fail => bad_output() }
case List(Markup.Commands_Accepted.THIS) =>
msg.text match { case Protocol.Commands_Accepted(ids) =>
ids.foreach(id =>
change_command(_.accumulate(id, Protocol.Commands_Accepted.message, cache))) case _ => bad_output()
}
case List(Markup.Assign_Update.THIS) =>
msg.text match { case Protocol.Assign_Update(id, edited, update) => try { val (edited_nodes, cmds) =
global_state.change_result(_.assign(id, edited, update))
change_buffer.invoke(true, edited_nodes, cmds)
manager.send(Session.Change_Flush)
} catch { case _: Document.State.Fail => bad_output() } case _ => bad_output()
}
delay_prune.invoke()
case List(Markup.Removed_Versions.THIS) =>
msg.text match { case Protocol.Removed(removed) => try {
global_state.change(_.removed_versions(removed))
manager.send(Session.Change_Flush)
} catch { case _: Document.State.Fail => bad_output() } case _ => bad_output()
}
case _ => bad_output()
}
} case _ =>
output.properties match { case Position.Id(state_id) =>
change_command(_.accumulate(state_id, output.message, cache))
case _ if output.is_init => val init_ok = try {
Isabelle_System.make_services(classOf[Session.Protocol_Handler])
.foreach(init_protocol_handler) true
} catch { case exn: Throwable =>
prover.get.protocol_command( "Prover.stop", XML.Encode.int(1), XML.string(Exn.message(exn))) false
}
if (init_ok) {
prover.get.options(prover_options(session_options))
prover.get.init_session(resources)
phase = Session.Ready
debugger.ready()
}
case Markup.Process_Result(result) if output.is_exit => val exit_state = global_state.value if (prover.defined) protocol_handlers.exit(exit_state) for (id <- exit_state.theories.keys) { val snapshot = global_state.change_result(_.end_theory(id, build_blobs))
finished_theories.post(snapshot)
}
file_formats.stop_session()
phase = Session.Terminated(result)
prover.reset()
case _ =>
raw_output_messages.post(output)
}
}
//}}}
}
/* main thread */
Consumer_Thread.fork[Any]("Session.manager", daemon = true) { case arg: Any =>
//{{{
arg match { case output: Prover.Output => if (output.is_syslog) {
syslog += XML.content(output.message)
syslog_messages.post(output)
}
if (output.is_stdout || output.is_stderr)
raw_output_messages.post(output) else handle_output(output)
all_messages.post(output)
case input: Prover.Input =>
all_messages.post(input)
case Start(start_prover) if !prover.defined =>
prover.set(start_prover(manager.send(_)))
case Stop =>
consolidation.exit()
delay_prune.revoke() if (prover.defined) {
global_state.change(_ => Document.State.init)
prover.get.terminate()
}
case Get_State(promise) =>
promise.fulfill(global_state.value)
case Consolidate_Execution => if (prover.defined) { val state = global_state.value
state.stable_tip_version match { case None => consolidation.update() case Some(version) => val consolidate =
version.nodes.descendants(consolidation.flush().toList).filter { name =>
!resources.loaded_theory(name) &&
!state.node_consolidated(version, name) &&
state.node_maybe_consolidated(version, name)
} if (consolidate.nonEmpty) handle_raw_edits(consolidate = consolidate)
}
}
case Prune_History => if (prover.defined) { val old_versions = global_state.change_result(_.remove_versions(prune_size)) if (old_versions.nonEmpty) prover.get.remove_versions(old_versions)
}
case Update_Options(options) => if (prover.defined && is_ready) {
prover.get.options(prover_options(options))
handle_raw_edits()
}
global_options.post(Session.Global_Options(options))
case Cancel_Exec(exec_id) if prover.defined =>
prover.get.cancel_exec(exec_id)
case Session.Raw_Edits(doc_blobs, edits) if prover.defined =>
handle_raw_edits(doc_blobs = doc_blobs, edits = edits)
case Session.Dialog_Result(id, serial, result) if prover.defined =>
prover.get.dialog_result(serial, result)
handle_output(new Prover.Output(Protocol.Dialog_Result(id, serial, result)))
case Protocol_Command_Raw(name, args) if prover.defined =>
prover.get.protocol_command_raw(name, args)
case Protocol_Command_Args(name, args) if prover.defined =>
prover.get.protocol_command_args(name, args)
case change: Session.Change if prover.defined => val state = global_state.value if (!state.removing_versions && state.is_assigned(change.previous))
handle_change(change) else postponed_changes.store(change)
case Session.Change_Flush if prover.defined => val state = global_state.value if (!state.removing_versions)
postponed_changes.flush(state).foreach(handle_change)
case bad => if (verbose) Output.warning("Ignoring bad message: " + bad.toString)
} true
//}}}
}
}
/* main operations */
def get_state(): Document.State = { if (manager.is_active()) { val promise = Future.promise[Document.State]
manager.send_wait(Get_State(promise))
promise.join
} else Document.State.init
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.