src/Tools/jEdit/src/proofdocument/prover.scala
author wenzelm
Tue, 08 Dec 2009 16:30:20 +0100
changeset 34760 dc7f5e0d9d27
parent 34759 bfea7839d9e1
child 34769 826525fc5285
permissions -rw-r--r--
misc modernization of names;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     1
/*
34501
01021d160be7 beginnings of global document state;
wenzelm
parents: 34499
diff changeset
     2
 * Higher-level prover communication: interactive document model
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     3
 *
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     4
 * @author Johannes Hölzl, TU Munich
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     5
 * @author Fabian Immler, TU Munich
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
     6
 * @author Makarius
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     7
 */
aad6834ba380 added some headers and comments;
wenzelm
parents: 34404
diff changeset
     8
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
     9
package isabelle.proofdocument
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    10
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    11
34703
ff037c17332a minor tuning;
wenzelm
parents: 34692
diff changeset
    12
import scala.actors.Actor, Actor._
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    13
34671
d179fcb04cbc output_info specific to prover
immler@in.tum.de
parents: 34660
diff changeset
    14
import javax.swing.JTextArea
34456
14367c0715e8 replaced EventSource by EventBus;
wenzelm
parents: 34454
diff changeset
    15
34501
01021d160be7 beginnings of global document state;
wenzelm
parents: 34499
diff changeset
    16
import isabelle.jedit.Isabelle
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    17
34703
ff037c17332a minor tuning;
wenzelm
parents: 34692
diff changeset
    18
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    19
class Prover(system: Isabelle_System, logic: String)
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
    20
{
34724
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    21
  /* incoming messages */
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
    22
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    23
  private var prover_ready = false
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    24
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    25
  private val receiver = new Actor {
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    26
    def act() {
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    27
      loop {
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    28
        react {
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    29
          case result: Isabelle_Process.Result => handle_result(result)
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    30
          case change: Change if prover_ready => handle_change(change)
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    31
          case bad if prover_ready => System.err.println("prover: ignoring bad message " + bad)
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    32
        }
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    33
      }
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    34
    }
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    35
  }
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    36
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    37
  def input(change: Change) { receiver ! change }
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    38
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    39
34724
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    40
  /* outgoing messages */
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
    41
34724
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    42
  val command_change = new Event_Bus[Command]
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
    43
  val document_change = new Event_Bus[Proof_Document]
34724
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    44
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    45
34504
4bd676662792 eliminated Prover.start -- part of main constructor;
wenzelm
parents: 34503
diff changeset
    46
  /* prover process */
4bd676662792 eliminated Prover.start -- part of main constructor;
wenzelm
parents: 34503
diff changeset
    47
34533
35308320713a preliminary/failed attempt to use the new IsarDocument access model to the prover;
wenzelm
parents: 34509
diff changeset
    48
  private val process =
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
    49
    new Isabelle_Process(system, receiver, "-m", "xsymbols", logic) with Isar_Document
34504
4bd676662792 eliminated Prover.start -- part of main constructor;
wenzelm
parents: 34503
diff changeset
    50
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
    51
34720
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    52
  /* outer syntax keywords and completion */
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    53
34723
wenzelm
parents: 34721
diff changeset
    54
  @volatile private var _command_decls = Map[String, String]()
wenzelm
parents: 34721
diff changeset
    55
  def command_decls() = _command_decls
wenzelm
parents: 34721
diff changeset
    56
34720
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    57
  @volatile private var _keyword_decls = Set[String]()
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    58
  def keyword_decls() = _keyword_decls
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    59
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    60
  @volatile private var _completion = Isabelle.completion
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    61
  def completion() = _completion
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    62
ac61bdd7f598 modernized Event_Bus -- based on actors;
wenzelm
parents: 34719
diff changeset
    63
34509
839d1f0b2dd1 eliminated Command.Status.REMOVE/REMOVED;
wenzelm
parents: 34505
diff changeset
    64
  /* document state information */
839d1f0b2dd1 eliminated Command.Status.REMOVE/REMOVED;
wenzelm
parents: 34505
diff changeset
    65
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    66
  @volatile private var states = Map[Isar_Document.State_ID, Command_State]()
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    67
  @volatile private var commands = Map[Isar_Document.Command_ID, Command]()
34654
30f588245884 arbitrary history
immler@in.tum.de
parents: 34653
diff changeset
    68
  val document_0 =
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
    69
    Proof_Document.empty.
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    70
    set_command_keyword((s: String) => command_decls().contains(s))
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    71
  @volatile private var document_versions = List(document_0)
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    72
34690
e588fe99cd68 modernized Isar_Document;
wenzelm
parents: 34685
diff changeset
    73
  def command(id: Isar_Document.Command_ID): Option[Command] = commands.get(id)
34760
dc7f5e0d9d27 misc modernization of names;
wenzelm
parents: 34759
diff changeset
    74
  def document(id: Isar_Document.Document_ID): Option[Proof_Document] =
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    75
    document_versions.find(_.id == id)
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
    76
34489
7b7ccf0ff629 replaced java.util.Property by plain association list;
wenzelm
parents: 34485
diff changeset
    77
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
    78
  /* prover results */
34489
7b7ccf0ff629 replaced java.util.Property by plain association list;
wenzelm
parents: 34485
diff changeset
    79
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    80
  val output_text_view = new JTextArea    // FIXME separate jEdit component
34671
d179fcb04cbc output_info specific to prover
immler@in.tum.de
parents: 34660
diff changeset
    81
34615
5e61055bf35b renamed IsabelleProcess to Isabelle_Process;
wenzelm
parents: 34612
diff changeset
    82
  private def handle_result(result: Isabelle_Process.Result)
34489
7b7ccf0ff629 replaced java.util.Property by plain association list;
wenzelm
parents: 34485
diff changeset
    83
  {
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    84
    // FIXME separate jEdit component
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    85
    Swing_Thread.later { output_text_view.append(result.toString + "\n") }
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    86
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    87
    val message = Isabelle_Process.parse_message(system, result)
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    88
34676
9e725d34df7b Command and Command_State handle results from prover as Accumulator
immler@in.tum.de
parents: 34674
diff changeset
    89
    val state =
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    90
      Position.id_of(result.props) match {
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    91
        case None => None
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    92
        case Some(id) => commands.get(id) orElse states.get(id) orElse None
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
    93
      }
34724
b1079c3ba1da Prover: keep command_change/document_change event buses here, not in ProofDocument, Command, State, Plugin;
wenzelm
parents: 34723
diff changeset
    94
    if (state.isDefined) state.get ! (this, message)
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    95
    else if (result.kind == Isabelle_Process.Kind.STATUS) {
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    96
      //{{{ global status message
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    97
      message match {
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    98
        case XML.Elem(Markup.MESSAGE, _, elems) =>
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
    99
          for (elem <- elems) {
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   100
            elem match {
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   101
              // document edits
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   102
              case XML.Elem(Markup.EDITS, (Markup.ID, doc_id) :: _, edits) =>
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   103
                document_versions.find(_.id == doc_id) match {
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   104
                  case Some(doc) =>
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   105
                    for {
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   106
                      XML.Elem(Markup.EDIT, (Markup.ID, cmd_id) :: (Markup.STATE, state_id) :: _, _)
34741
wenzelm
parents: 34740
diff changeset
   107
                      <- edits }
wenzelm
parents: 34740
diff changeset
   108
                    {
wenzelm
parents: 34740
diff changeset
   109
                      commands.get(cmd_id) match {
wenzelm
parents: 34740
diff changeset
   110
                        case Some(cmd) =>
wenzelm
parents: 34740
diff changeset
   111
                          val state = new Command_State(cmd)
wenzelm
parents: 34740
diff changeset
   112
                          states += (state_id -> state)
wenzelm
parents: 34740
diff changeset
   113
                          doc.states += (cmd -> state)
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   114
                          command_change.event(cmd)   // FIXME really!?
34741
wenzelm
parents: 34740
diff changeset
   115
                        case None =>
wenzelm
parents: 34740
diff changeset
   116
                      }
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   117
                    }
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   118
                  case None =>
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   119
                }
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   120
34741
wenzelm
parents: 34740
diff changeset
   121
              // command and keyword declarations
34740
ec35626a2aa5 misc tuning;
wenzelm
parents: 34730
diff changeset
   122
              case XML.Elem(Markup.COMMAND_DECL, (Markup.NAME, name) :: (Markup.KIND, kind) :: _, _) =>
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   123
                _command_decls += (name -> kind)
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   124
                _completion += name
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   125
              case XML.Elem(Markup.KEYWORD_DECL, (Markup.NAME, name) :: _, _) =>
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   126
                _keyword_decls += name
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   127
                _completion += name
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
   128
34741
wenzelm
parents: 34740
diff changeset
   129
              // process ready (after initialization)
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   130
              case XML.Elem(Markup.READY, _, _) => prover_ready = true
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   131
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   132
              case _ =>
34676
9e725d34df7b Command and Command_State handle results from prover as Accumulator
immler@in.tum.de
parents: 34674
diff changeset
   133
            }
34728
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   134
          }
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   135
        case _ =>
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   136
      }
e3df9c8699ea handle_result: no special treatment of outer markup (it is now properly identified by the prover);
wenzelm
parents: 34724
diff changeset
   137
      //}}}
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   138
    }
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   139
  }
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
   140
34721
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
   141
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
   142
  /* document changes */
4f3e352dde8b Prover: just one actor -- single message dispatch;
wenzelm
parents: 34720
diff changeset
   143
34729
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   144
  def begin_document(path: String) {
34650
d7ba607bf684 current version in theoryview/buffer
immler@in.tum.de
parents: 34649
diff changeset
   145
    process.begin_document(document_0.id, path)
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   146
  }
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
   147
34729
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   148
  def handle_change(change: Change) {
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   149
    val old = document(change.parent.get.id).get
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   150
    val (doc, changes) = old.text_changed(change)
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   151
    document_versions ::= doc
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   152
34709
2f0c18f9b6c7 minor tuning;
wenzelm
parents: 34703
diff changeset
   153
    val id_changes = changes map { case (c1, c2) =>
34730
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   154
        (c1.map(_.id).getOrElse(document_0.id),
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   155
         c2 match {
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   156
            case None => None
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   157
            case Some(command) =>
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   158
              commands += (command.id -> command)
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   159
              process.define_command(command.id, system.symbols.encode(command.content))
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   160
              Some(command.id)
819862460a12 tuned white space;
wenzelm
parents: 34729
diff changeset
   161
          })
34660
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents: 34654
diff changeset
   162
    }
e0561943bfc9 Change consisting of a list of Edits
immler@in.tum.de
parents: 34654
diff changeset
   163
    process.edit_document(old.id, doc.id, id_changes)
34729
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   164
5bf8f8200762 misc tuning;
wenzelm
parents: 34728
diff changeset
   165
    document_change.event(doc)
34650
d7ba607bf684 current version in theoryview/buffer
immler@in.tum.de
parents: 34649
diff changeset
   166
  }
34742
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   167
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   168
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   169
  /* main controls */
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   170
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   171
  def start() { receiver.start() }
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   172
7b8847852aae Prover: private Actor;
wenzelm
parents: 34741
diff changeset
   173
  def stop() { process.kill() }
34453
dfa99a91951b eliminated hardwired string constants;
wenzelm
parents: 34452
diff changeset
   174
}