src/Tools/jEdit/src/proofdocument/ProofDocument.scala
author immler@in.tum.de
Wed, 08 Jul 2009 13:29:42 +0200
changeset 34648 8213a350fd45
parent 34603 83a37e3b8c9c
child 34649 70759ca6bb87
permissions -rw-r--r--
remember removed text
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
diff changeset
     1
/*
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
     2
 * Document as list of commands, consisting of lists of tokens
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
diff changeset
     3
 *
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
diff changeset
     4
 * @author Johannes Hölzl, TU Munich
34532
aaafe9c4180b ProofDocument without state
immler@in.tum.de
parents: 34531
diff changeset
     5
 * @author Fabian Immler, TU Munich
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
     6
 * @author Makarius
34407
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
diff changeset
     7
 */
aad6834ba380 added some headers and comments;
wenzelm
parents: 34390
diff changeset
     8
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
     9
package isabelle.proofdocument
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    10
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
    11
import scala.collection.mutable.ListBuffer
34532
aaafe9c4180b ProofDocument without state
immler@in.tum.de
parents: 34531
diff changeset
    12
import scala.actors.Actor
aaafe9c4180b ProofDocument without state
immler@in.tum.de
parents: 34531
diff changeset
    13
import scala.actors.Actor._
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    14
import java.util.regex.Pattern
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    15
import isabelle.prover.{Prover, Command}
34531
db1c28e326fc *very* superficial usage of LinearSet
immler@in.tum.de
parents: 34526
diff changeset
    16
import isabelle.utils.LinearSet
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    17
34494
47f9303db81d misc tuning -- de-camelization;
wenzelm
parents: 34491
diff changeset
    18
case class StructureChange(
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
    19
  val before_change: Option[Command],
34494
47f9303db81d misc tuning -- de-camelization;
wenzelm
parents: 34491
diff changeset
    20
  val added_commands: List[Command],
47f9303db81d misc tuning -- de-camelization;
wenzelm
parents: 34491
diff changeset
    21
  val removed_commands: List[Command])
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    22
34483
0923926022d7 superficial tuning;
wenzelm
parents: 34482
diff changeset
    23
object ProofDocument
0923926022d7 superficial tuning;
wenzelm
parents: 34482
diff changeset
    24
{
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    25
  // Be careful when changing this regex. Not only must it handle the
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    26
  // spurious end of a token but also:  
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    27
  // Bug ID: 5050507 Pattern.matches throws StackOverflow Error
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    28
  // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    29
  
34483
0923926022d7 superficial tuning;
wenzelm
parents: 34482
diff changeset
    30
  val token_pattern = 
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    31
    Pattern.compile(
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    32
      "\\{\\*([^*]|\\*[^}]|\\*\\z)*(\\z|\\*\\})|" +
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    33
      "\\(\\*([^*]|\\*[^)]|\\*\\z)*(\\z|\\*\\))|" +
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    34
      "(\\?'?|')[A-Za-z_0-9.]*|" + 
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    35
      "[A-Za-z_0-9.]+|" + 
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    36
      "[!#$%&*+-/<=>?@^_|~]+|" +
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    37
      "\"([^\\\\\"]?(\\\\(.|\\z))?)*+(\"|\\z)|" +
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    38
      "`([^\\\\`]?(\\\\(.|\\z))?)*+(`|\\z)|" +
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    39
      "[()\\[\\]{}:;]", Pattern.MULTILINE)
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    40
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
    41
 val empty =
34603
83a37e3b8c9c produce ids via Isabelle.system (http://isabelle.in.tum.de/repos/isabelle/rev/c23663825e23);
wenzelm
parents: 34597
diff changeset
    42
  new ProofDocument(isabelle.jedit.Isabelle.system.id(),
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    43
    LinearSet(), Map(), LinearSet(), false, _ => false)
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    44
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    45
}
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
    46
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    47
class ProofDocument(
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    48
  val id: String,
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    49
  val tokens: LinearSet[Token],
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    50
  val token_start: Map[Token, Int],
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    51
  val commands: LinearSet[Command],
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    52
  val active: Boolean,
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    53
  is_command_keyword: String => Boolean)
34483
0923926022d7 superficial tuning;
wenzelm
parents: 34482
diff changeset
    54
{
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    55
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
    56
  def mark_active: ProofDocument =
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    57
    new ProofDocument(id, tokens, token_start, commands, true, is_command_keyword)
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    58
  def activate: (ProofDocument, StructureChange) = {
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
    59
    val (doc, change) =
34648
8213a350fd45 remember removed text
immler@in.tum.de
parents: 34603
diff changeset
    60
      text_changed(new Text.Change(isabelle.jedit.Isabelle.system.id(), 0, content, content))
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    61
    return (doc.mark_active, change)
34456
14367c0715e8 replaced EventSource by EventBus;
wenzelm
parents: 34408
diff changeset
    62
  }
34532
aaafe9c4180b ProofDocument without state
immler@in.tum.de
parents: 34531
diff changeset
    63
  def set_command_keyword(f: String => Boolean): ProofDocument =
34603
83a37e3b8c9c produce ids via Isabelle.system (http://isabelle.in.tum.de/repos/isabelle/rev/c23663825e23);
wenzelm
parents: 34597
diff changeset
    64
    new ProofDocument(isabelle.jedit.Isabelle.system.id(), tokens, token_start, commands, active, f)
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    65
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    66
  def content = Token.string_from_tokens(Nil ++ tokens, token_start)
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    67
  /** token view **/
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    68
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
    69
  def text_changed(change: Text.Change): (ProofDocument, StructureChange) =
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    70
  {
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    71
    //indices of tokens
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    72
    var start: Map[Token, Int] = token_start
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    73
    def stop(t: Token) = start(t) + t.length
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    74
    // split old token lists
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    75
    val tokens = Nil ++ this.tokens
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    76
    val (begin, remaining) = tokens.span(stop(_) < change.start)
34648
8213a350fd45 remember removed text
immler@in.tum.de
parents: 34603
diff changeset
    77
    val (removed, end) = remaining.span(token_start(_) <= change.start + change.removed.length)
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    78
    // update indices
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    79
    start = end.foldLeft(start)((s, t) =>
34648
8213a350fd45 remember removed text
immler@in.tum.de
parents: 34603
diff changeset
    80
      s + (t -> (s(t) + change.added.length - change.removed.length)))
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
    81
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    82
    val split_begin = removed.takeWhile(start(_) < change.start).
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    83
      map (t => {
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    84
          val split_tok = new Token(t.content.substring(0, change.start - start(t)), t.kind)
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    85
          start += (split_tok -> start(t))
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    86
          split_tok
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    87
        })
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    88
34648
8213a350fd45 remember removed text
immler@in.tum.de
parents: 34603
diff changeset
    89
    val split_end = removed.dropWhile(stop(_) < change.start + change.removed.length).
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    90
      map (t => {
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
    91
          val split_tok =
34648
8213a350fd45 remember removed text
immler@in.tum.de
parents: 34603
diff changeset
    92
            new Token(t.content.substring(change.start + change.removed.length - start(t)), t.kind)
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    93
          start += (split_tok -> start(t))
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    94
          split_tok
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    95
        })
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
    96
    // update indices
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    97
    start = removed.foldLeft (start) ((s, t) => s - t)
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    98
    start = split_end.foldLeft (start) ((s, t) =>
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
    99
    s + (t -> (change.start + change.added.length)))
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   100
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   101
    val ins = new Token(change.added, Token.Kind.OTHER)
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   102
    start += (ins -> change.start)
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   103
    
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   104
    var invalid_tokens = split_begin ::: ins :: split_end ::: end
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   105
    var new_tokens: List[Token] = Nil
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   106
    var old_suffix: List[Token] = Nil
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   107
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   108
    val match_start = invalid_tokens.firstOption.map(start(_)).getOrElse(0)
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   109
    val matcher =
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   110
      ProofDocument.token_pattern.matcher(Token.string_from_tokens(invalid_tokens, start))
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   111
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   112
    while (matcher.find() && invalid_tokens != Nil) {
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   113
			val kind =
34505
87f4f70d61bb ProofDocument: pass is_command_keyword directly, not via full-blown Prover object;
wenzelm
parents: 34496
diff changeset
   114
        if (is_command_keyword(matcher.group))
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   115
          Token.Kind.COMMAND_START
34494
47f9303db81d misc tuning -- de-camelization;
wenzelm
parents: 34491
diff changeset
   116
        else if (matcher.end - matcher.start > 2 && matcher.group.substring(0, 2) == "(*")
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   117
          Token.Kind.COMMENT
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   118
        else
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   119
          Token.Kind.OTHER
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   120
      val new_token = new Token(matcher.group, kind)
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   121
      start += (new_token -> (match_start + matcher.start))
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   122
      new_tokens ::= new_token
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   123
34551
bd2b8fde9e25 incomplete changes of immutable tokens and commands
immler@in.tum.de
parents: 34550
diff changeset
   124
      invalid_tokens = invalid_tokens dropWhile (stop(_) < stop(new_token))
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   125
      invalid_tokens match {
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   126
        case t :: ts =>
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   127
          if (start(t) == start(new_token) &&
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   128
              start(t) > change.start + change.added.length) {
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   129
          old_suffix = t :: ts
34592
b17ebec3690c ignore unchanged tokens
immler@in.tum.de
parents: 34575
diff changeset
   130
          new_tokens = new_tokens.tail
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   131
          invalid_tokens = Nil
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   132
        }
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   133
        case _ =>
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   134
      }
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   135
    }
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   136
    val insert = new_tokens.reverse
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
   137
    val new_token_list = begin ::: insert ::: old_suffix
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   138
    token_changed(change.id, begin.lastOption, insert,
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   139
      old_suffix.firstOption, new_token_list, start)
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   140
  }
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   141
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   142
  
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   143
  /** command view **/
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   144
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   145
  private def token_changed(
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   146
    new_id: String,
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   147
    before_change: Option[Token],
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   148
    inserted_tokens: List[Token],
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   149
    after_change: Option[Token],
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   150
    new_tokens: List[Token],
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   151
    new_token_start: Map[Token, Int]): (ProofDocument, StructureChange) =
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   152
  {
34595
0e0e08aaddb5 lists work faster here
immler@in.tum.de
parents: 34594
diff changeset
   153
    val new_tokenset = (LinearSet() ++ new_tokens).asInstanceOf[LinearSet[Token]]
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   154
    val cmd_before_change = before_change match {
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   155
      case None => None
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   156
      case Some(bc) =>
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   157
        val cmd_with_bc = commands.find(_.contains(bc)).get
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   158
        if (cmd_with_bc.tokens.last == bc) {
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   159
          if (new_tokenset.next(bc).map(_.is_start).getOrElse(true))
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   160
            Some(cmd_with_bc)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   161
          else commands.prev(cmd_with_bc)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   162
        }
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   163
        else commands.prev(cmd_with_bc)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   164
    }
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
   165
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   166
    val cmd_after_change = after_change match {
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   167
      case None => None
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   168
      case Some(ac) =>
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   169
        val cmd_with_ac = commands.find(_.contains(ac)).get
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   170
        if (ac.is_start)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   171
          Some(cmd_with_ac)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   172
        else
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   173
          commands.next(cmd_with_ac)
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   174
    }
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   175
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   176
    val removed_commands = commands.dropWhile(Some(_) != cmd_before_change).drop(1).
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   177
      takeWhile(Some(_) != cmd_after_change)
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   178
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   179
    // calculate inserted commands
34526
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   180
    def tokens_to_commands(tokens: List[Token]): List[Command]= {
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   181
      tokens match {
b504abb6eff6 tokens and commands as lists
immler@in.tum.de
parents: 34516
diff changeset
   182
        case Nil => Nil
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   183
        case t :: ts =>
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   184
          val (cmd, rest) =
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   185
            ts.span(t => t.kind != Token.Kind.COMMAND_START && t.kind != Token.Kind.COMMENT)
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   186
          new Command(t :: cmd, new_token_start) :: tokens_to_commands(rest)
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   187
      }
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   188
    }
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   189
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   190
    val split_begin =
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   191
      if (before_change.isDefined) {
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   192
        val changed =
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   193
          if (cmd_before_change.isDefined)
34595
0e0e08aaddb5 lists work faster here
immler@in.tum.de
parents: 34594
diff changeset
   194
            new_tokens.dropWhile(_ != cmd_before_change.get.tokens.last).drop(1)
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   195
          else new_tokenset
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   196
        if (changed.exists(_ == before_change.get))
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   197
          changed.takeWhile(_ != before_change.get).toList :::
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   198
            List(before_change.get)
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   199
        else Nil
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   200
      } else Nil
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   201
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   202
    val split_end =
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   203
      if (after_change.isDefined && cmd_after_change.isDefined) {
34595
0e0e08aaddb5 lists work faster here
immler@in.tum.de
parents: 34594
diff changeset
   204
        val unchanged = new_tokens.dropWhile(_ != after_change.get)
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   205
        if (unchanged.exists(_ == cmd_after_change.get.tokens.first))
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   206
          unchanged.takeWhile(_ != cmd_after_change.get.tokens.first).toList
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   207
        else Nil
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   208
      } else Nil
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   209
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   210
    val rescan_begin =
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   211
      split_begin :::
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   212
        before_change.map(bc => new_tokens.dropWhile(_ != bc).drop(1)).getOrElse(new_tokens)
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   213
    val rescanning_tokens =
34597
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   214
      after_change.map(ac => rescan_begin.takeWhile(_ != ac)).getOrElse(rescan_begin) :::
a0c84b0edb9a merged; resolved superficial conflicts
immler@in.tum.de
parents: 34582 34596
diff changeset
   215
        split_end
34593
cf37a9f988bf ignore unchanged commands
immler@in.tum.de
parents: 34592
diff changeset
   216
    val inserted_commands = tokens_to_commands(rescanning_tokens.toList)
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   217
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   218
    val change = new StructureChange(cmd_before_change, inserted_commands, removed_commands.toList)
34550
171c8c6e5707 prepared proofdocument for only needed changes
immler@in.tum.de
parents: 34544
diff changeset
   219
    // build new document
34554
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   220
    val new_commandset = commands.delete_between(cmd_before_change, cmd_after_change).
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   221
        insert_after(cmd_before_change, inserted_commands)
7dc6c231da40 abs. stops, markup nodes depend on doc-version;
immler@in.tum.de
parents: 34551
diff changeset
   222
34544
56217d219e27 proofdocument-versions get id from changes
immler@in.tum.de
parents: 34541
diff changeset
   223
    val doc =
34582
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   224
      new ProofDocument(new_id, new_tokenset, new_token_start,
5d5d253c7c29 superficial tuning;
wenzelm
parents: 34575
diff changeset
   225
        new_commandset, active, is_command_keyword)
34538
20bfcca24658 Prover as actor managing ProofDocument-versions (removed EventBus structural_changes);
immler@in.tum.de
parents: 34532
diff changeset
   226
    return (doc, change)
34485
6475bfb4ff99 joined Document with ProofDocument;
wenzelm
parents: 34483
diff changeset
   227
  }
34596
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   228
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   229
  val commands_offsets = {
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   230
    var last_stop = 0
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   231
    (for (c <- commands) yield {
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   232
      val r = c -> (last_stop,c.stop(this))
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   233
      last_stop = c.stop(this)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   234
      r
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   235
    }).toArray
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   236
  }
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   237
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   238
  // use a binary search to find commands for a given offset
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   239
  def find_command_at(pos: Int): Command = find_command_at(pos, 0, commands_offsets.length)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   240
  private def find_command_at(pos: Int, array_start: Int, array_stop: Int): Command = {
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   241
    val middle_index = (array_start + array_stop) / 2
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   242
    if (middle_index >= commands_offsets.length) return null
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   243
    val (middle, (start, stop)) = commands_offsets(middle_index)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   244
    // does middle contain pos?
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   245
    if (start <= pos && stop > pos)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   246
      middle
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   247
    else if (start > pos)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   248
      find_command_at(pos, array_start, middle_index)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   249
    else if (stop <= pos)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   250
      find_command_at(pos, middle_index + 1, array_stop)
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   251
    else error("can't be")
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   252
  }
2b46d92e4642 linearset works faster here
immler@in.tum.de
parents: 34595
diff changeset
   253
34318
c13e168a8ae6 original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
wenzelm
parents:
diff changeset
   254
}