# HG changeset patch # User wenzelm # Date 1507657914 -7200 # Node ID 091012ac3dc27a83b4fa08ed1f2171af5c1ea8c4 # Parent c94531b5007de765021af02fa379ed6988bff84a# Parent 875fe2cb7e706bdc0eccacff8cf2c30ca5a9dccf merged diff -r c94531b5007d -r 091012ac3dc2 src/Pure/Admin/afp.scala --- a/src/Pure/Admin/afp.scala Tue Oct 10 17:15:37 2017 +0100 +++ b/src/Pure/Admin/afp.scala Tue Oct 10 19:51:54 2017 +0200 @@ -43,23 +43,34 @@ private def sessions_deps(entry: AFP.Entry): List[String] = entry.sessions.flatMap(sessions_structure.imports_graph.imm_preds(_)).distinct.sorted - val entries_graph: Graph[String, Unit] = + def dependency_graph(acyclic: Boolean): Graph[String, Unit] = { val session_entries = - (Multi_Map.empty[String, String] /: entries) { case (m1, e) => - (m1 /: e.sessions) { case (m2, s) => m2.insert(s, e.name) } + (Map.empty[String, String] /: entries) { + case (m1, e) => (m1 /: e.sessions) { case (m2, s) => m2 + (s -> e.name) } } - (Graph.empty[String, Unit] /: entries) { case (g, e1) => - val name1 = e1.name - val g1 = g.default_node(name1, ()) - (g1 /: sessions_deps(e1)) { case (g2, s2) => - (g2 /: session_entries.get_list(s2)) { case (g3, name2) => - if (name1 == name2) g3 else g3.default_node(name2, ()).add_edge(name2, name1) + (Graph.empty[String, Unit] /: entries) { case (g, entry) => + val e1 = entry.name + (g.default_node(e1, ()) /: sessions_deps(entry)) { case (g1, s) => + (g1 /: session_entries.get(s).filterNot(_ == e1)) { case (g2, e2) => + val g3 = g2.default_node(e2, ()) + if (acyclic) { + try { g3.add_edge_acyclic(e2, e1) } + catch { + case exn: Graph.Cycles[_] => + error(cat_lines(exn.cycles.map(cycle => + "Cyclic dependency of " + cycle.map(c => quote(c.toString)).mkString(" via ") + + " due to session " + quote(s)))) + } + } + else g3.add_edge(e2, e1) } } } } + val entries_graph: Graph[String, Unit] = dependency_graph(acyclic = false) + def entries_graph_display: Graph_Display.Graph = Graph_Display.make_graph(entries_graph) diff -r c94531b5007d -r 091012ac3dc2 src/Pure/General/graph.ML --- a/src/Pure/General/graph.ML Tue Oct 10 17:15:37 2017 +0100 +++ b/src/Pure/General/graph.ML Tue Oct 10 19:51:54 2017 +0200 @@ -40,6 +40,7 @@ val maximals: 'a T -> key list val is_minimal: 'a T -> key -> bool val is_maximal: 'a T -> key -> bool + val is_isolated: 'a T -> key -> bool val new_node: key * 'a -> 'a T -> 'a T (*exception DUP*) val default_node: key * 'a -> 'a T -> 'a T val del_node: key -> 'a T -> 'a T (*exception UNDEF*) @@ -177,6 +178,8 @@ fun is_minimal G x = Keys.is_empty (imm_preds G x); fun is_maximal G x = Keys.is_empty (imm_succs G x); +fun is_isolated G x = is_minimal G x andalso is_maximal G x; + (* node operations *) diff -r c94531b5007d -r 091012ac3dc2 src/Pure/General/graph.scala --- a/src/Pure/General/graph.scala Tue Oct 10 17:15:37 2017 +0100 +++ b/src/Pure/General/graph.scala Tue Oct 10 19:51:54 2017 +0200 @@ -147,6 +147,8 @@ def is_minimal(x: Key): Boolean = imm_preds(x).isEmpty def is_maximal(x: Key): Boolean = imm_succs(x).isEmpty + def is_isolated(x: Key): Boolean = is_minimal(x) && is_maximal(x) + /* node operations */ diff -r c94531b5007d -r 091012ac3dc2 src/Pure/Thy/sessions.scala --- a/src/Pure/Thy/sessions.scala Tue Oct 10 17:15:37 2017 +0100 +++ b/src/Pure/Thy/sessions.scala Tue Oct 10 19:51:54 2017 +0200 @@ -267,8 +267,7 @@ } val imports_subgraph = - sessions.imports_graph.restrict( - sessions.imports_graph.all_preds(info.parent.toList ::: info.imports).toSet) + sessions.imports_graph.restrict(sessions.imports_graph.all_preds(info.deps).toSet) val graph0 = (Graph_Display.empty_graph /: imports_subgraph.topological_order)( @@ -356,7 +355,7 @@ sealed case class Info( name: String, chapter: String, - select: Boolean, + dir_selected: Boolean, pos: Position.T, groups: List[String], dir: Path, @@ -369,6 +368,8 @@ document_files: List[(Path, Path)], meta_digest: SHA1.Digest) { + def deps: List[String] = parent.toList ::: imports + def timeout: Time = Time.seconds(options.real("timeout") * options.real("timeout_scale")) } @@ -424,7 +425,7 @@ val select = sessions.toSet ++ graph.all_succs(base_sessions) (for { (name, (info, _)) <- graph.iterator - if info.select || select(name) || graph.get_node(name).groups.exists(select_group) + if info.dir_selected || select(name) || graph.get_node(name).groups.exists(select_group) } yield name).toList } }.filterNot(excluded)