src/Pure/Thy/thy_info.scala
author wenzelm
Tue, 19 Nov 2013 12:57:56 +0100
changeset 54515 570ba266f5b5
parent 51298 ec7f10155389
child 54549 2a3053472ec3
permissions -rw-r--r--
clarified boundary cases of Document.Node.Name;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     1
/*  Title:      Pure/Thy/thy_info.scala
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     3
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     4
Theory and file dependencies.
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     5
*/
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     6
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     7
package isabelle
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     8
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
     9
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    10
import java.util.concurrent.{Future => JFuture}
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    11
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    12
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    13
class Thy_Info(thy_load: Thy_Load)
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    14
{
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    15
  /* messages */
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    16
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    17
  private def show_path(names: List[Document.Node.Name]): String =
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    18
    names.map(name => quote(name.theory)).mkString(" via ")
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    19
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    20
  private def cycle_msg(names: List[Document.Node.Name]): String =
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    21
    "Cyclic dependency of " + show_path(names)
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    22
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    23
  private def required_by(initiators: List[Document.Node.Name]): String =
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    24
    if (initiators.isEmpty) ""
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    25
    else "\n(required by " + show_path(initiators.reverse) + ")"
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    26
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    27
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    28
  /* dependencies */
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    29
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    30
  sealed case class Dep(
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    31
    name: Document.Node.Name,
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    32
    header: Document.Node.Header)
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    33
  {
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    34
    def load_files(syntax: Outer_Syntax): List[String] =
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    35
    {
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    36
      val string = thy_load.with_thy_text(name, _.toString)
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    37
      if (thy_load.body_files_test(syntax, string))
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    38
        thy_load.body_files(syntax, string)
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    39
      else Nil
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    40
    }
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    41
  }
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    42
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    43
  object Dependencies
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    44
  {
48873
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    45
    val empty = new Dependencies(Nil, Nil, Set.empty)
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    46
  }
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    47
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    48
  final class Dependencies private(
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    49
    rev_deps: List[Dep],
48873
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    50
    val keywords: Thy_Header.Keywords,
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    51
    val seen: Set[Document.Node.Name])
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    52
  {
48873
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    53
    def :: (dep: Dep): Dependencies =
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    54
      new Dependencies(dep :: rev_deps, dep.header.keywords ::: keywords, seen)
48873
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    55
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    56
    def + (name: Document.Node.Name): Dependencies =
18b17f15bc62 more direct cumulation of (sparse) keywords;
wenzelm
parents: 48872
diff changeset
    57
      new Dependencies(rev_deps, keywords, seen = seen + name)
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    58
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    59
    def deps: List[Dep] = rev_deps.reverse
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    60
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    61
    lazy val syntax: Outer_Syntax = thy_load.base_syntax.add_keywords(keywords)
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    62
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    63
    def loaded_theories: Set[String] =
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    64
      (thy_load.loaded_theories /: rev_deps) { case (loaded, dep) => loaded + dep.name.theory }
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    65
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    66
    def load_files: List[Path] =
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    67
    {
51298
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    68
      val dep_files =
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    69
        rev_deps.par.map(dep =>
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    70
          Exn.capture {
54515
570ba266f5b5 clarified boundary cases of Document.Node.Name;
wenzelm
parents: 51298
diff changeset
    71
            dep.load_files(syntax).map(a => Path.explode(dep.name.master_dir) + Path.explode(a))
51298
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    72
          }).toList
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    73
      ((Nil: List[Path]) /: dep_files) {
ec7f10155389 parallel dep.load_files saves approx. 1s on 4 cores;
wenzelm
parents: 51294
diff changeset
    74
        case (acc_files, files) => Exn.release(files) ::: acc_files
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    75
      }
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    76
    }
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    77
  }
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    78
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    79
  private def require_thys(initiators: List[Document.Node.Name],
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    80
      required: Dependencies, names: List[Document.Node.Name]): Dependencies =
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    81
    (required /: names)(require_thy(initiators, _, _))
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    82
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    83
  private def require_thy(initiators: List[Document.Node.Name],
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    84
      required: Dependencies, name: Document.Node.Name): Dependencies =
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    85
  {
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    86
    if (required.seen(name)) required
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    87
    else if (thy_load.loaded_theories(name.theory)) required + name
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    88
    else {
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    89
      def err(msg: String): Nothing =
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    90
        cat_error(msg, "The error(s) above occurred while examining theory " +
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    91
          quote(name.theory) + required_by(initiators))
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    92
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    93
      try {
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    94
        if (initiators.contains(name)) error(cycle_msg(initiators))
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    95
        val header =
50414
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    96
          try { thy_load.check_thy(name) }
e17a1f179bb0 explore theory_body_files via future, for improved performance;
wenzelm
parents: 49098
diff changeset
    97
          catch { case ERROR(msg) => err(msg) }
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
    98
        Dep(name, header) :: require_thys(name :: initiators, required + name, header.imports)
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    99
      }
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
   100
      catch {
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
   101
        case e: Throwable =>
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
   102
          Dep(name, Document.Node.bad_header(Exn.message(e))) :: (required + name)
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
   103
      }
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
   104
    }
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
   105
  }
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
   106
51294
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
   107
  def dependencies(names: List[Document.Node.Name]): Dependencies =
0850d43cb355 discontinued obsolete header "files" -- these are loaded explicitly after exploring dependencies;
wenzelm
parents: 51293
diff changeset
   108
    require_thys(Nil, Dependencies.empty, names)
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
   109
}