src/Pure/Tools/simplifier_trace.scala
changeset 75393 87ebf5a50283
parent 74253 45dc9de1bd33
child 75394 42267c650205
equal deleted inserted replaced
75388:b3ca4a6ed74b 75393:87ebf5a50283
     9 
     9 
    10 import scala.annotation.tailrec
    10 import scala.annotation.tailrec
    11 import scala.collection.immutable.SortedMap
    11 import scala.collection.immutable.SortedMap
    12 
    12 
    13 
    13 
    14 object Simplifier_Trace
    14 object Simplifier_Trace {
    15 {
       
    16   /* trace items from the prover */
    15   /* trace items from the prover */
    17 
    16 
    18   val TEXT = "text"
    17   val TEXT = "text"
    19   val Text = new Properties.String(TEXT)
    18   val Text = new Properties.String(TEXT)
    20 
    19 
    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()