75907
|
1 |
/* Title: Pure/PIDE/document_info.scala
|
|
2 |
Author: Makarius
|
|
3 |
|
|
4 |
Persistent document information --- for presentation purposes.
|
|
5 |
*/
|
|
6 |
|
|
7 |
package isabelle
|
|
8 |
|
|
9 |
|
|
10 |
object Document_Info {
|
|
11 |
sealed case class Session(
|
|
12 |
name: String,
|
|
13 |
used_theories: List[String],
|
|
14 |
loaded_theories: Map[String, Theory])
|
|
15 |
|
|
16 |
object Theory {
|
|
17 |
def apply(
|
|
18 |
name: String,
|
|
19 |
files: List[String],
|
|
20 |
static_session: String,
|
|
21 |
dynamic_session: String,
|
|
22 |
entities: List[Export_Theory.Entity0],
|
|
23 |
others: List[String]
|
|
24 |
): Theory = {
|
|
25 |
val entities1 =
|
|
26 |
entities.filter(e => e.file.nonEmpty && Position.Range.unapply(e.pos).isDefined)
|
|
27 |
new Theory(name, files, static_session, dynamic_session, entities1, others)
|
|
28 |
}
|
|
29 |
}
|
|
30 |
|
|
31 |
class Theory private(
|
|
32 |
val name: String,
|
|
33 |
val files: List[String],
|
|
34 |
val static_session: String,
|
|
35 |
val dynamic_session: String,
|
|
36 |
entities: List[Export_Theory.Entity0],
|
|
37 |
others: List[String]
|
|
38 |
) {
|
|
39 |
override def toString: String = name
|
|
40 |
|
|
41 |
val (thy_file, blobs_files) =
|
|
42 |
files match {
|
|
43 |
case Nil => error("Unknown theory file for " + quote(name))
|
|
44 |
case a :: bs =>
|
|
45 |
def for_theory: String = " for theory " + quote(name)
|
|
46 |
if (!File.is_thy(a)) error("Bad .thy file " + quote(a) + for_theory)
|
|
47 |
for (b <- bs if File.is_thy(b)) error("Bad auxiliary file " + quote(b) + for_theory)
|
|
48 |
(a, bs)
|
|
49 |
}
|
|
50 |
|
|
51 |
def home_session: Boolean = static_session == dynamic_session
|
|
52 |
|
|
53 |
def print_short: String =
|
|
54 |
if (home_session) Long_Name.base_name(name) else name
|
|
55 |
|
|
56 |
def print_long: String =
|
|
57 |
"theory " + quote(name) +
|
|
58 |
(if (home_session) "" else " (session " + quote(dynamic_session) + ")")
|
|
59 |
|
|
60 |
private lazy val by_file_range: Map[(String, Symbol.Range), List[Export_Theory.Entity0]] =
|
|
61 |
entities.groupBy(entity => (entity.file, entity.range))
|
|
62 |
|
|
63 |
private lazy val by_file_kname: Map[(String, String), Export_Theory.Entity0] =
|
|
64 |
(for {
|
|
65 |
entity <- entities
|
|
66 |
file <- Position.File.unapply(entity.pos)
|
|
67 |
} yield (file, entity.kname) -> entity).toMap
|
|
68 |
|
|
69 |
def get_defs(file: String, range: Symbol.Range): List[Export_Theory.Entity0] =
|
|
70 |
by_file_range.getOrElse((file, range), Nil)
|
|
71 |
|
|
72 |
def get_def(file: String, kind: String, name: String): Option[Export_Theory.Entity0] =
|
|
73 |
by_file_kname.get((file, Export_Theory.export_kind_name(kind, name)))
|
|
74 |
|
|
75 |
def elements(elements: Presentation.Elements): Presentation.Elements =
|
|
76 |
elements.copy(entity = others.foldLeft(elements.entity)(_ + _))
|
|
77 |
}
|
|
78 |
|
|
79 |
val empty: Document_Info = new Document_Info(Map.empty)
|
|
80 |
|
|
81 |
def read(
|
|
82 |
database_context: Export.Database_Context,
|
|
83 |
deps: Sessions.Deps,
|
|
84 |
sessions: List[String]
|
|
85 |
): Document_Info = {
|
|
86 |
val sessions_domain = sessions.toSet
|
|
87 |
val sessions_structure = deps.sessions_structure
|
|
88 |
val sessions_requirements = sessions_structure.build_requirements(sessions)
|
|
89 |
|
|
90 |
def read_theory(theory_context: Export.Theory_Context): Document_Info.Theory =
|
|
91 |
{
|
|
92 |
val session_name = theory_context.session_context.session_name
|
|
93 |
val theory_name = theory_context.theory
|
|
94 |
|
|
95 |
val files = theory_context.files0(permissive = true)
|
|
96 |
|
|
97 |
val (entities, others) =
|
|
98 |
if (sessions_domain(session_name)) {
|
|
99 |
val theory = Export_Theory.read_theory(theory_context, permissive = true)
|
|
100 |
(theory.entity_iterator.toList,
|
|
101 |
theory.others.keySet.toList)
|
|
102 |
}
|
|
103 |
else (Nil, Nil)
|
|
104 |
|
|
105 |
Theory(theory_name,
|
|
106 |
static_session = sessions_structure.theory_qualifier(theory_name),
|
|
107 |
dynamic_session = session_name,
|
|
108 |
files = files,
|
|
109 |
entities = entities,
|
|
110 |
others = others)
|
|
111 |
}
|
|
112 |
|
|
113 |
def read_session(session_name: String): Document_Info.Session = {
|
|
114 |
val used_theories = deps(session_name).used_theories.map(_._1.theory)
|
|
115 |
val loaded_theories0 =
|
|
116 |
using(database_context.open_session(deps.base_info(session_name))) { session_context =>
|
|
117 |
for (theory_name <- used_theories)
|
|
118 |
yield theory_name -> read_theory(session_context.theory(theory_name))
|
|
119 |
}
|
|
120 |
Session(session_name, used_theories, loaded_theories0.toMap)
|
|
121 |
}
|
|
122 |
|
|
123 |
val result0 =
|
|
124 |
(for (session <- Par_List.map(read_session, sessions_requirements).iterator)
|
|
125 |
yield session.name -> session).toMap
|
|
126 |
|
|
127 |
val result1 =
|
|
128 |
sessions_requirements.foldLeft(Map.empty[String, Session]) {
|
|
129 |
case (seen, session_name) =>
|
|
130 |
val session0 = result0(session_name)
|
|
131 |
val loaded_theories1 =
|
|
132 |
sessions_structure(session_name).parent.map(seen) match {
|
|
133 |
case None => session0.loaded_theories
|
|
134 |
case Some(parent_session) =>
|
|
135 |
parent_session.loaded_theories ++ session0.loaded_theories
|
|
136 |
}
|
|
137 |
val session1 = session0.copy(loaded_theories = loaded_theories1)
|
|
138 |
seen + (session_name -> session1)
|
|
139 |
}
|
|
140 |
|
|
141 |
new Document_Info(result1)
|
|
142 |
}
|
|
143 |
}
|
|
144 |
|
|
145 |
class Document_Info private(sessions: Map[String, Document_Info.Session]) {
|
|
146 |
override def toString: String =
|
|
147 |
sessions.keysIterator.toList.sorted.mkString("Document_Info(", ", ", ")")
|
|
148 |
|
|
149 |
def the_session(session: String): Document_Info.Session =
|
|
150 |
sessions.getOrElse(session,
|
|
151 |
error("Unknown document information for session: " + quote(session)))
|
|
152 |
|
|
153 |
def theory_by_name(session: String, theory: String): Option[Document_Info.Theory] =
|
|
154 |
by_session_and_theory_name.get((session, theory))
|
|
155 |
|
|
156 |
def theory_by_file(session: String, file: String): Option[Document_Info.Theory] =
|
|
157 |
by_session_and_theory_file.get((session, file))
|
|
158 |
|
|
159 |
private lazy val by_session_and_theory_name: Map[(String, String), Document_Info.Theory] =
|
|
160 |
(for {
|
|
161 |
session <- sessions.valuesIterator
|
|
162 |
theory <- session.loaded_theories.valuesIterator
|
|
163 |
} yield (session.name, theory.name) -> theory).toMap
|
|
164 |
|
|
165 |
private lazy val by_session_and_theory_file: Map[(String, String), Document_Info.Theory] = {
|
|
166 |
(for {
|
|
167 |
session <- sessions.valuesIterator
|
|
168 |
theory <- session.loaded_theories.valuesIterator
|
|
169 |
file <- theory.files.iterator
|
|
170 |
} yield (session.name, file) -> theory).toMap
|
|
171 |
}
|
|
172 |
}
|