| author | wenzelm | 
| Wed, 02 Oct 2024 23:47:07 +0200 | |
| changeset 81107 | ad5fc948e053 | 
| parent 80463 | 3490a9c96d2f | 
| permissions | -rw-r--r-- | 
| 59244 | 1 | /* Title: Pure/General/graph_display.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 4 | Support for graph display. | |
| 5 | */ | |
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 75393 | 9 | object Graph_Display {
 | 
| 59244 | 10 | /* graph entries */ | 
| 11 | ||
| 59440 | 12 | type Entry = ((String, (String, XML.Body)), List[String]) // ident, name, content, parents | 
| 59244 | 13 | |
| 14 | ||
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 15 | /* graph structure */ | 
| 59244 | 16 | |
| 75393 | 17 |   object Node {
 | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 18 |     val dummy: Node = Node("", "")
 | 
| 59244 | 19 | |
| 75393 | 20 |     object Ordering extends scala.math.Ordering[Node] {
 | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 21 | def compare(node1: Node, node2: Node): Int = | 
| 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 22 |         node1.name compare node2.name match {
 | 
| 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 23 | case 0 => node1.ident compare node2.ident | 
| 59244 | 24 | case ord => ord | 
| 25 | } | |
| 26 | } | |
| 27 | } | |
| 75393 | 28 |   sealed case class Node(name: String, ident: String) {
 | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 29 | def is_dummy: Boolean = this == Node.dummy | 
| 59244 | 30 | override def toString: String = name | 
| 31 | } | |
| 32 | ||
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 33 | type Edge = (Node, Node) | 
| 59244 | 34 | |
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 35 | type Graph = isabelle.Graph[Node, XML.Body] | 
| 59244 | 36 | |
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 37 | val empty_graph: Graph = isabelle.Graph.empty(Node.Ordering) | 
| 59244 | 38 | |
| 75393 | 39 |   def build_graph(entries: List[Entry]): Graph = {
 | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 40 | val node = | 
| 73359 | 41 |       entries.foldLeft(Map.empty[String, Node]) {
 | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 42 | case (m, ((ident, (name, _)), _)) => m + (ident -> Node(name, ident)) | 
| 59244 | 43 | } | 
| 73359 | 44 | entries.foldLeft( | 
| 45 |       entries.foldLeft(empty_graph) {
 | |
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 46 | case (g, ((ident, (_, content)), _)) => g.new_node(node(ident), content) | 
| 73359 | 47 |       }) {
 | 
| 59244 | 48 | case (g1, ((ident, _), parents)) => | 
| 73359 | 49 |           parents.foldLeft(g1) { case (g2, parent) => g2.add_edge(node(parent), node(ident)) }
 | 
| 59244 | 50 | } | 
| 51 | } | |
| 52 | ||
| 53 | def decode_graph(body: XML.Body): Graph = | |
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 54 | build_graph( | 
| 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 55 |       {
 | 
| 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 56 | import XML.Decode._ | 
| 80463 | 57 | list(pair(pair(string, pair(string, self)), list(string)))(body) | 
| 59245 
be4180f3c236
more formal Graph_Display.Node (with ordering) and Graph_Display.Edge;
 wenzelm parents: 
59244diff
changeset | 58 | }) | 
| 66823 | 59 | |
| 60 | def make_graph[A]( | |
| 61 | graph: isabelle.Graph[String, A], | |
| 66834 | 62 | isolated: Boolean = false, | 
| 75393 | 63 | name: (String, A) => String = (x: String, a: A) => x | 
| 64 |   ): Graph = {
 | |
| 66823 | 65 | val entries = | 
| 66834 | 66 |       (for { (x, (a, (ps, _))) <- graph.iterator if isolated || !graph.is_isolated(x) }
 | 
| 67 | yield ((x, (name(x, a), Nil)), ps.toList)).toList | |
| 66823 | 68 | build_graph(entries) | 
| 69 | } | |
| 59244 | 70 | } |