src/Pure/Thy/thy_info.scala
author wenzelm
Tue, 21 Aug 2012 14:54:29 +0200
changeset 48872 6124e0d1120a
parent 48871 c82720f054c3
child 48873 18b17f15bc62
permissions -rw-r--r--
some support for thy_load_commands; clarified signatures;
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
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    10
class Thy_Info(thy_load: Thy_Load)
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    11
{
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    12
  /* messages */
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    13
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    14
  private def show_path(names: List[Document.Node.Name]): String =
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    15
    names.map(name => quote(name.theory)).mkString(" via ")
43651
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 cycle_msg(names: List[Document.Node.Name]): String =
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    18
    "Cyclic dependency of " + show_path(names)
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 required_by(initiators: List[Document.Node.Name]): String =
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    21
    if (initiators.isEmpty) ""
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    22
    else "\n(required by " + show_path(initiators.reverse) + ")"
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    23
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    24
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    25
  /* dependencies */
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    26
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
    27
  type Dep = (Document.Node.Name, Document.Node.Header)
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    28
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    29
  object Dependencies
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    30
  {
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    31
    val empty = new Dependencies(Nil, Set.empty)
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    32
  }
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    33
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    34
  final class Dependencies private(
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    35
    rev_deps: List[Dep],
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    36
    val seen: Set[Document.Node.Name])
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    37
  {
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    38
    def :: (dep: Dep): Dependencies = new Dependencies(dep :: rev_deps, seen)
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    39
    def + (name: Document.Node.Name): Dependencies = new Dependencies(rev_deps, seen = seen + name)
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    40
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    41
    def deps: List[Dep] = rev_deps.reverse
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
    def thy_load_commands: List[String] =
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    44
      (for ((_, h) <- rev_deps; (cmd, Some(((Keyword.THY_LOAD, _), _))) <- h.keywords) yield cmd) :::
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    45
        thy_load.base_syntax.thy_load_commands
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
    def loaded_theories: Set[String] =
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    48
      (thy_load.loaded_theories /: rev_deps) { case (loaded, (name, _)) => loaded + name.theory }
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    49
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    50
    def syntax: Outer_Syntax =
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    51
      (thy_load.base_syntax /: rev_deps) { case (syn, (name, h)) =>
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    52
        val syn1 = syn.add_keywords(h)
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    53
        // FIXME avoid hardwired stuff!?
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    54
        // FIXME broken?!
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    55
        if (name.theory == "Pure")
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    56
          syn1 +
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    57
            ("hence", (Keyword.PRF_ASM_GOAL, Nil), "then have") +
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    58
            ("thus", (Keyword.PRF_ASM_GOAL, Nil), "then show")
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    59
        else syn1
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    60
      }
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    61
  }
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    62
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    63
  private def require_thys(initiators: List[Document.Node.Name],
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    64
      required: Dependencies, names: List[Document.Node.Name]): Dependencies =
44954
b536b1144eb3 more careful traversal of theory dependencies to retain standard import order;
wenzelm
parents: 44616
diff changeset
    65
    (required /: names)(require_thy(initiators, _, _))
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    66
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    67
  private def require_thy(initiators: List[Document.Node.Name],
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    68
      required: Dependencies, name: Document.Node.Name): Dependencies =
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    69
  {
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    70
    if (required.seen(name)) required
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    71
    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
    72
    else {
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    73
      try {
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    74
        if (initiators.contains(name)) error(cycle_msg(initiators))
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
    75
        val header =
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    76
          try { thy_load.check_thy(name) }
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    77
          catch {
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    78
            case ERROR(msg) =>
44615
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    79
              cat_error(msg, "The error(s) above occurred while examining theory " +
a4ff8a787202 more abstract Document.Node.Name;
wenzelm
parents: 44574
diff changeset
    80
                quote(name.theory) + required_by(initiators))
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    81
          }
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    82
        (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
    83
      }
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
    84
      catch {
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
    85
        case e: Throwable =>
48871
c82720f054c3 tuned signature;
wenzelm
parents: 48870
diff changeset
    86
          (name, Document.Node.bad_header(Exn.message(e))) :: (required + name)
48707
ba531af91148 simplified Document.Node.Header -- internalized errors;
wenzelm
parents: 46737
diff changeset
    87
      }
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    88
    }
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    89
  }
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    90
48872
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    91
  def dependencies(names: List[Document.Node.Name]): Dependencies =
6124e0d1120a some support for thy_load_commands;
wenzelm
parents: 48871
diff changeset
    92
    require_thys(Nil, Dependencies.empty, names)
43651
511df47bcadc some support for theory files within Isabelle/Scala session;
wenzelm
parents:
diff changeset
    93
}