src/Pure/Admin/afp.scala
author wenzelm
Mon, 04 Feb 2019 14:03:31 +0100
changeset 69787 60b5a4731695
parent 69693 06153e2e0cdb
child 69973 a3e3be17dca5
permissions -rw-r--r--
clarified URL -- avoid odd certificate problem with api.media.atlassian.com;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Admin/afp.scala
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     3
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     4
Administrative support for the Archive of Formal Proofs.
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     5
*/
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     6
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     7
package isabelle
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     8
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
     9
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    10
object AFP
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    11
{
69787
60b5a4731695 clarified URL -- avoid odd certificate problem with api.media.atlassian.com;
wenzelm
parents: 69693
diff changeset
    12
  val repos_source = "https://isabelle.sketis.net/repos/afp-devel"
66854
wenzelm
parents: 66852
diff changeset
    13
69693
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    14
  val groups: Map[String, String] =
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    15
    Map("large" -> "full 64-bit memory model or word arithmetic required",
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    16
      "slow" -> "CPU time much higher than 60min (on mid-range hardware)",
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    17
      "very_slow" -> "elapsed time of many hours (on high-end hardware)")
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    18
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    19
  def groups_bulky: List[String] = List("large", "slow")
06153e2e0cdb more official AFP.groups;
wenzelm
parents: 67817
diff changeset
    20
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    21
  def init(options: Options, base_dir: Path = Path.explode("$AFP_BASE")): AFP =
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    22
    new AFP(options, base_dir)
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    23
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    24
  sealed case class Entry(name: String, sessions: List[String])
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    25
}
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    26
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    27
class AFP private(options: Options, val base_dir: Path)
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    28
{
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    29
  override def toString: String = base_dir.expand.toString
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    30
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    31
  val main_dir: Path = base_dir + Path.explode("thys")
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    32
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    33
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    34
  /* entries and sessions */
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    35
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    36
  val entries: List[AFP.Entry] =
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    37
    (for (name <- Sessions.parse_roots(main_dir + Sessions.ROOTS)) yield {
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    38
      val sessions =
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    39
        Sessions.parse_root_entries(main_dir + Path.explode(name) + Sessions.ROOT).map(_.name)
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    40
      AFP.Entry(name, sessions)
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    41
    }).sortBy(_.name)
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
    42
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    43
  val sessions: List[String] = entries.flatMap(_.sessions)
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    44
67052
caf87d4b9b61 tuned signature;
wenzelm
parents: 67026
diff changeset
    45
  val sessions_structure: Sessions.Structure =
67026
687c822ee5e3 tuned signature;
wenzelm
parents: 67025
diff changeset
    46
    Sessions.load_structure(options, dirs = List(main_dir)).
67025
961285f581e6 clarifified selection: always wrt. build_graph structure;
wenzelm
parents: 66861
diff changeset
    47
      selection(Sessions.Selection(sessions = sessions.toList))
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    48
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    49
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    50
  /* dependency graph */
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    51
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    52
  private def sessions_deps(entry: AFP.Entry): List[String] =
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    53
    entry.sessions.flatMap(sessions_structure.imports_graph.imm_preds(_)).distinct.sorted
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    54
66852
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    55
  lazy val entries_graph: Graph[String, Unit] =
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    56
  {
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    57
    val session_entries =
66831
29ea2b900a05 tuned: each session has at most one defining entry;
wenzelm
parents: 66824
diff changeset
    58
      (Map.empty[String, String] /: entries) {
29ea2b900a05 tuned: each session has at most one defining entry;
wenzelm
parents: 66824
diff changeset
    59
        case (m1, e) => (m1 /: e.sessions) { case (m2, s) => m2 + (s -> e.name) }
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    60
      }
66831
29ea2b900a05 tuned: each session has at most one defining entry;
wenzelm
parents: 66824
diff changeset
    61
    (Graph.empty[String, Unit] /: entries) { case (g, entry) =>
29ea2b900a05 tuned: each session has at most one defining entry;
wenzelm
parents: 66824
diff changeset
    62
      val e1 = entry.name
66832
875fe2cb7e70 cycle check with informative error;
wenzelm
parents: 66831
diff changeset
    63
      (g.default_node(e1, ()) /: sessions_deps(entry)) { case (g1, s) =>
875fe2cb7e70 cycle check with informative error;
wenzelm
parents: 66831
diff changeset
    64
        (g1 /: session_entries.get(s).filterNot(_ == e1)) { case (g2, e2) =>
66852
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    65
          try { g2.default_node(e2, ()).add_edge_acyclic(e2, e1) }
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    66
          catch {
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    67
            case exn: Graph.Cycles[_] =>
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    68
              error(cat_lines(exn.cycles.map(cycle =>
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    69
                "Cyclic dependency of " + cycle.map(c => quote(c.toString)).mkString(" via ") +
d20a668b394e entries_graph requires acyclic graph, but lazy val allows forming the AFP object nonetheless;
wenzelm
parents: 66832
diff changeset
    70
                " due to session " + quote(s))))
66832
875fe2cb7e70 cycle check with informative error;
wenzelm
parents: 66831
diff changeset
    71
          }
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    72
        }
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    73
      }
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    74
    }
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    75
  }
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    76
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    77
  def entries_graph_display: Graph_Display.Graph =
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    78
    Graph_Display.make_graph(entries_graph)
66823
f529719cc47d operations for graph display;
wenzelm
parents: 66821
diff changeset
    79
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    80
  def entries_json_text: String =
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    81
    (for (entry <- entries.iterator) yield {
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    82
      val distrib_deps = sessions_deps(entry).filterNot(sessions.contains(_))
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    83
      val afp_deps = entries_graph.imm_preds(entry.name).toList
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    84
      """
66821
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    85
 {""" + JSON.Format(entry.name) + """:
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    86
  {"distrib_deps": """ + JSON.Format(distrib_deps) + """,
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    87
   "afp_deps": """ + JSON.Format(afp_deps) + """
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    88
  }
c0e8c199cb2e dependencies of entries vs. sessions;
wenzelm
parents: 66820
diff changeset
    89
 }"""
66824
49a3a0a6ffaf tuned: less oo-non-sense;
wenzelm
parents: 66823
diff changeset
    90
    }).mkString("[", ", ", "\n]\n")
66861
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    91
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    92
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    93
  /* partition sessions */
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    94
67817
93faefc25fe7 clarified AFP partitioning;
wenzelm
parents: 67815
diff changeset
    95
  val force_partition1: List[String] = List("Category3", "HOL-ODE")
67776
44efac3d8638 more balanced AFP partitioning;
wenzelm
parents: 67052
diff changeset
    96
66861
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    97
  def partition(n: Int): List[String] =
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    98
    n match {
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
    99
      case 0 => Nil
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
   100
      case 1 | 2 =>
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
   101
        val graph = sessions_structure.build_graph.restrict(sessions.toSet)
67817
93faefc25fe7 clarified AFP partitioning;
wenzelm
parents: 67815
diff changeset
   102
        val force_part1 =
93faefc25fe7 clarified AFP partitioning;
wenzelm
parents: 67815
diff changeset
   103
          graph.all_preds(graph.all_succs(force_partition1.filter(graph.defined(_)))).toSet
93faefc25fe7 clarified AFP partitioning;
wenzelm
parents: 67815
diff changeset
   104
        val (part1, part2) = graph.keys.partition(a => force_part1(a) || graph.is_isolated(a))
93faefc25fe7 clarified AFP partitioning;
wenzelm
parents: 67815
diff changeset
   105
        if (n == 1) part1 else part2
66861
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
   106
      case _ => error("Bad AFP partition: " + n + " (should be 0, 1, 2)")
f6676691ef8a partition AFP sessions according to structure, which happens to cut it roughly into equal parts;
wenzelm
parents: 66854
diff changeset
   107
    }
66820
fc516da7ee4f some administrative support for AFP;
wenzelm
parents:
diff changeset
   108
}