| author | wenzelm | 
| Sun, 22 Aug 2010 13:59:47 +0200 | |
| changeset 38574 | 79cb7b4c908a | 
| parent 38572 | 0fe2c01ef7da | 
| child 38575 | 80d962964216 | 
| permissions | -rw-r--r-- | 
| 36676 | 1  | 
/* Title: Pure/PIDE/command.scala  | 
2  | 
Author: Fabian Immler, TU Munich  | 
|
3  | 
Author: Makarius  | 
|
4  | 
||
5  | 
Prover commands with semantic state.  | 
|
6  | 
*/  | 
|
| 34407 | 7  | 
|
| 
34871
 
e596a0b71f3c
incorporate "proofdocument" part into main Isabelle/Pure.jar -- except for html_panel.scala, which depends on external library (Lobo/Cobra browser);
 
wenzelm 
parents: 
34865 
diff
changeset
 | 
8  | 
package isabelle  | 
| 
34318
 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 
wenzelm 
parents:  
diff
changeset
 | 
9  | 
|
| 34451 | 10  | 
|
| 34699 | 11  | 
import scala.actors.Actor, Actor._  | 
| 34497 | 12  | 
import scala.collection.mutable  | 
| 34486 | 13  | 
|
| 34451 | 14  | 
|
| 34637 | 15  | 
object Command  | 
16  | 
{
 | 
|
| 
34707
 
cc5d388fcbf2
eliminated MarkupInfo, moved particular variants into object Command;
 
wenzelm 
parents: 
34705 
diff
changeset
 | 
17  | 
case class RefInfo(file: Option[String], line: Option[Int],  | 
| 
38363
 
af7f41a8a0a8
clarified "state" (accumulated data) vs. "exec" (execution that produces data);
 
wenzelm 
parents: 
38362 
diff
changeset
 | 
18  | 
command_id: Option[Document.Command_ID], offset: Option[Int]) // FIXME Command_ID vs. Exec_ID !?  | 
| 38361 | 19  | 
|
20  | 
||
| 38362 | 21  | 
|
| 38361 | 22  | 
/** accumulated results from prover **/  | 
23  | 
||
| 38362 | 24  | 
case class State(  | 
| 38361 | 25  | 
val command: Command,  | 
| 
38480
 
e5eed57913d0
Command.status: full XML.Tree, i.e. Markup with potential "arguments";
 
wenzelm 
parents: 
38479 
diff
changeset
 | 
26  | 
val status: List[XML.Tree],  | 
| 38361 | 27  | 
val reverse_results: List[XML.Tree],  | 
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
28  | 
val markup: Markup_Tree)  | 
| 38361 | 29  | 
  {
 | 
30  | 
/* content */  | 
|
31  | 
||
| 38362 | 32  | 
lazy val results = reverse_results.reverse  | 
| 38361 | 33  | 
|
| 38362 | 34  | 
def add_result(result: XML.Tree): State = copy(reverse_results = result :: reverse_results)  | 
| 38361 | 35  | 
|
| 38564 | 36  | 
def add_markup(node: Markup_Tree.Node[Any]): State = copy(markup = markup + node)  | 
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
37  | 
|
| 38564 | 38  | 
def markup_root_node: Markup_Tree.Node[Any] =  | 
| 
38480
 
e5eed57913d0
Command.status: full XML.Tree, i.e. Markup with potential "arguments";
 
wenzelm 
parents: 
38479 
diff
changeset
 | 
39  | 
new Markup_Tree.Node(command.range, XML.Elem(Markup(Markup.STATUS, Nil), status))  | 
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
40  | 
def markup_root: Markup_Tree = markup + markup_root_node  | 
| 38361 | 41  | 
|
42  | 
||
43  | 
/* markup */  | 
|
44  | 
||
| 38564 | 45  | 
private lazy val refs: List[Markup_Tree.Node[Any]] =  | 
| 38362 | 46  | 
      markup.filter(_.info match {
 | 
| 38361 | 47  | 
case Command.RefInfo(_, _, _, _) => true  | 
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
48  | 
case _ => false }).flatten(markup_root_node)  | 
| 38361 | 49  | 
|
| 38564 | 50  | 
def ref_at(pos: Text.Offset): Option[Markup_Tree.Node[Any]] =  | 
| 38427 | 51  | 
refs.find(_.range.contains(pos))  | 
| 38361 | 52  | 
|
53  | 
||
54  | 
/* message dispatch */  | 
|
55  | 
||
56  | 
def accumulate(message: XML.Tree): Command.State =  | 
|
57  | 
      message match {
 | 
|
| 
38480
 
e5eed57913d0
Command.status: full XML.Tree, i.e. Markup with potential "arguments";
 
wenzelm 
parents: 
38479 
diff
changeset
 | 
58  | 
case XML.Elem(Markup(Markup.STATUS, _), body) => copy(status = body ::: status)  | 
| 
38572
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
59  | 
case XML.Elem(Markup(Markup.REPORT, _), msgs) =>  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
60  | 
(this /: msgs)((state, msg) =>  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
61  | 
            msg match {
 | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
62  | 
case XML.Elem(Markup(name, atts), args)  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
63  | 
if Position.get_id(atts) == Some(command.id) && Position.get_range(atts).isDefined =>  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
64  | 
val range = command.decode_range(Position.get_range(atts).get)  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
65  | 
val props = atts.filterNot(p => Markup.POSITION_PROPERTIES(p._1))  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
66  | 
val node = Markup_Tree.Node[Any](range, XML.Elem(Markup(name, props), args))  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
67  | 
add_markup(node)  | 
| 
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
68  | 
              case _ => System.err.println("Ignored report message: " + msg); state
 | 
| 38361 | 69  | 
})  | 
70  | 
case _ => add_result(message)  | 
|
71  | 
}  | 
|
72  | 
}  | 
|
| 38367 | 73  | 
|
74  | 
||
75  | 
/* unparsed dummy commands */  | 
|
76  | 
||
77  | 
def unparsed(source: String) =  | 
|
78  | 
new Command(Document.NO_ID, List(Token(Token.Kind.UNPARSED, source)))  | 
|
| 
34318
 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 
wenzelm 
parents:  
diff
changeset
 | 
79  | 
}  | 
| 
 
c13e168a8ae6
original sources from Johannes Hölzl a48e0c6ab1aea77c52d596f7efc007a543d3d10c with minor modifications of directory layout;
 
wenzelm 
parents:  
diff
changeset
 | 
80  | 
|
| 38361 | 81  | 
|
| 34697 | 82  | 
class Command(  | 
| 
38150
 
67fc24df3721
simplified/refined document model: collection of named nodes, without proper dependencies yet;
 
wenzelm 
parents: 
37373 
diff
changeset
 | 
83  | 
val id: Document.Command_ID,  | 
| 38373 | 84  | 
val span: List[Token])  | 
| 34451 | 85  | 
{
 | 
| 34859 | 86  | 
/* classification */  | 
| 
34500
 
384427c750c8
state_results: separate buffer for messages from running command;
 
wenzelm 
parents: 
34497 
diff
changeset
 | 
87  | 
|
| 36012 | 88  | 
def is_command: Boolean = !span.isEmpty && span.head.is_command  | 
| 34865 | 89  | 
def is_ignored: Boolean = span.forall(_.is_ignored)  | 
| 34859 | 90  | 
def is_malformed: Boolean = !is_command && !is_ignored  | 
91  | 
||
| 38367 | 92  | 
def is_unparsed = id == Document.NO_ID  | 
93  | 
||
| 36012 | 94  | 
def name: String = if (is_command) span.head.content else ""  | 
| 37129 | 95  | 
override def toString =  | 
| 
37373
 
25078ba44436
tuned Command.toString -- preserving uniqueness allows the Scala toplevel to print Linear_Set[Command] results without crashing;
 
wenzelm 
parents: 
37197 
diff
changeset
 | 
96  | 
id + "/" + (if (is_command) name else if (is_ignored) "IGNORED" else "MALFORMED")  | 
| 34495 | 97  | 
|
| 34859 | 98  | 
|
99  | 
/* source text */  | 
|
| 34451 | 100  | 
|
| 34859 | 101  | 
val source: String = span.map(_.source).mkString  | 
| 38426 | 102  | 
def source(range: Text.Range): String = source.substring(range.start, range.stop)  | 
| 34859 | 103  | 
def length: Int = source.length  | 
| 
38572
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
104  | 
|
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
105  | 
val range: Text.Range = Text.Range(0, length)  | 
| 
34855
 
81d0410dc3ac
iterators for ranges of commands/starts -- avoid extra array per document;
 
wenzelm 
parents: 
34835 
diff
changeset
 | 
106  | 
|
| 34859 | 107  | 
lazy val symbol_index = new Symbol.Index(source)  | 
| 
38572
 
0fe2c01ef7da
Command.State: accumulate markup reports uniformly;
 
wenzelm 
parents: 
38564 
diff
changeset
 | 
108  | 
def decode_range(r: Text.Range): Text.Range = symbol_index.decode(r)  | 
| 
38370
 
8b15d0f98962
explicit Document.State value, instead of individual state variables in Session, Command, Document;
 
wenzelm 
parents: 
38367 
diff
changeset
 | 
109  | 
|
| 
 
8b15d0f98962
explicit Document.State value, instead of individual state variables in Session, Command, Document;
 
wenzelm 
parents: 
38367 
diff
changeset
 | 
110  | 
|
| 
 
8b15d0f98962
explicit Document.State value, instead of individual state variables in Session, Command, Document;
 
wenzelm 
parents: 
38367 
diff
changeset
 | 
111  | 
/* accumulated results */  | 
| 
 
8b15d0f98962
explicit Document.State value, instead of individual state variables in Session, Command, Document;
 
wenzelm 
parents: 
38367 
diff
changeset
 | 
112  | 
|
| 
38479
 
e628da370072
more efficient Markup_Tree, based on branches sorted by quasi-order;
 
wenzelm 
parents: 
38476 
diff
changeset
 | 
113  | 
val empty_state: Command.State = Command.State(this, Nil, Nil, Markup_Tree.empty)  | 
| 
34676
 
9e725d34df7b
Command and Command_State handle results from prover as Accumulator
 
immler@in.tum.de 
parents: 
34675 
diff
changeset
 | 
114  | 
}  |