merged
authorblanchet
Fri, 06 Mar 2009 15:31:26 +0100
changeset 30310 0c1d6621bb19
parent 30300 aa44d67eea16 (diff)
parent 30309 188f0658af9f (current diff)
child 30311 66a57e4f043e
merged
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Admin/Mercurial/cvsids	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,5 @@
+Identifiers of some old CVS file versions
+=========================================
+
+src/Pure/type.ML    1.65        0d984ee030a1
+
--- a/Admin/makedist	Fri Mar 06 15:31:07 2009 +0100
+++ b/Admin/makedist	Fri Mar 06 15:31:26 2009 +0100
@@ -144,7 +144,7 @@
 echo "###"
 
 find . -name .cvsignore -print | xargs rm -rf
-find . "(" -name \*.thy -o -name \*.ML ")" -perm +111 -print | xargs chmod -x
+find . "(" -name \*.thy -o -name \*.ML ")" -perm +111 -print | xargs chmod -f -x
 find . -print | xargs chmod u+rw
 
 ./Admin/build all || fail "Failed to build distribution"
--- a/NEWS	Fri Mar 06 15:31:07 2009 +0100
+++ b/NEWS	Fri Mar 06 15:31:26 2009 +0100
@@ -220,6 +220,10 @@
 
 *** HOL ***
 
+* New predicate "strict_mono" classifies strict functions on partial orders.
+With strict functions on linear orders, reasoning about (in)equalities is
+facilitated by theorems "strict_mono_eq", "strict_mono_less_eq" and "strict_mono_less".
+
 * Auxiliary class "itself" has disappeared -- classes without any parameter
 are treated as expected by the 'class' command.
 
--- a/doc-src/IsarImplementation/Makefile	Fri Mar 06 15:31:07 2009 +0100
+++ b/doc-src/IsarImplementation/Makefile	Fri Mar 06 15:31:26 2009 +0100
@@ -12,10 +12,11 @@
 
 FILES = ../extra.sty ../iman.sty ../isabelle.sty ../isabellesym.sty	\
   ../isar.sty ../manual.bib ../pdfsetup.sty ../proof.sty		\
-  Thy/document/Integration.tex Thy/document/Local_Theory.tex		\
-  Thy/document/Logic.tex Thy/document/Prelim.tex			\
-  Thy/document/Proof.tex Thy/document/Syntax.tex			\
-  Thy/document/Tactic.tex implementation.tex style.sty
+  Thy/document/Integration.tex Thy/document/Isar.tex			\
+  Thy/document/Local_Theory.tex Thy/document/Logic.tex			\
+  Thy/document/Prelim.tex Thy/document/Proof.tex			\
+  Thy/document/Syntax.tex Thy/document/Tactic.tex implementation.tex	\
+  style.sty
 
 dvi: $(NAME).dvi
 
--- a/doc-src/IsarImplementation/Thy/Logic.thy	Fri Mar 06 15:31:07 2009 +0100
+++ b/doc-src/IsarImplementation/Thy/Logic.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -556,7 +556,7 @@
   @{index_ML Thm.generalize: "string list * string list -> int -> thm -> thm"} \\
   @{index_ML Thm.instantiate: "(ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm"} \\
   @{index_ML Thm.axiom: "theory -> string -> thm"} \\
-  @{index_ML Thm.add_oracle: "bstring * ('a -> cterm) -> theory
+  @{index_ML Thm.add_oracle: "binding * ('a -> cterm) -> theory
   -> (string * ('a -> thm)) * theory"} \\
   \end{mldecls}
   \begin{mldecls}
@@ -613,7 +613,7 @@
   \item @{ML Thm.axiom}~@{text "thy name"} retrieves a named
   axiom, cf.\ @{text "axiom"} in \figref{fig:prim-rules}.
 
-  \item @{ML Thm.add_oracle}~@{text "(name, oracle)"} produces a named
+  \item @{ML Thm.add_oracle}~@{text "(binding, oracle)"} produces a named
   oracle rule, essentially generating arbitrary axioms on the fly,
   cf.\ @{text "axiom"} in \figref{fig:prim-rules}.
 
--- a/doc-src/IsarImplementation/Thy/Prelim.thy	Fri Mar 06 15:31:07 2009 +0100
+++ b/doc-src/IsarImplementation/Thy/Prelim.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -682,7 +682,7 @@
 
 text %mlref {*
   \begin{mldecls}
-  @{index_ML NameSpace.base: "string -> string"} \\
+  @{index_ML NameSpace.base_name: "string -> string"} \\
   @{index_ML NameSpace.qualifier: "string -> string"} \\
   @{index_ML NameSpace.append: "string -> string -> string"} \\
   @{index_ML NameSpace.implode: "string list -> string"} \\
@@ -698,14 +698,15 @@
   @{index_ML_type NameSpace.T} \\
   @{index_ML NameSpace.empty: NameSpace.T} \\
   @{index_ML NameSpace.merge: "NameSpace.T * NameSpace.T -> NameSpace.T"} \\
-  @{index_ML NameSpace.declare: "NameSpace.naming -> binding -> NameSpace.T -> string * NameSpace.T"} \\
+  @{index_ML NameSpace.declare: "NameSpace.naming -> binding -> NameSpace.T ->
+  string * NameSpace.T"} \\
   @{index_ML NameSpace.intern: "NameSpace.T -> string -> string"} \\
   @{index_ML NameSpace.extern: "NameSpace.T -> string -> string"} \\
   \end{mldecls}
 
   \begin{description}
 
-  \item @{ML NameSpace.base}~@{text "name"} returns the base name of a
+  \item @{ML NameSpace.base_name}~@{text "name"} returns the base name of a
   qualified name.
 
   \item @{ML NameSpace.qualifier}~@{text "name"} returns the qualifier
@@ -728,8 +729,8 @@
   \item @{ML NameSpace.add_path}~@{text "path naming"} augments the
   naming policy by extending its path component.
 
-  \item @{ML NameSpace.full_name}@{text "naming binding"} turns a name
-  binding (usually a basic name) into the fully qualified
+  \item @{ML NameSpace.full_name}~@{text "naming binding"} turns a
+  name binding (usually a basic name) into the fully qualified
   internal name, according to the given naming policy.
 
   \item @{ML_type NameSpace.T} represents name spaces.
@@ -755,8 +756,8 @@
   \item @{ML NameSpace.extern}~@{text "space name"} externalizes a
   (fully qualified) internal name.
 
-  This operation is mostly for printing!  Note unqualified names are
-  produced via @{ML NameSpace.base}.
+  This operation is mostly for printing!  User code should not rely on
+  the precise result too much.
 
   \end{description}
 *}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Base.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,29 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Base}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Base\isanewline
+\isakeyword{imports}\ Pure\isanewline
+\isakeyword{uses}\ {\isachardoublequoteopen}{\isachardot}{\isachardot}{\isacharslash}{\isachardot}{\isachardot}{\isacharslash}antiquote{\isacharunderscore}setup{\isachardot}ML{\isachardoublequoteclose}\isanewline
+\isakeyword{begin}\isanewline
+\isanewline
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+\isanewline
+%
+\endisadelimtheory
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Integration.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,520 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Integration}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Integration\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{System integration%
+}
+\isamarkuptrue%
+%
+\isamarkupsection{Isar toplevel \label{sec:isar-toplevel}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The Isar toplevel may be considered the centeral hub of the
+  Isabelle/Isar system, where all key components and sub-systems are
+  integrated into a single read-eval-print loop of Isar commands.  We
+  shall even incorporate the existing {\ML} toplevel of the compiler
+  and run-time system (cf.\ \secref{sec:ML-toplevel}).
+
+  Isabelle/Isar departs from the original ``LCF system architecture''
+  where {\ML} was really The Meta Language for defining theories and
+  conducting proofs.  Instead, {\ML} now only serves as the
+  implementation language for the system (and user extensions), while
+  the specific Isar toplevel supports the concepts of theory and proof
+  development natively.  This includes the graph structure of theories
+  and the block structure of proofs, support for unlimited undo,
+  facilities for tracing, debugging, timing, profiling etc.
+
+  \medskip The toplevel maintains an implicit state, which is
+  transformed by a sequence of transitions -- either interactively or
+  in batch-mode.  In interactive mode, Isar state transitions are
+  encapsulated as safe transactions, such that both failure and undo
+  are handled conveniently without destroying the underlying draft
+  theory (cf.~\secref{sec:context-theory}).  In batch mode,
+  transitions operate in a linear (destructive) fashion, such that
+  error conditions abort the present attempt to construct a theory or
+  proof altogether.
+
+  The toplevel state is a disjoint sum of empty \isa{toplevel}, or
+  \isa{theory}, or \isa{proof}.  On entering the main Isar loop we
+  start with an empty toplevel.  A theory is commenced by giving a
+  \isa{{\isasymTHEORY}} header; within a theory we may issue theory
+  commands such as \isa{{\isasymDEFINITION}}, or state a \isa{{\isasymTHEOREM}} to be proven.  Now we are within a proof state, with a
+  rich collection of Isar proof commands for structured proof
+  composition, or unstructured proof scripts.  When the proof is
+  concluded we get back to the theory, which is then updated by
+  storing the resulting fact.  Further theory declarations or theorem
+  statements with proofs may follow, until we eventually conclude the
+  theory development by issuing \isa{{\isasymEND}}.  The resulting theory
+  is then stored within the theory database and we are back to the
+  empty toplevel.
+
+  In addition to these proper state transformations, there are also
+  some diagnostic commands for peeking at the toplevel state without
+  modifying it (e.g.\ \isakeyword{thm}, \isakeyword{term},
+  \isakeyword{print-cases}).%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{Toplevel.state}\verb|type Toplevel.state| \\
+  \indexdef{}{ML}{Toplevel.UNDEF}\verb|Toplevel.UNDEF: exn| \\
+  \indexdef{}{ML}{Toplevel.is\_toplevel}\verb|Toplevel.is_toplevel: Toplevel.state -> bool| \\
+  \indexdef{}{ML}{Toplevel.theory\_of}\verb|Toplevel.theory_of: Toplevel.state -> theory| \\
+  \indexdef{}{ML}{Toplevel.proof\_of}\verb|Toplevel.proof_of: Toplevel.state -> Proof.state| \\
+  \indexdef{}{ML}{Toplevel.debug}\verb|Toplevel.debug: bool ref| \\
+  \indexdef{}{ML}{Toplevel.timing}\verb|Toplevel.timing: bool ref| \\
+  \indexdef{}{ML}{Toplevel.profiling}\verb|Toplevel.profiling: int ref| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Toplevel.state| represents Isar toplevel states,
+  which are normally manipulated through the concept of toplevel
+  transitions only (\secref{sec:toplevel-transition}).  Also note that
+  a raw toplevel state is subject to the same linearity restrictions
+  as a theory context (cf.~\secref{sec:context-theory}).
+
+  \item \verb|Toplevel.UNDEF| is raised for undefined toplevel
+  operations.  Many operations work only partially for certain cases,
+  since \verb|Toplevel.state| is a sum type.
+
+  \item \verb|Toplevel.is_toplevel|~\isa{state} checks for an empty
+  toplevel state.
+
+  \item \verb|Toplevel.theory_of|~\isa{state} selects the theory of
+  a theory or proof (!), otherwise raises \verb|Toplevel.UNDEF|.
+
+  \item \verb|Toplevel.proof_of|~\isa{state} selects the Isar proof
+  state if available, otherwise raises \verb|Toplevel.UNDEF|.
+
+  \item \verb|set Toplevel.debug| makes the toplevel print further
+  details about internal error conditions, exceptions being raised
+  etc.
+
+  \item \verb|set Toplevel.timing| makes the toplevel print timing
+  information for each Isar command being executed.
+
+  \item \verb|Toplevel.profiling|~\verb|:=|~\isa{n} controls
+  low-level profiling of the underlying {\ML} runtime system.  For
+  Poly/ML, \isa{n\ {\isacharequal}\ {\isadigit{1}}} means time and \isa{n\ {\isacharequal}\ {\isadigit{2}}} space
+  profiling.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Toplevel transitions \label{sec:toplevel-transition}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+An Isar toplevel transition consists of a partial function on the
+  toplevel state, with additional information for diagnostics and
+  error reporting: there are fields for command name, source position,
+  optional source text, as well as flags for interactive-only commands
+  (which issue a warning in batch-mode), printing of result state,
+  etc.
+
+  The operational part is represented as the sequential union of a
+  list of partial functions, which are tried in turn until the first
+  one succeeds.  This acts like an outer case-expression for various
+  alternative state transitions.  For example, \isakeyword{qed} acts
+  differently for a local proofs vs.\ the global ending of the main
+  proof.
+
+  Toplevel transitions are composed via transition transformers.
+  Internally, Isar commands are put together from an empty transition
+  extended by name and source position (and optional source text).  It
+  is then left to the individual command parser to turn the given
+  concrete syntax into a suitable transition transformer that adjoins
+  actual operations on a theory or proof state etc.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{Toplevel.print}\verb|Toplevel.print: Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.no\_timing}\verb|Toplevel.no_timing: Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.keep}\verb|Toplevel.keep: (Toplevel.state -> unit) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.theory}\verb|Toplevel.theory: (theory -> theory) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.theory\_to\_proof}\verb|Toplevel.theory_to_proof: (theory -> Proof.state) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.proof}\verb|Toplevel.proof: (Proof.state -> Proof.state) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.proofs}\verb|Toplevel.proofs: (Proof.state -> Proof.state Seq.seq) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \indexdef{}{ML}{Toplevel.end\_proof}\verb|Toplevel.end_proof: (bool -> Proof.state -> Proof.context) ->|\isasep\isanewline%
+\verb|  Toplevel.transition -> Toplevel.transition| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Toplevel.print|~\isa{tr} sets the print flag, which
+  causes the toplevel loop to echo the result state (in interactive
+  mode).
+
+  \item \verb|Toplevel.no_timing|~\isa{tr} indicates that the
+  transition should never show timing information, e.g.\ because it is
+  a diagnostic command.
+
+  \item \verb|Toplevel.keep|~\isa{tr} adjoins a diagnostic
+  function.
+
+  \item \verb|Toplevel.theory|~\isa{tr} adjoins a theory
+  transformer.
+
+  \item \verb|Toplevel.theory_to_proof|~\isa{tr} adjoins a global
+  goal function, which turns a theory into a proof state.  The theory
+  may be changed before entering the proof; the generic Isar goal
+  setup includes an argument that specifies how to apply the proven
+  result to the theory, when the proof is finished.
+
+  \item \verb|Toplevel.proof|~\isa{tr} adjoins a deterministic
+  proof command, with a singleton result.
+
+  \item \verb|Toplevel.proofs|~\isa{tr} adjoins a general proof
+  command, with zero or more result states (represented as a lazy
+  list).
+
+  \item \verb|Toplevel.end_proof|~\isa{tr} adjoins a concluding
+  proof command, that returns the resulting theory, after storing the
+  resulting facts in the context etc.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Toplevel control%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+There are a few special control commands that modify the behavior
+  the toplevel itself, and only make sense in interactive mode.  Under
+  normal circumstances, the user encounters these only implicitly as
+  part of the protocol between the Isabelle/Isar system and a
+  user-interface such as ProofGeneral.
+
+  \begin{description}
+
+  \item \isacommand{undo} follows the three-level hierarchy of empty
+  toplevel vs.\ theory vs.\ proof: undo within a proof reverts to the
+  previous proof context, undo after a proof reverts to the theory
+  before the initial goal statement, undo of a theory command reverts
+  to the previous theory value, undo of a theory header discontinues
+  the current theory development and removes it from the theory
+  database (\secref{sec:theory-database}).
+
+  \item \isacommand{kill} aborts the current level of development:
+  kill in a proof context reverts to the theory before the initial
+  goal statement, kill in a theory context aborts the current theory
+  development, removing it from the database.
+
+  \item \isacommand{exit} drops out of the Isar toplevel into the
+  underlying {\ML} toplevel (\secref{sec:ML-toplevel}).  The Isar
+  toplevel state is preserved and may be continued later.
+
+  \item \isacommand{quit} terminates the Isabelle/Isar process without
+  saving.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{ML toplevel \label{sec:ML-toplevel}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The {\ML} toplevel provides a read-compile-eval-print loop for {\ML}
+  values, types, structures, and functors.  {\ML} declarations operate
+  on the global system state, which consists of the compiler
+  environment plus the values of {\ML} reference variables.  There is
+  no clean way to undo {\ML} declarations, except for reverting to a
+  previously saved state of the whole Isabelle process.  {\ML} input
+  is either read interactively from a TTY, or from a string (usually
+  within a theory text), or from a source file (usually loaded from a
+  theory).
+
+  Whenever the {\ML} toplevel is active, the current Isabelle theory
+  context is passed as an internal reference variable.  Thus {\ML}
+  code may access the theory context during compilation, it may even
+  change the value of a theory being under construction --- while
+  observing the usual linearity restrictions
+  (cf.~\secref{sec:context-theory}).%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{the\_context}\verb|the_context: unit -> theory| \\
+  \indexdef{}{ML}{Context.$>$$>$ }\verb|Context.>> : (Context.generic -> Context.generic) -> unit| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|the_context ()| refers to the theory context of the
+  {\ML} toplevel --- at compile time!  {\ML} code needs to take care
+  to refer to \verb|the_context ()| correctly.  Recall that
+  evaluation of a function body is delayed until actual runtime.
+  Moreover, persistent {\ML} toplevel bindings to an unfinished theory
+  should be avoided: code should either project out the desired
+  information immediately, or produce an explicit \verb|theory_ref| (cf.\ \secref{sec:context-theory}).
+
+  \item \verb|Context.>>|~\isa{f} applies context transformation
+  \isa{f} to the implicit context of the {\ML} toplevel.
+
+  \end{description}
+
+  It is very important to note that the above functions are really
+  restricted to the compile time, even though the {\ML} compiler is
+  invoked at runtime!  The majority of {\ML} code uses explicit
+  functional arguments of a theory or proof context instead.  Thus it
+  may be invoked for an arbitrary context later on, without having to
+  worry about any operational details.
+
+  \bigskip
+
+  \begin{mldecls}
+  \indexdef{}{ML}{Isar.main}\verb|Isar.main: unit -> unit| \\
+  \indexdef{}{ML}{Isar.loop}\verb|Isar.loop: unit -> unit| \\
+  \indexdef{}{ML}{Isar.state}\verb|Isar.state: unit -> Toplevel.state| \\
+  \indexdef{}{ML}{Isar.exn}\verb|Isar.exn: unit -> (exn * string) option| \\
+  \indexdef{}{ML}{Isar.context}\verb|Isar.context: unit -> Proof.context| \\
+  \indexdef{}{ML}{Isar.goal}\verb|Isar.goal: unit -> thm| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Isar.main ()| invokes the Isar toplevel from {\ML},
+  initializing an empty toplevel state.
+
+  \item \verb|Isar.loop ()| continues the Isar toplevel with the
+  current state, after having dropped out of the Isar toplevel loop.
+
+  \item \verb|Isar.state ()| and \verb|Isar.exn ()| get current
+  toplevel state and error condition, respectively.  This only works
+  after having dropped out of the Isar toplevel loop.
+
+  \item \verb|Isar.context ()| produces the proof context from \verb|Isar.state ()|, analogous to \verb|Context.proof_of|
+  (\secref{sec:generic-context}).
+
+  \item \verb|Isar.goal ()| picks the tactical goal from \verb|Isar.state ()|, represented as a theorem according to
+  \secref{sec:tactical-goals}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Theory database \label{sec:theory-database}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The theory database maintains a collection of theories, together
+  with some administrative information about their original sources,
+  which are held in an external store (i.e.\ some directory within the
+  regular file system).
+
+  The theory database is organized as a directed acyclic graph;
+  entries are referenced by theory name.  Although some additional
+  interfaces allow to include a directory specification as well, this
+  is only a hint to the underlying theory loader.  The internal theory
+  name space is flat!
+
+  Theory \isa{A} is associated with the main theory file \isa{A}\verb,.thy,, which needs to be accessible through the theory
+  loader path.  Any number of additional {\ML} source files may be
+  associated with each theory, by declaring these dependencies in the
+  theory header as \isa{{\isasymUSES}}, and loading them consecutively
+  within the theory context.  The system keeps track of incoming {\ML}
+  sources and associates them with the current theory.  The file
+  \isa{A}\verb,.ML, is loaded after a theory has been concluded, in
+  order to support legacy proof {\ML} proof scripts.
+
+  The basic internal actions of the theory database are \isa{update}, \isa{outdate}, and \isa{remove}:
+
+  \begin{itemize}
+
+  \item \isa{update\ A} introduces a link of \isa{A} with a
+  \isa{theory} value of the same name; it asserts that the theory
+  sources are now consistent with that value;
+
+  \item \isa{outdate\ A} invalidates the link of a theory database
+  entry to its sources, but retains the present theory value;
+
+  \item \isa{remove\ A} deletes entry \isa{A} from the theory
+  database.
+  
+  \end{itemize}
+
+  These actions are propagated to sub- or super-graphs of a theory
+  entry as expected, in order to preserve global consistency of the
+  state of all loaded theories with the sources of the external store.
+  This implies certain causalities between actions: \isa{update}
+  or \isa{outdate} of an entry will \isa{outdate} all
+  descendants; \isa{remove} will \isa{remove} all descendants.
+
+  \medskip There are separate user-level interfaces to operate on the
+  theory database directly or indirectly.  The primitive actions then
+  just happen automatically while working with the system.  In
+  particular, processing a theory header \isa{{\isasymTHEORY}\ A\ {\isasymIMPORTS}\ B\isactrlsub {\isadigit{1}}\ {\isasymdots}\ B\isactrlsub n\ {\isasymBEGIN}} ensures that the
+  sub-graph of the collective imports \isa{B\isactrlsub {\isadigit{1}}\ {\isasymdots}\ B\isactrlsub n}
+  is up-to-date, too.  Earlier theories are reloaded as required, with
+  \isa{update} actions proceeding in topological order according to
+  theory dependencies.  There may be also a wave of implied \isa{outdate} actions for derived theory nodes until a stable situation
+  is achieved eventually.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{theory}\verb|theory: string -> theory| \\
+  \indexdef{}{ML}{use\_thy}\verb|use_thy: string -> unit| \\
+  \indexdef{}{ML}{use\_thys}\verb|use_thys: string list -> unit| \\
+  \indexdef{}{ML}{ThyInfo.touch\_thy}\verb|ThyInfo.touch_thy: string -> unit| \\
+  \indexdef{}{ML}{ThyInfo.remove\_thy}\verb|ThyInfo.remove_thy: string -> unit| \\[1ex]
+  \indexdef{}{ML}{ThyInfo.begin\_theory}\verb|ThyInfo.begin_theory|\verb|: ... -> bool -> theory| \\
+  \indexdef{}{ML}{ThyInfo.end\_theory}\verb|ThyInfo.end_theory: theory -> unit| \\
+  \indexdef{}{ML}{ThyInfo.register\_theory}\verb|ThyInfo.register_theory: theory -> unit| \\[1ex]
+  \verb|datatype action = Update |\verb,|,\verb| Outdate |\verb,|,\verb| Remove| \\
+  \indexdef{}{ML}{ThyInfo.add\_hook}\verb|ThyInfo.add_hook: (ThyInfo.action -> string -> unit) -> unit| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|theory|~\isa{A} retrieves the theory value presently
+  associated with name \isa{A}.  Note that the result might be
+  outdated.
+
+  \item \verb|use_thy|~\isa{A} ensures that theory \isa{A} is fully
+  up-to-date wrt.\ the external file store, reloading outdated
+  ancestors as required.
+
+  \item \verb|use_thys| is similar to \verb|use_thy|, but handles
+  several theories simultaneously.  Thus it acts like processing the
+  import header of a theory, without performing the merge of the
+  result, though.
+
+  \item \verb|ThyInfo.touch_thy|~\isa{A} performs and \isa{outdate} action
+  on theory \isa{A} and all descendants.
+
+  \item \verb|ThyInfo.remove_thy|~\isa{A} deletes theory \isa{A} and all
+  descendants from the theory database.
+
+  \item \verb|ThyInfo.begin_theory| is the basic operation behind a
+  \isa{{\isasymTHEORY}} header declaration.  This is {\ML} functions is
+  normally not invoked directly.
+
+  \item \verb|ThyInfo.end_theory| concludes the loading of a theory
+  proper and stores the result in the theory database.
+
+  \item \verb|ThyInfo.register_theory|~\isa{text\ thy} registers an
+  existing theory value with the theory loader database.  There is no
+  management of associated sources.
+
+  \item \verb|ThyInfo.add_hook|~\isa{f} registers function \isa{f} as a hook for theory database actions.  The function will be
+  invoked with the action and theory name being involved; thus derived
+  actions may be performed in associated system components, e.g.\
+  maintaining the state of an editor for the theory sources.
+
+  The kind and order of actions occurring in practice depends both on
+  user interactions and the internal process of resolving theory
+  imports.  Hooks should not rely on a particular policy here!  Any
+  exceptions raised by the hook are ignored.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Isar.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,86 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Isar}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Isar\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{Isar language elements%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The primary Isar language consists of three main categories of
+  language elements:
+
+  \begin{enumerate}
+
+  \item Proof commands
+
+  \item Proof methods
+
+  \item Attributes
+
+  \end{enumerate}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{Proof commands%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+FIXME%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{Proof methods%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+FIXME%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{Attributes%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+FIXME%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Logic.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,959 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Logic}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Logic\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{Primitive logic \label{ch:logic}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The logical foundations of Isabelle/Isar are that of the Pure logic,
+  which has been introduced as a Natural Deduction framework in
+  \cite{paulson700}.  This is essentially the same logic as ``\isa{{\isasymlambda}HOL}'' in the more abstract setting of Pure Type Systems (PTS)
+  \cite{Barendregt-Geuvers:2001}, although there are some key
+  differences in the specific treatment of simple types in
+  Isabelle/Pure.
+
+  Following type-theoretic parlance, the Pure logic consists of three
+  levels of \isa{{\isasymlambda}}-calculus with corresponding arrows, \isa{{\isasymRightarrow}} for syntactic function space (terms depending on terms), \isa{{\isasymAnd}} for universal quantification (proofs depending on terms), and
+  \isa{{\isasymLongrightarrow}} for implication (proofs depending on proofs).
+
+  Derivations are relative to a logical theory, which declares type
+  constructors, constants, and axioms.  Theory declarations support
+  schematic polymorphism, which is strictly speaking outside the
+  logic.\footnote{This is the deeper logical reason, why the theory
+  context \isa{{\isasymTheta}} is separate from the proof context \isa{{\isasymGamma}}
+  of the core calculus.}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{Types \label{sec:types}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The language of types is an uninterpreted order-sorted first-order
+  algebra; types are qualified by ordered type classes.
+
+  \medskip A \emph{type class} is an abstract syntactic entity
+  declared in the theory context.  The \emph{subclass relation} \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}} is specified by stating an acyclic
+  generating relation; the transitive closure is maintained
+  internally.  The resulting relation is an ordering: reflexive,
+  transitive, and antisymmetric.
+
+  A \emph{sort} is a list of type classes written as \isa{s\ {\isacharequal}\ {\isacharbraceleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ c\isactrlisub m{\isacharbraceright}}, which represents symbolic
+  intersection.  Notationally, the curly braces are omitted for
+  singleton intersections, i.e.\ any class \isa{c} may be read as
+  a sort \isa{{\isacharbraceleft}c{\isacharbraceright}}.  The ordering on type classes is extended to
+  sorts according to the meaning of intersections: \isa{{\isacharbraceleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}\ c\isactrlisub m{\isacharbraceright}\ {\isasymsubseteq}\ {\isacharbraceleft}d\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ d\isactrlisub n{\isacharbraceright}} iff
+  \isa{{\isasymforall}j{\isachardot}\ {\isasymexists}i{\isachardot}\ c\isactrlisub i\ {\isasymsubseteq}\ d\isactrlisub j}.  The empty intersection
+  \isa{{\isacharbraceleft}{\isacharbraceright}} refers to the universal sort, which is the largest
+  element wrt.\ the sort order.  The intersections of all (finitely
+  many) classes declared in the current theory are the minimal
+  elements wrt.\ the sort order.
+
+  \medskip A \emph{fixed type variable} is a pair of a basic name
+  (starting with a \isa{{\isacharprime}} character) and a sort constraint, e.g.\
+  \isa{{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ s{\isacharparenright}} which is usually printed as \isa{{\isasymalpha}\isactrlisub s}.
+  A \emph{schematic type variable} is a pair of an indexname and a
+  sort constraint, e.g.\ \isa{{\isacharparenleft}{\isacharparenleft}{\isacharprime}a{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ s{\isacharparenright}} which is usually
+  printed as \isa{{\isacharquery}{\isasymalpha}\isactrlisub s}.
+
+  Note that \emph{all} syntactic components contribute to the identity
+  of type variables, including the sort constraint.  The core logic
+  handles type variables with the same name but different sorts as
+  different, although some outer layers of the system make it hard to
+  produce anything like this.
+
+  A \emph{type constructor} \isa{{\isasymkappa}} is a \isa{k}-ary operator
+  on types declared in the theory.  Type constructor application is
+  written postfix as \isa{{\isacharparenleft}{\isasymalpha}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlisub k{\isacharparenright}{\isasymkappa}}.  For
+  \isa{k\ {\isacharequal}\ {\isadigit{0}}} the argument tuple is omitted, e.g.\ \isa{prop}
+  instead of \isa{{\isacharparenleft}{\isacharparenright}prop}.  For \isa{k\ {\isacharequal}\ {\isadigit{1}}} the parentheses
+  are omitted, e.g.\ \isa{{\isasymalpha}\ list} instead of \isa{{\isacharparenleft}{\isasymalpha}{\isacharparenright}list}.
+  Further notation is provided for specific constructors, notably the
+  right-associative infix \isa{{\isasymalpha}\ {\isasymRightarrow}\ {\isasymbeta}} instead of \isa{{\isacharparenleft}{\isasymalpha}{\isacharcomma}\ {\isasymbeta}{\isacharparenright}fun}.
+  
+  A \emph{type} is defined inductively over type variables and type
+  constructors as follows: \isa{{\isasymtau}\ {\isacharequal}\ {\isasymalpha}\isactrlisub s\ {\isacharbar}\ {\isacharquery}{\isasymalpha}\isactrlisub s\ {\isacharbar}\ {\isacharparenleft}{\isasymtau}\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlsub k{\isacharparenright}{\isasymkappa}}.
+
+  A \emph{type abbreviation} is a syntactic definition \isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}\ {\isacharequal}\ {\isasymtau}} of an arbitrary type expression \isa{{\isasymtau}} over
+  variables \isa{\isactrlvec {\isasymalpha}}.  Type abbreviations appear as type
+  constructors in the syntax, but are expanded before entering the
+  logical core.
+
+  A \emph{type arity} declares the image behavior of a type
+  constructor wrt.\ the algebra of sorts: \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ s\isactrlisub k{\isacharparenright}s} means that \isa{{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub k{\isacharparenright}{\isasymkappa}} is
+  of sort \isa{s} if every argument type \isa{{\isasymtau}\isactrlisub i} is
+  of sort \isa{s\isactrlisub i}.  Arity declarations are implicitly
+  completed, i.e.\ \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}c} entails \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}c{\isacharprime}} for any \isa{c{\isacharprime}\ {\isasymsupseteq}\ c}.
+
+  \medskip The sort algebra is always maintained as \emph{coregular},
+  which means that type arities are consistent with the subclass
+  relation: for any type constructor \isa{{\isasymkappa}}, and classes \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}}, and arities \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s\isactrlisub {\isadigit{1}}{\isacharparenright}c\isactrlisub {\isadigit{1}}} and \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s\isactrlisub {\isadigit{2}}{\isacharparenright}c\isactrlisub {\isadigit{2}}} holds \isa{\isactrlvec s\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ \isactrlvec s\isactrlisub {\isadigit{2}}} component-wise.
+
+  The key property of a coregular order-sorted algebra is that sort
+  constraints can be solved in a most general fashion: for each type
+  constructor \isa{{\isasymkappa}} and sort \isa{s} there is a most general
+  vector of argument sorts \isa{{\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ s\isactrlisub k{\isacharparenright}} such
+  that a type scheme \isa{{\isacharparenleft}{\isasymalpha}\isactrlbsub s\isactrlisub {\isadigit{1}}\isactrlesub {\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymalpha}\isactrlbsub s\isactrlisub k\isactrlesub {\isacharparenright}{\isasymkappa}} is of sort \isa{s}.
+  Consequently, type unification has most general solutions (modulo
+  equivalence of sorts), so type-inference produces primary types as
+  expected \cite{nipkow-prehofer}.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{class}\verb|type class| \\
+  \indexdef{}{ML type}{sort}\verb|type sort| \\
+  \indexdef{}{ML type}{arity}\verb|type arity| \\
+  \indexdef{}{ML type}{typ}\verb|type typ| \\
+  \indexdef{}{ML}{map\_atyps}\verb|map_atyps: (typ -> typ) -> typ -> typ| \\
+  \indexdef{}{ML}{fold\_atyps}\verb|fold_atyps: (typ -> 'a -> 'a) -> typ -> 'a -> 'a| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML}{Sign.subsort}\verb|Sign.subsort: theory -> sort * sort -> bool| \\
+  \indexdef{}{ML}{Sign.of\_sort}\verb|Sign.of_sort: theory -> typ * sort -> bool| \\
+  \indexdef{}{ML}{Sign.add\_types}\verb|Sign.add_types: (string * int * mixfix) list -> theory -> theory| \\
+  \indexdef{}{ML}{Sign.add\_tyabbrs\_i}\verb|Sign.add_tyabbrs_i: |\isasep\isanewline%
+\verb|  (string * string list * typ * mixfix) list -> theory -> theory| \\
+  \indexdef{}{ML}{Sign.primitive\_class}\verb|Sign.primitive_class: string * class list -> theory -> theory| \\
+  \indexdef{}{ML}{Sign.primitive\_classrel}\verb|Sign.primitive_classrel: class * class -> theory -> theory| \\
+  \indexdef{}{ML}{Sign.primitive\_arity}\verb|Sign.primitive_arity: arity -> theory -> theory| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|class| represents type classes; this is an alias for
+  \verb|string|.
+
+  \item \verb|sort| represents sorts; this is an alias for
+  \verb|class list|.
+
+  \item \verb|arity| represents type arities; this is an alias for
+  triples of the form \isa{{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec s{\isacharcomma}\ s{\isacharparenright}} for \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}s} described above.
+
+  \item \verb|typ| represents types; this is a datatype with
+  constructors \verb|TFree|, \verb|TVar|, \verb|Type|.
+
+  \item \verb|map_atyps|~\isa{f\ {\isasymtau}} applies the mapping \isa{f}
+  to all atomic types (\verb|TFree|, \verb|TVar|) occurring in \isa{{\isasymtau}}.
+
+  \item \verb|fold_atyps|~\isa{f\ {\isasymtau}} iterates the operation \isa{f} over all occurrences of atomic types (\verb|TFree|, \verb|TVar|)
+  in \isa{{\isasymtau}}; the type structure is traversed from left to right.
+
+  \item \verb|Sign.subsort|~\isa{thy\ {\isacharparenleft}s\isactrlisub {\isadigit{1}}{\isacharcomma}\ s\isactrlisub {\isadigit{2}}{\isacharparenright}}
+  tests the subsort relation \isa{s\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ s\isactrlisub {\isadigit{2}}}.
+
+  \item \verb|Sign.of_sort|~\isa{thy\ {\isacharparenleft}{\isasymtau}{\isacharcomma}\ s{\isacharparenright}} tests whether type
+  \isa{{\isasymtau}} is of sort \isa{s}.
+
+  \item \verb|Sign.add_types|~\isa{{\isacharbrackleft}{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ k{\isacharcomma}\ mx{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} declares a new
+  type constructors \isa{{\isasymkappa}} with \isa{k} arguments and
+  optional mixfix syntax.
+
+  \item \verb|Sign.add_tyabbrs_i|~\isa{{\isacharbrackleft}{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec {\isasymalpha}{\isacharcomma}\ {\isasymtau}{\isacharcomma}\ mx{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}}
+  defines a new type abbreviation \isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}\ {\isacharequal}\ {\isasymtau}} with
+  optional mixfix syntax.
+
+  \item \verb|Sign.primitive_class|~\isa{{\isacharparenleft}c{\isacharcomma}\ {\isacharbrackleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ c\isactrlisub n{\isacharbrackright}{\isacharparenright}} declares a new class \isa{c}, together with class
+  relations \isa{c\ {\isasymsubseteq}\ c\isactrlisub i}, for \isa{i\ {\isacharequal}\ {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ n}.
+
+  \item \verb|Sign.primitive_classrel|~\isa{{\isacharparenleft}c\isactrlisub {\isadigit{1}}{\isacharcomma}\ c\isactrlisub {\isadigit{2}}{\isacharparenright}} declares the class relation \isa{c\isactrlisub {\isadigit{1}}\ {\isasymsubseteq}\ c\isactrlisub {\isadigit{2}}}.
+
+  \item \verb|Sign.primitive_arity|~\isa{{\isacharparenleft}{\isasymkappa}{\isacharcomma}\ \isactrlvec s{\isacharcomma}\ s{\isacharparenright}} declares
+  the arity \isa{{\isasymkappa}\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}\isactrlvec s{\isacharparenright}s}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Terms \label{sec:terms}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The language of terms is that of simply-typed \isa{{\isasymlambda}}-calculus
+  with de-Bruijn indices for bound variables (cf.\ \cite{debruijn72}
+  or \cite{paulson-ml2}), with the types being determined by the
+  corresponding binders.  In contrast, free variables and constants
+  are have an explicit name and type in each occurrence.
+
+  \medskip A \emph{bound variable} is a natural number \isa{b},
+  which accounts for the number of intermediate binders between the
+  variable occurrence in the body and its binding position.  For
+  example, the de-Bruijn term \isa{{\isasymlambda}\isactrlbsub nat\isactrlesub {\isachardot}\ {\isasymlambda}\isactrlbsub nat\isactrlesub {\isachardot}\ {\isadigit{1}}\ {\isacharplus}\ {\isadigit{0}}} would
+  correspond to \isa{{\isasymlambda}x\isactrlbsub nat\isactrlesub {\isachardot}\ {\isasymlambda}y\isactrlbsub nat\isactrlesub {\isachardot}\ x\ {\isacharplus}\ y} in a named
+  representation.  Note that a bound variable may be represented by
+  different de-Bruijn indices at different occurrences, depending on
+  the nesting of abstractions.
+
+  A \emph{loose variable} is a bound variable that is outside the
+  scope of local binders.  The types (and names) for loose variables
+  can be managed as a separate context, that is maintained as a stack
+  of hypothetical binders.  The core logic operates on closed terms,
+  without any loose variables.
+
+  A \emph{fixed variable} is a pair of a basic name and a type, e.g.\
+  \isa{{\isacharparenleft}x{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed \isa{x\isactrlisub {\isasymtau}}.  A
+  \emph{schematic variable} is a pair of an indexname and a type,
+  e.g.\ \isa{{\isacharparenleft}{\isacharparenleft}x{\isacharcomma}\ {\isadigit{0}}{\isacharparenright}{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed as \isa{{\isacharquery}x\isactrlisub {\isasymtau}}.
+
+  \medskip A \emph{constant} is a pair of a basic name and a type,
+  e.g.\ \isa{{\isacharparenleft}c{\isacharcomma}\ {\isasymtau}{\isacharparenright}} which is usually printed as \isa{c\isactrlisub {\isasymtau}}.  Constants are declared in the context as polymorphic
+  families \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}, meaning that all substitution instances
+  \isa{c\isactrlisub {\isasymtau}} for \isa{{\isasymtau}\ {\isacharequal}\ {\isasymsigma}{\isasymvartheta}} are valid.
+
+  The vector of \emph{type arguments} of constant \isa{c\isactrlisub {\isasymtau}}
+  wrt.\ the declaration \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} is defined as the codomain of
+  the matcher \isa{{\isasymvartheta}\ {\isacharequal}\ {\isacharbraceleft}{\isacharquery}{\isasymalpha}\isactrlisub {\isadigit{1}}\ {\isasymmapsto}\ {\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isacharquery}{\isasymalpha}\isactrlisub n\ {\isasymmapsto}\ {\isasymtau}\isactrlisub n{\isacharbraceright}} presented in canonical order \isa{{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharparenright}}.  Within a given theory context,
+  there is a one-to-one correspondence between any constant \isa{c\isactrlisub {\isasymtau}} and the application \isa{c{\isacharparenleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharparenright}} of its type arguments.  For example, with \isa{plus\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}}, the instance \isa{plus\isactrlbsub nat\ {\isasymRightarrow}\ nat\ {\isasymRightarrow}\ nat\isactrlesub } corresponds to \isa{plus{\isacharparenleft}nat{\isacharparenright}}.
+
+  Constant declarations \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} may contain sort constraints
+  for type variables in \isa{{\isasymsigma}}.  These are observed by
+  type-inference as expected, but \emph{ignored} by the core logic.
+  This means the primitive logic is able to reason with instances of
+  polymorphic constants that the user-level type-checker would reject
+  due to violation of type class restrictions.
+
+  \medskip An \emph{atomic} term is either a variable or constant.  A
+  \emph{term} is defined inductively over atomic terms, with
+  abstraction and application as follows: \isa{t\ {\isacharequal}\ b\ {\isacharbar}\ x\isactrlisub {\isasymtau}\ {\isacharbar}\ {\isacharquery}x\isactrlisub {\isasymtau}\ {\isacharbar}\ c\isactrlisub {\isasymtau}\ {\isacharbar}\ {\isasymlambda}\isactrlisub {\isasymtau}{\isachardot}\ t\ {\isacharbar}\ t\isactrlisub {\isadigit{1}}\ t\isactrlisub {\isadigit{2}}}.
+  Parsing and printing takes care of converting between an external
+  representation with named bound variables.  Subsequently, we shall
+  use the latter notation instead of internal de-Bruijn
+  representation.
+
+  The inductive relation \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}} assigns a (unique) type to a
+  term according to the structure of atomic terms, abstractions, and
+  applicatins:
+  \[
+  \infer{\isa{a\isactrlisub {\isasymtau}\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}}{}
+  \qquad
+  \infer{\isa{{\isacharparenleft}{\isasymlambda}x\isactrlsub {\isasymtau}{\isachardot}\ t{\isacharparenright}\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymsigma}}}{\isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}}
+  \qquad
+  \infer{\isa{t\ u\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}}{\isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}\ {\isasymRightarrow}\ {\isasymsigma}} & \isa{u\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}}}
+  \]
+  A \emph{well-typed term} is a term that can be typed according to these rules.
+
+  Typing information can be omitted: type-inference is able to
+  reconstruct the most general type of a raw term, while assigning
+  most general types to all of its variables and constants.
+  Type-inference depends on a context of type constraints for fixed
+  variables, and declarations for polymorphic constants.
+
+  The identity of atomic terms consists both of the name and the type
+  component.  This means that different variables \isa{x\isactrlbsub {\isasymtau}\isactrlisub {\isadigit{1}}\isactrlesub } and \isa{x\isactrlbsub {\isasymtau}\isactrlisub {\isadigit{2}}\isactrlesub } may become the same after type
+  instantiation.  Some outer layers of the system make it hard to
+  produce variables of the same name, but different types.  In
+  contrast, mixed instances of polymorphic constants occur frequently.
+
+  \medskip The \emph{hidden polymorphism} of a term \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}}
+  is the set of type variables occurring in \isa{t}, but not in
+  \isa{{\isasymsigma}}.  This means that the term implicitly depends on type
+  arguments that are not accounted in the result type, i.e.\ there are
+  different type instances \isa{t{\isasymvartheta}\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} and \isa{t{\isasymvartheta}{\isacharprime}\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} with the same type.  This slightly
+  pathological situation notoriously demands additional care.
+
+  \medskip A \emph{term abbreviation} is a syntactic definition \isa{c\isactrlisub {\isasymsigma}\ {\isasymequiv}\ t} of a closed term \isa{t} of type \isa{{\isasymsigma}},
+  without any hidden polymorphism.  A term abbreviation looks like a
+  constant in the syntax, but is expanded before entering the logical
+  core.  Abbreviations are usually reverted when printing terms, using
+  \isa{t\ {\isasymrightarrow}\ c\isactrlisub {\isasymsigma}} as rules for higher-order rewriting.
+
+  \medskip Canonical operations on \isa{{\isasymlambda}}-terms include \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion: \isa{{\isasymalpha}}-conversion refers to capture-free
+  renaming of bound variables; \isa{{\isasymbeta}}-conversion contracts an
+  abstraction applied to an argument term, substituting the argument
+  in the body: \isa{{\isacharparenleft}{\isasymlambda}x{\isachardot}\ b{\isacharparenright}a} becomes \isa{b{\isacharbrackleft}a{\isacharslash}x{\isacharbrackright}}; \isa{{\isasymeta}}-conversion contracts vacuous application-abstraction: \isa{{\isasymlambda}x{\isachardot}\ f\ x} becomes \isa{f}, provided that the bound variable
+  does not occur in \isa{f}.
+
+  Terms are normally treated modulo \isa{{\isasymalpha}}-conversion, which is
+  implicit in the de-Bruijn representation.  Names for bound variables
+  in abstractions are maintained separately as (meaningless) comments,
+  mostly for parsing and printing.  Full \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion is
+  commonplace in various standard operations (\secref{sec:obj-rules})
+  that are based on higher-order unification and matching.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{term}\verb|type term| \\
+  \indexdef{}{ML}{op aconv}\verb|op aconv: term * term -> bool| \\
+  \indexdef{}{ML}{map\_types}\verb|map_types: (typ -> typ) -> term -> term| \\
+  \indexdef{}{ML}{fold\_types}\verb|fold_types: (typ -> 'a -> 'a) -> term -> 'a -> 'a| \\
+  \indexdef{}{ML}{map\_aterms}\verb|map_aterms: (term -> term) -> term -> term| \\
+  \indexdef{}{ML}{fold\_aterms}\verb|fold_aterms: (term -> 'a -> 'a) -> term -> 'a -> 'a| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML}{fastype\_of}\verb|fastype_of: term -> typ| \\
+  \indexdef{}{ML}{lambda}\verb|lambda: term -> term -> term| \\
+  \indexdef{}{ML}{betapply}\verb|betapply: term * term -> term| \\
+  \indexdef{}{ML}{Sign.declare\_const}\verb|Sign.declare_const: Properties.T -> (binding * typ) * mixfix ->|\isasep\isanewline%
+\verb|  theory -> term * theory| \\
+  \indexdef{}{ML}{Sign.add\_abbrev}\verb|Sign.add_abbrev: string -> Properties.T -> binding * term ->|\isasep\isanewline%
+\verb|  theory -> (term * term) * theory| \\
+  \indexdef{}{ML}{Sign.const\_typargs}\verb|Sign.const_typargs: theory -> string * typ -> typ list| \\
+  \indexdef{}{ML}{Sign.const\_instance}\verb|Sign.const_instance: theory -> string * typ list -> typ| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|term| represents de-Bruijn terms, with comments in
+  abstractions, and explicitly named free variables and constants;
+  this is a datatype with constructors \verb|Bound|, \verb|Free|, \verb|Var|, \verb|Const|, \verb|Abs|, \verb|op $|.
+
+  \item \isa{t}~\verb|aconv|~\isa{u} checks \isa{{\isasymalpha}}-equivalence of two terms.  This is the basic equality relation
+  on type \verb|term|; raw datatype equality should only be used
+  for operations related to parsing or printing!
+
+  \item \verb|map_types|~\isa{f\ t} applies the mapping \isa{f} to all types occurring in \isa{t}.
+
+  \item \verb|fold_types|~\isa{f\ t} iterates the operation \isa{f} over all occurrences of types in \isa{t}; the term
+  structure is traversed from left to right.
+
+  \item \verb|map_aterms|~\isa{f\ t} applies the mapping \isa{f}
+  to all atomic terms (\verb|Bound|, \verb|Free|, \verb|Var|, \verb|Const|) occurring in \isa{t}.
+
+  \item \verb|fold_aterms|~\isa{f\ t} iterates the operation \isa{f} over all occurrences of atomic terms (\verb|Bound|, \verb|Free|,
+  \verb|Var|, \verb|Const|) in \isa{t}; the term structure is
+  traversed from left to right.
+
+  \item \verb|fastype_of|~\isa{t} determines the type of a
+  well-typed term.  This operation is relatively slow, despite the
+  omission of any sanity checks.
+
+  \item \verb|lambda|~\isa{a\ b} produces an abstraction \isa{{\isasymlambda}a{\isachardot}\ b}, where occurrences of the atomic term \isa{a} in the
+  body \isa{b} are replaced by bound variables.
+
+  \item \verb|betapply|~\isa{{\isacharparenleft}t{\isacharcomma}\ u{\isacharparenright}} produces an application \isa{t\ u}, with topmost \isa{{\isasymbeta}}-conversion if \isa{t} is an
+  abstraction.
+
+  \item \verb|Sign.declare_const|~\isa{properties\ {\isacharparenleft}{\isacharparenleft}c{\isacharcomma}\ {\isasymsigma}{\isacharparenright}{\isacharcomma}\ mx{\isacharparenright}}
+  declares a new constant \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} with optional mixfix
+  syntax.
+
+  \item \verb|Sign.add_abbrev|~\isa{print{\isacharunderscore}mode\ properties\ {\isacharparenleft}c{\isacharcomma}\ t{\isacharparenright}}
+  introduces a new term abbreviation \isa{c\ {\isasymequiv}\ t}.
+
+  \item \verb|Sign.const_typargs|~\isa{thy\ {\isacharparenleft}c{\isacharcomma}\ {\isasymtau}{\isacharparenright}} and \verb|Sign.const_instance|~\isa{thy\ {\isacharparenleft}c{\isacharcomma}\ {\isacharbrackleft}{\isasymtau}\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ {\isasymtau}\isactrlisub n{\isacharbrackright}{\isacharparenright}}
+  convert between two representations of polymorphic constants: full
+  type instance vs.\ compact type arguments form.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Theorems \label{sec:thms}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{proposition} is a well-typed term of type \isa{prop}, a
+  \emph{theorem} is a proven proposition (depending on a context of
+  hypotheses and the background theory).  Primitive inferences include
+  plain Natural Deduction rules for the primary connectives \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}} of the framework.  There is also a builtin
+  notion of equality/equivalence \isa{{\isasymequiv}}.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Primitive connectives and rules \label{sec:prim-rules}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The theory \isa{Pure} contains constant declarations for the
+  primitive connectives \isa{{\isasymAnd}}, \isa{{\isasymLongrightarrow}}, and \isa{{\isasymequiv}} of
+  the logical framework, see \figref{fig:pure-connectives}.  The
+  derivability judgment \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n\ {\isasymturnstile}\ B} is
+  defined inductively by the primitive inferences given in
+  \figref{fig:prim-rules}, with the global restriction that the
+  hypotheses must \emph{not} contain any schematic variables.  The
+  builtin equality is conceptually axiomatized as shown in
+  \figref{fig:pure-equality}, although the implementation works
+  directly with derived inferences.
+
+  \begin{figure}[htb]
+  \begin{center}
+  \begin{tabular}{ll}
+  \isa{all\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}{\isasymalpha}\ {\isasymRightarrow}\ prop{\isacharparenright}\ {\isasymRightarrow}\ prop} & universal quantification (binder \isa{{\isasymAnd}}) \\
+  \isa{{\isasymLongrightarrow}\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop\ {\isasymRightarrow}\ prop} & implication (right associative infix) \\
+  \isa{{\isasymequiv}\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ prop} & equality relation (infix) \\
+  \end{tabular}
+  \caption{Primitive connectives of Pure}\label{fig:pure-connectives}
+  \end{center}
+  \end{figure}
+
+  \begin{figure}[htb]
+  \begin{center}
+  \[
+  \infer[\isa{{\isacharparenleft}axiom{\isacharparenright}}]{\isa{{\isasymturnstile}\ A}}{\isa{A\ {\isasymin}\ {\isasymTheta}}}
+  \qquad
+  \infer[\isa{{\isacharparenleft}assume{\isacharparenright}}]{\isa{A\ {\isasymturnstile}\ A}}{}
+  \]
+  \[
+  \infer[\isa{{\isacharparenleft}{\isasymAnd}{\isacharunderscore}intro{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ b{\isacharbrackleft}x{\isacharbrackright}} & \isa{x\ {\isasymnotin}\ {\isasymGamma}}}
+  \qquad
+  \infer[\isa{{\isacharparenleft}{\isasymAnd}{\isacharunderscore}elim{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ b{\isacharbrackleft}a{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}}}
+  \]
+  \[
+  \infer[\isa{{\isacharparenleft}{\isasymLongrightarrow}{\isacharunderscore}intro{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isacharminus}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
+  \qquad
+  \infer[\isa{{\isacharparenleft}{\isasymLongrightarrow}{\isacharunderscore}elim{\isacharparenright}}]{\isa{{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymunion}\ {\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ B}}{\isa{{\isasymGamma}\isactrlsub {\isadigit{1}}\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B} & \isa{{\isasymGamma}\isactrlsub {\isadigit{2}}\ {\isasymturnstile}\ A}}
+  \]
+  \caption{Primitive inferences of Pure}\label{fig:prim-rules}
+  \end{center}
+  \end{figure}
+
+  \begin{figure}[htb]
+  \begin{center}
+  \begin{tabular}{ll}
+  \isa{{\isasymturnstile}\ {\isacharparenleft}{\isasymlambda}x{\isachardot}\ b{\isacharbrackleft}x{\isacharbrackright}{\isacharparenright}\ a\ {\isasymequiv}\ b{\isacharbrackleft}a{\isacharbrackright}} & \isa{{\isasymbeta}}-conversion \\
+  \isa{{\isasymturnstile}\ x\ {\isasymequiv}\ x} & reflexivity \\
+  \isa{{\isasymturnstile}\ x\ {\isasymequiv}\ y\ {\isasymLongrightarrow}\ P\ x\ {\isasymLongrightarrow}\ P\ y} & substitution \\
+  \isa{{\isasymturnstile}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ f\ x\ {\isasymequiv}\ g\ x{\isacharparenright}\ {\isasymLongrightarrow}\ f\ {\isasymequiv}\ g} & extensionality \\
+  \isa{{\isasymturnstile}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}B\ {\isasymLongrightarrow}\ A{\isacharparenright}\ {\isasymLongrightarrow}\ A\ {\isasymequiv}\ B} & logical equivalence \\
+  \end{tabular}
+  \caption{Conceptual axiomatization of Pure equality}\label{fig:pure-equality}
+  \end{center}
+  \end{figure}
+
+  The introduction and elimination rules for \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}} are analogous to formation of dependently typed \isa{{\isasymlambda}}-terms representing the underlying proof objects.  Proof terms
+  are irrelevant in the Pure logic, though; they cannot occur within
+  propositions.  The system provides a runtime option to record
+  explicit proof terms for primitive inferences.  Thus all three
+  levels of \isa{{\isasymlambda}}-calculus become explicit: \isa{{\isasymRightarrow}} for
+  terms, and \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} for proofs (cf.\
+  \cite{Berghofer-Nipkow:2000:TPHOL}).
+
+  Observe that locally fixed parameters (as in \isa{{\isasymAnd}{\isacharunderscore}intro}) need
+  not be recorded in the hypotheses, because the simple syntactic
+  types of Pure are always inhabitable.  ``Assumptions'' \isa{x\ {\isacharcolon}{\isacharcolon}\ {\isasymtau}} for type-membership are only present as long as some \isa{x\isactrlisub {\isasymtau}} occurs in the statement body.\footnote{This is the key
+  difference to ``\isa{{\isasymlambda}HOL}'' in the PTS framework
+  \cite{Barendregt-Geuvers:2001}, where hypotheses \isa{x\ {\isacharcolon}\ A} are
+  treated uniformly for propositions and types.}
+
+  \medskip The axiomatization of a theory is implicitly closed by
+  forming all instances of type and term variables: \isa{{\isasymturnstile}\ A{\isasymvartheta}} holds for any substitution instance of an axiom
+  \isa{{\isasymturnstile}\ A}.  By pushing substitutions through derivations
+  inductively, we also get admissible \isa{generalize} and \isa{instance} rules as shown in \figref{fig:subst-rules}.
+
+  \begin{figure}[htb]
+  \begin{center}
+  \[
+  \infer{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}{\isasymalpha}{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isasymalpha}{\isacharbrackright}} & \isa{{\isasymalpha}\ {\isasymnotin}\ {\isasymGamma}}}
+  \quad
+  \infer[\quad\isa{{\isacharparenleft}generalize{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}x{\isacharbrackright}} & \isa{x\ {\isasymnotin}\ {\isasymGamma}}}
+  \]
+  \[
+  \infer{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isasymtau}{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}{\isasymalpha}{\isacharbrackright}}}
+  \quad
+  \infer[\quad\isa{{\isacharparenleft}instantiate{\isacharparenright}}]{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}t{\isacharbrackright}}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}}
+  \]
+  \caption{Admissible substitution rules}\label{fig:subst-rules}
+  \end{center}
+  \end{figure}
+
+  Note that \isa{instantiate} does not require an explicit
+  side-condition, because \isa{{\isasymGamma}} may never contain schematic
+  variables.
+
+  In principle, variables could be substituted in hypotheses as well,
+  but this would disrupt the monotonicity of reasoning: deriving
+  \isa{{\isasymGamma}{\isasymvartheta}\ {\isasymturnstile}\ B{\isasymvartheta}} from \isa{{\isasymGamma}\ {\isasymturnstile}\ B} is
+  correct, but \isa{{\isasymGamma}{\isasymvartheta}\ {\isasymsupseteq}\ {\isasymGamma}} does not necessarily hold:
+  the result belongs to a different proof context.
+
+  \medskip An \emph{oracle} is a function that produces axioms on the
+  fly.  Logically, this is an instance of the \isa{axiom} rule
+  (\figref{fig:prim-rules}), but there is an operational difference.
+  The system always records oracle invocations within derivations of
+  theorems by a unique tag.
+
+  Axiomatizations should be limited to the bare minimum, typically as
+  part of the initial logical basis of an object-logic formalization.
+  Later on, theories are usually developed in a strictly definitional
+  fashion, by stating only certain equalities over new constants.
+
+  A \emph{simple definition} consists of a constant declaration \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} together with an axiom \isa{{\isasymturnstile}\ c\ {\isasymequiv}\ t}, where \isa{t\ {\isacharcolon}{\isacharcolon}\ {\isasymsigma}} is a closed term without any hidden polymorphism.  The RHS
+  may depend on further defined constants, but not \isa{c} itself.
+  Definitions of functions may be presented as \isa{c\ \isactrlvec x\ {\isasymequiv}\ t} instead of the puristic \isa{c\ {\isasymequiv}\ {\isasymlambda}\isactrlvec x{\isachardot}\ t}.
+
+  An \emph{overloaded definition} consists of a collection of axioms
+  for the same constant, with zero or one equations \isa{c{\isacharparenleft}{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharparenright}{\isasymkappa}{\isacharparenright}\ {\isasymequiv}\ t} for each type constructor \isa{{\isasymkappa}} (for
+  distinct variables \isa{\isactrlvec {\isasymalpha}}).  The RHS may mention
+  previously defined constants as above, or arbitrary constants \isa{d{\isacharparenleft}{\isasymalpha}\isactrlisub i{\isacharparenright}} for some \isa{{\isasymalpha}\isactrlisub i} projected from \isa{\isactrlvec {\isasymalpha}}.  Thus overloaded definitions essentially work by
+  primitive recursion over the syntactic structure of a single type
+  argument.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{ctyp}\verb|type ctyp| \\
+  \indexdef{}{ML type}{cterm}\verb|type cterm| \\
+  \indexdef{}{ML}{Thm.ctyp\_of}\verb|Thm.ctyp_of: theory -> typ -> ctyp| \\
+  \indexdef{}{ML}{Thm.cterm\_of}\verb|Thm.cterm_of: theory -> term -> cterm| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{thm}\verb|type thm| \\
+  \indexdef{}{ML}{proofs}\verb|proofs: int ref| \\
+  \indexdef{}{ML}{Thm.assume}\verb|Thm.assume: cterm -> thm| \\
+  \indexdef{}{ML}{Thm.forall\_intr}\verb|Thm.forall_intr: cterm -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.forall\_elim}\verb|Thm.forall_elim: cterm -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.implies\_intr}\verb|Thm.implies_intr: cterm -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.implies\_elim}\verb|Thm.implies_elim: thm -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.generalize}\verb|Thm.generalize: string list * string list -> int -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.instantiate}\verb|Thm.instantiate: (ctyp * ctyp) list * (cterm * cterm) list -> thm -> thm| \\
+  \indexdef{}{ML}{Thm.axiom}\verb|Thm.axiom: theory -> string -> thm| \\
+  \indexdef{}{ML}{Thm.add\_oracle}\verb|Thm.add_oracle: binding * ('a -> cterm) -> theory|\isasep\isanewline%
+\verb|  -> (string * ('a -> thm)) * theory| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML}{Theory.add\_axioms\_i}\verb|Theory.add_axioms_i: (binding * term) list -> theory -> theory| \\
+  \indexdef{}{ML}{Theory.add\_deps}\verb|Theory.add_deps: string -> string * typ -> (string * typ) list -> theory -> theory| \\
+  \indexdef{}{ML}{Theory.add\_defs\_i}\verb|Theory.add_defs_i: bool -> bool -> (binding * term) list -> theory -> theory| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|ctyp| and \verb|cterm| represent certified types
+  and terms, respectively.  These are abstract datatypes that
+  guarantee that its values have passed the full well-formedness (and
+  well-typedness) checks, relative to the declarations of type
+  constructors, constants etc. in the theory.
+
+  \item \verb|Thm.ctyp_of|~\isa{thy\ {\isasymtau}} and \verb|Thm.cterm_of|~\isa{thy\ t} explicitly checks types and terms,
+  respectively.  This also involves some basic normalizations, such
+  expansion of type and term abbreviations from the theory context.
+
+  Re-certification is relatively slow and should be avoided in tight
+  reasoning loops.  There are separate operations to decompose
+  certified entities (including actual theorems).
+
+  \item \verb|thm| represents proven propositions.  This is an
+  abstract datatype that guarantees that its values have been
+  constructed by basic principles of the \verb|Thm| module.
+  Every \verb|thm| value contains a sliding back-reference to the
+  enclosing theory, cf.\ \secref{sec:context-theory}.
+
+  \item \verb|proofs| determines the detail of proof recording within
+  \verb|thm| values: \verb|0| records only the names of oracles,
+  \verb|1| records oracle names and propositions, \verb|2| additionally
+  records full proof terms.  Officially named theorems that contribute
+  to a result are always recorded.
+
+  \item \verb|Thm.assume|, \verb|Thm.forall_intr|, \verb|Thm.forall_elim|, \verb|Thm.implies_intr|, and \verb|Thm.implies_elim|
+  correspond to the primitive inferences of \figref{fig:prim-rules}.
+
+  \item \verb|Thm.generalize|~\isa{{\isacharparenleft}\isactrlvec {\isasymalpha}{\isacharcomma}\ \isactrlvec x{\isacharparenright}}
+  corresponds to the \isa{generalize} rules of
+  \figref{fig:subst-rules}.  Here collections of type and term
+  variables are generalized simultaneously, specified by the given
+  basic names.
+
+  \item \verb|Thm.instantiate|~\isa{{\isacharparenleft}\isactrlvec {\isasymalpha}\isactrlisub s{\isacharcomma}\ \isactrlvec x\isactrlisub {\isasymtau}{\isacharparenright}} corresponds to the \isa{instantiate} rules
+  of \figref{fig:subst-rules}.  Type variables are substituted before
+  term variables.  Note that the types in \isa{\isactrlvec x\isactrlisub {\isasymtau}}
+  refer to the instantiated versions.
+
+  \item \verb|Thm.axiom|~\isa{thy\ name} retrieves a named
+  axiom, cf.\ \isa{axiom} in \figref{fig:prim-rules}.
+
+  \item \verb|Thm.add_oracle|~\isa{{\isacharparenleft}binding{\isacharcomma}\ oracle{\isacharparenright}} produces a named
+  oracle rule, essentially generating arbitrary axioms on the fly,
+  cf.\ \isa{axiom} in \figref{fig:prim-rules}.
+
+  \item \verb|Theory.add_axioms_i|~\isa{{\isacharbrackleft}{\isacharparenleft}name{\isacharcomma}\ A{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} declares
+  arbitrary propositions as axioms.
+
+  \item \verb|Theory.add_deps|~\isa{name\ c\isactrlisub {\isasymtau}\ \isactrlvec d\isactrlisub {\isasymsigma}} declares dependencies of a named specification
+  for constant \isa{c\isactrlisub {\isasymtau}}, relative to existing
+  specifications for constants \isa{\isactrlvec d\isactrlisub {\isasymsigma}}.
+
+  \item \verb|Theory.add_defs_i|~\isa{unchecked\ overloaded\ {\isacharbrackleft}{\isacharparenleft}name{\isacharcomma}\ c\ \isactrlvec x\ {\isasymequiv}\ t{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharbrackright}} states a definitional axiom for an existing
+  constant \isa{c}.  Dependencies are recorded (cf.\ \verb|Theory.add_deps|), unless the \isa{unchecked} option is set.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Auxiliary definitions%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Theory \isa{Pure} provides a few auxiliary definitions, see
+  \figref{fig:pure-aux}.  These special constants are normally not
+  exposed to the user, but appear in internal encodings.
+
+  \begin{figure}[htb]
+  \begin{center}
+  \begin{tabular}{ll}
+  \isa{conjunction\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop\ {\isasymRightarrow}\ prop} & (infix \isa{{\isacharampersand}}) \\
+  \isa{{\isasymturnstile}\ A\ {\isacharampersand}\ B\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}C{\isachardot}\ {\isacharparenleft}A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ C{\isacharparenright}\ {\isasymLongrightarrow}\ C{\isacharparenright}} \\[1ex]
+  \isa{prop\ {\isacharcolon}{\isacharcolon}\ prop\ {\isasymRightarrow}\ prop} & (prefix \isa{{\isacharhash}}, suppressed) \\
+  \isa{{\isacharhash}A\ {\isasymequiv}\ A} \\[1ex]
+  \isa{term\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ {\isasymRightarrow}\ prop} & (prefix \isa{TERM}) \\
+  \isa{term\ x\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}A{\isachardot}\ A\ {\isasymLongrightarrow}\ A{\isacharparenright}} \\[1ex]
+  \isa{TYPE\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ itself} & (prefix \isa{TYPE}) \\
+  \isa{{\isacharparenleft}unspecified{\isacharparenright}} \\
+  \end{tabular}
+  \caption{Definitions of auxiliary connectives}\label{fig:pure-aux}
+  \end{center}
+  \end{figure}
+
+  Derived conjunction rules include introduction \isa{A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ A\ {\isacharampersand}\ B}, and destructions \isa{A\ {\isacharampersand}\ B\ {\isasymLongrightarrow}\ A} and \isa{A\ {\isacharampersand}\ B\ {\isasymLongrightarrow}\ B}.
+  Conjunction allows to treat simultaneous assumptions and conclusions
+  uniformly.  For example, multiple claims are intermediately
+  represented as explicit conjunction, but this is refined into
+  separate sub-goals before the user continues the proof; the final
+  result is projected into a list of theorems (cf.\
+  \secref{sec:tactical-goals}).
+
+  The \isa{prop} marker (\isa{{\isacharhash}}) makes arbitrarily complex
+  propositions appear as atomic, without changing the meaning: \isa{{\isasymGamma}\ {\isasymturnstile}\ A} and \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isacharhash}A} are interchangeable.  See
+  \secref{sec:tactical-goals} for specific operations.
+
+  The \isa{term} marker turns any well-typed term into a derivable
+  proposition: \isa{{\isasymturnstile}\ TERM\ t} holds unconditionally.  Although
+  this is logically vacuous, it allows to treat terms and proofs
+  uniformly, similar to a type-theoretic framework.
+
+  The \isa{TYPE} constructor is the canonical representative of
+  the unspecified type \isa{{\isasymalpha}\ itself}; it essentially injects the
+  language of types into that of terms.  There is specific notation
+  \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} for \isa{TYPE\isactrlbsub {\isasymtau}\ itself\isactrlesub }.
+  Although being devoid of any particular meaning, the \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} accounts for the type \isa{{\isasymtau}} within the term
+  language.  In particular, \isa{TYPE{\isacharparenleft}{\isasymalpha}{\isacharparenright}} may be used as formal
+  argument in primitive definitions, in order to circumvent hidden
+  polymorphism (cf.\ \secref{sec:terms}).  For example, \isa{c\ TYPE{\isacharparenleft}{\isasymalpha}{\isacharparenright}\ {\isasymequiv}\ A{\isacharbrackleft}{\isasymalpha}{\isacharbrackright}} defines \isa{c\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}\ itself\ {\isasymRightarrow}\ prop} in terms of
+  a proposition \isa{A} that depends on an additional type
+  argument, which is essentially a predicate on types.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{Conjunction.intr}\verb|Conjunction.intr: thm -> thm -> thm| \\
+  \indexdef{}{ML}{Conjunction.elim}\verb|Conjunction.elim: thm -> thm * thm| \\
+  \indexdef{}{ML}{Drule.mk\_term}\verb|Drule.mk_term: cterm -> thm| \\
+  \indexdef{}{ML}{Drule.dest\_term}\verb|Drule.dest_term: thm -> cterm| \\
+  \indexdef{}{ML}{Logic.mk\_type}\verb|Logic.mk_type: typ -> term| \\
+  \indexdef{}{ML}{Logic.dest\_type}\verb|Logic.dest_type: term -> typ| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Conjunction.intr| derives \isa{A\ {\isacharampersand}\ B} from \isa{A} and \isa{B}.
+
+  \item \verb|Conjunction.elim| derives \isa{A} and \isa{B}
+  from \isa{A\ {\isacharampersand}\ B}.
+
+  \item \verb|Drule.mk_term| derives \isa{TERM\ t}.
+
+  \item \verb|Drule.dest_term| recovers term \isa{t} from \isa{TERM\ t}.
+
+  \item \verb|Logic.mk_type|~\isa{{\isasymtau}} produces the term \isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}}.
+
+  \item \verb|Logic.dest_type|~\isa{TYPE{\isacharparenleft}{\isasymtau}{\isacharparenright}} recovers the type
+  \isa{{\isasymtau}}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Object-level rules \label{sec:obj-rules}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The primitive inferences covered so far mostly serve foundational
+  purposes.  User-level reasoning usually works via object-level rules
+  that are represented as theorems of Pure.  Composition of rules
+  involves \emph{backchaining}, \emph{higher-order unification} modulo
+  \isa{{\isasymalpha}{\isasymbeta}{\isasymeta}}-conversion of \isa{{\isasymlambda}}-terms, and so-called
+  \emph{lifting} of rules into a context of \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}} connectives.  Thus the full power of higher-order Natural
+  Deduction in Isabelle/Pure becomes readily available.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Hereditary Harrop Formulae%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The idea of object-level rules is to model Natural Deduction
+  inferences in the style of Gentzen \cite{Gentzen:1935}, but we allow
+  arbitrary nesting similar to \cite{extensions91}.  The most basic
+  rule format is that of a \emph{Horn Clause}:
+  \[
+  \infer{\isa{A}}{\isa{A\isactrlsub {\isadigit{1}}} & \isa{{\isasymdots}} & \isa{A\isactrlsub n}}
+  \]
+  where \isa{A{\isacharcomma}\ A\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlsub n} are atomic propositions
+  of the framework, usually of the form \isa{Trueprop\ B}, where
+  \isa{B} is a (compound) object-level statement.  This
+  object-level inference corresponds to an iterated implication in
+  Pure like this:
+  \[
+  \isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ A\isactrlsub n\ {\isasymLongrightarrow}\ A}
+  \]
+  As an example consider conjunction introduction: \isa{A\ {\isasymLongrightarrow}\ B\ {\isasymLongrightarrow}\ A\ {\isasymand}\ B}.  Any parameters occurring in such rule statements are
+  conceptionally treated as arbitrary:
+  \[
+  \isa{{\isasymAnd}x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ x\isactrlsub m{\isachardot}\ A\isactrlsub {\isadigit{1}}\ x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ x\isactrlsub m\ {\isasymLongrightarrow}\ {\isasymdots}\ A\isactrlsub n\ x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ x\isactrlsub m\ {\isasymLongrightarrow}\ A\ x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ x\isactrlsub m}
+  \]
+
+  Nesting of rules means that the positions of \isa{A\isactrlsub i} may
+  again hold compound rules, not just atomic propositions.
+  Propositions of this format are called \emph{Hereditary Harrop
+  Formulae} in the literature \cite{Miller:1991}.  Here we give an
+  inductive characterization as follows:
+
+  \medskip
+  \begin{tabular}{ll}
+  \isa{\isactrlbold x} & set of variables \\
+  \isa{\isactrlbold A} & set of atomic propositions \\
+  \isa{\isactrlbold H\ \ {\isacharequal}\ \ {\isasymAnd}\isactrlbold x\isactrlsup {\isacharasterisk}{\isachardot}\ \isactrlbold H\isactrlsup {\isacharasterisk}\ {\isasymLongrightarrow}\ \isactrlbold A} & set of Hereditary Harrop Formulas \\
+  \end{tabular}
+  \medskip
+
+  \noindent Thus we essentially impose nesting levels on propositions
+  formed from \isa{{\isasymAnd}} and \isa{{\isasymLongrightarrow}}.  At each level there is a
+  prefix of parameters and compound premises, concluding an atomic
+  proposition.  Typical examples are \isa{{\isasymlongrightarrow}}-introduction \isa{{\isacharparenleft}A\ {\isasymLongrightarrow}\ B{\isacharparenright}\ {\isasymLongrightarrow}\ A\ {\isasymlongrightarrow}\ B} or mathematical induction \isa{P\ {\isadigit{0}}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}n{\isachardot}\ P\ n\ {\isasymLongrightarrow}\ P\ {\isacharparenleft}Suc\ n{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ P\ n}.  Even deeper nesting occurs in well-founded
+  induction \isa{{\isacharparenleft}{\isasymAnd}x{\isachardot}\ {\isacharparenleft}{\isasymAnd}y{\isachardot}\ y\ {\isasymprec}\ x\ {\isasymLongrightarrow}\ P\ y{\isacharparenright}\ {\isasymLongrightarrow}\ P\ x{\isacharparenright}\ {\isasymLongrightarrow}\ P\ x}, but this
+  already marks the limit of rule complexity seen in practice.
+
+  \medskip Regular user-level inferences in Isabelle/Pure always
+  maintain the following canonical form of results:
+
+  \begin{itemize}
+
+  \item Normalization by \isa{{\isacharparenleft}A\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ B\ x{\isacharparenright}{\isacharparenright}\ {\isasymequiv}\ {\isacharparenleft}{\isasymAnd}x{\isachardot}\ A\ {\isasymLongrightarrow}\ B\ x{\isacharparenright}},
+  which is a theorem of Pure, means that quantifiers are pushed in
+  front of implication at each level of nesting.  The normal form is a
+  Hereditary Harrop Formula.
+
+  \item The outermost prefix of parameters is represented via
+  schematic variables: instead of \isa{{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ A\ \isactrlvec x} we have \isa{\isactrlvec H\ {\isacharquery}\isactrlvec x\ {\isasymLongrightarrow}\ A\ {\isacharquery}\isactrlvec x}.
+  Note that this representation looses information about the order of
+  parameters, and vacuous quantifiers vanish automatically.
+
+  \end{itemize}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{MetaSimplifier.norm\_hhf}\verb|MetaSimplifier.norm_hhf: thm -> thm| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|MetaSimplifier.norm_hhf|~\isa{thm} normalizes the given
+  theorem according to the canonical form specified above.  This is
+  occasionally helpful to repair some low-level tools that do not
+  handle Hereditary Harrop Formulae properly.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Rule composition%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The rule calculus of Isabelle/Pure provides two main inferences:
+  \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} (i.e.\ back-chaining of rules) and
+  \hyperlink{inference.assumption}{\mbox{\isa{assumption}}} (i.e.\ closing a branch), both modulo
+  higher-order unification.  There are also combined variants, notably
+  \hyperlink{inference.elim-resolution}{\mbox{\isa{elim{\isacharunderscore}resolution}}} and \hyperlink{inference.dest-resolution}{\mbox{\isa{dest{\isacharunderscore}resolution}}}.
+
+  To understand the all-important \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} principle,
+  we first consider raw \indexdef{}{inference}{composition}\hypertarget{inference.composition}{\hyperlink{inference.composition}{\mbox{\isa{composition}}}} (modulo
+  higher-order unification with substitution \isa{{\isasymvartheta}}):
+  \[
+  \infer[(\indexdef{}{inference}{composition}\hypertarget{inference.composition}{\hyperlink{inference.composition}{\mbox{\isa{composition}}}})]{\isa{\isactrlvec A{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}}}
+  {\isa{\isactrlvec A\ {\isasymLongrightarrow}\ B} & \isa{B{\isacharprime}\ {\isasymLongrightarrow}\ C} & \isa{B{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}}}
+  \]
+  Here the conclusion of the first rule is unified with the premise of
+  the second; the resulting rule instance inherits the premises of the
+  first and conclusion of the second.  Note that \isa{C} can again
+  consist of iterated implications.  We can also permute the premises
+  of the second rule back-and-forth in order to compose with \isa{B{\isacharprime}} in any position (subsequently we shall always refer to
+  position 1 w.l.o.g.).
+
+  In \hyperlink{inference.composition}{\mbox{\isa{composition}}} the internal structure of the common
+  part \isa{B} and \isa{B{\isacharprime}} is not taken into account.  For
+  proper \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} we require \isa{B} to be atomic,
+  and explicitly observe the structure \isa{{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ B{\isacharprime}\ \isactrlvec x} of the premise of the second rule.  The
+  idea is to adapt the first rule by ``lifting'' it into this context,
+  by means of iterated application of the following inferences:
+  \[
+  \infer[(\indexdef{}{inference}{imp\_lift}\hypertarget{inference.imp-lift}{\hyperlink{inference.imp-lift}{\mbox{\isa{imp{\isacharunderscore}lift}}}})]{\isa{{\isacharparenleft}\isactrlvec H\ {\isasymLongrightarrow}\ \isactrlvec A{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}\isactrlvec H\ {\isasymLongrightarrow}\ B{\isacharparenright}}}{\isa{\isactrlvec A\ {\isasymLongrightarrow}\ B}}
+  \]
+  \[
+  \infer[(\indexdef{}{inference}{all\_lift}\hypertarget{inference.all-lift}{\hyperlink{inference.all-lift}{\mbox{\isa{all{\isacharunderscore}lift}}}})]{\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec A\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}}}{\isa{\isactrlvec A\ {\isacharquery}\isactrlvec a\ {\isasymLongrightarrow}\ B\ {\isacharquery}\isactrlvec a}}
+  \]
+  By combining raw composition with lifting, we get full \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} as follows:
+  \[
+  \infer[(\indexdef{}{inference}{resolution}\hypertarget{inference.resolution}{\hyperlink{inference.resolution}{\mbox{\isa{resolution}}}})]
+  {\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ \isactrlvec A\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isasymLongrightarrow}\ C{\isasymvartheta}}}
+  {\begin{tabular}{l}
+    \isa{\isactrlvec A\ {\isacharquery}\isactrlvec a\ {\isasymLongrightarrow}\ B\ {\isacharquery}\isactrlvec a} \\
+    \isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ B{\isacharprime}\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C} \\
+    \isa{{\isacharparenleft}{\isasymlambda}\isactrlvec x{\isachardot}\ B\ {\isacharparenleft}{\isacharquery}\isactrlvec a\ \isactrlvec x{\isacharparenright}{\isacharparenright}{\isasymvartheta}\ {\isacharequal}\ B{\isacharprime}{\isasymvartheta}} \\
+   \end{tabular}}
+  \]
+
+  Continued resolution of rules allows to back-chain a problem towards
+  more and sub-problems.  Branches are closed either by resolving with
+  a rule of 0 premises, or by producing a ``short-circuit'' within a
+  solved situation (again modulo unification):
+  \[
+  \infer[(\indexdef{}{inference}{assumption}\hypertarget{inference.assumption}{\hyperlink{inference.assumption}{\mbox{\isa{assumption}}}})]{\isa{C{\isasymvartheta}}}
+  {\isa{{\isacharparenleft}{\isasymAnd}\isactrlvec x{\isachardot}\ \isactrlvec H\ \isactrlvec x\ {\isasymLongrightarrow}\ A\ \isactrlvec x{\isacharparenright}\ {\isasymLongrightarrow}\ C} & \isa{A{\isasymvartheta}\ {\isacharequal}\ H\isactrlsub i{\isasymvartheta}}~~\text{(for some~\isa{i})}}
+  \]
+
+  FIXME \indexdef{}{inference}{elim\_resolution}\hypertarget{inference.elim-resolution}{\hyperlink{inference.elim-resolution}{\mbox{\isa{elim{\isacharunderscore}resolution}}}}, \indexdef{}{inference}{dest\_resolution}\hypertarget{inference.dest-resolution}{\hyperlink{inference.dest-resolution}{\mbox{\isa{dest{\isacharunderscore}resolution}}}}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{op RS}\verb|op RS: thm * thm -> thm| \\
+  \indexdef{}{ML}{op OF}\verb|op OF: thm * thm list -> thm| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \isa{rule\isactrlsub {\isadigit{1}}\ RS\ rule\isactrlsub {\isadigit{2}}} resolves \isa{rule\isactrlsub {\isadigit{1}}} with \isa{rule\isactrlsub {\isadigit{2}}} according to the
+  \hyperlink{inference.resolution}{\mbox{\isa{resolution}}} principle explained above.  Note that the
+  corresponding attribute in the Isar language is called \hyperlink{attribute.THEN}{\mbox{\isa{THEN}}}.
+
+  \item \isa{rule\ OF\ rules} resolves a list of rules with the
+  first rule, addressing its premises \isa{{\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ length\ rules}
+  (operating from last to first).  This means the newly emerging
+  premises are all concatenated, without interfering.  Also note that
+  compared to \isa{RS}, the rule argument order is swapped: \isa{rule\isactrlsub {\isadigit{1}}\ RS\ rule\isactrlsub {\isadigit{2}}\ {\isacharequal}\ rule\isactrlsub {\isadigit{2}}\ OF\ {\isacharbrackleft}rule\isactrlsub {\isadigit{1}}{\isacharbrackright}}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Prelim.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,897 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Prelim}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Prelim\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{Preliminaries%
+}
+\isamarkuptrue%
+%
+\isamarkupsection{Contexts \label{sec:context}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A logical context represents the background that is required for
+  formulating statements and composing proofs.  It acts as a medium to
+  produce formal content, depending on earlier material (declarations,
+  results etc.).
+
+  For example, derivations within the Isabelle/Pure logic can be
+  described as a judgment \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}}, which means that a
+  proposition \isa{{\isasymphi}} is derivable from hypotheses \isa{{\isasymGamma}}
+  within the theory \isa{{\isasymTheta}}.  There are logical reasons for
+  keeping \isa{{\isasymTheta}} and \isa{{\isasymGamma}} separate: theories can be
+  liberal about supporting type constructors and schematic
+  polymorphism of constants and axioms, while the inner calculus of
+  \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}} is strictly limited to Simple Type Theory (with
+  fixed type variables in the assumptions).
+
+  \medskip Contexts and derivations are linked by the following key
+  principles:
+
+  \begin{itemize}
+
+  \item Transfer: monotonicity of derivations admits results to be
+  transferred into a \emph{larger} context, i.e.\ \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}} implies \isa{{\isasymGamma}{\isacharprime}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\isactrlsub {\isacharprime}\ {\isasymphi}} for contexts \isa{{\isasymTheta}{\isacharprime}\ {\isasymsupseteq}\ {\isasymTheta}} and \isa{{\isasymGamma}{\isacharprime}\ {\isasymsupseteq}\ {\isasymGamma}}.
+
+  \item Export: discharge of hypotheses admits results to be exported
+  into a \emph{smaller} context, i.e.\ \isa{{\isasymGamma}{\isacharprime}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymphi}}
+  implies \isa{{\isasymGamma}\ {\isasymturnstile}\isactrlsub {\isasymTheta}\ {\isasymDelta}\ {\isasymLongrightarrow}\ {\isasymphi}} where \isa{{\isasymGamma}{\isacharprime}\ {\isasymsupseteq}\ {\isasymGamma}} and
+  \isa{{\isasymDelta}\ {\isacharequal}\ {\isasymGamma}{\isacharprime}\ {\isacharminus}\ {\isasymGamma}}.  Note that \isa{{\isasymTheta}} remains unchanged here,
+  only the \isa{{\isasymGamma}} part is affected.
+
+  \end{itemize}
+
+  \medskip By modeling the main characteristics of the primitive
+  \isa{{\isasymTheta}} and \isa{{\isasymGamma}} above, and abstracting over any
+  particular logical content, we arrive at the fundamental notions of
+  \emph{theory context} and \emph{proof context} in Isabelle/Isar.
+  These implement a certain policy to manage arbitrary \emph{context
+  data}.  There is a strongly-typed mechanism to declare new kinds of
+  data at compile time.
+
+  The internal bootstrap process of Isabelle/Pure eventually reaches a
+  stage where certain data slots provide the logical content of \isa{{\isasymTheta}} and \isa{{\isasymGamma}} sketched above, but this does not stop there!
+  Various additional data slots support all kinds of mechanisms that
+  are not necessarily part of the core logic.
+
+  For example, there would be data for canonical introduction and
+  elimination rules for arbitrary operators (depending on the
+  object-logic and application), which enables users to perform
+  standard proof steps implicitly (cf.\ the \isa{rule} method
+  \cite{isabelle-isar-ref}).
+
+  \medskip Thus Isabelle/Isar is able to bring forth more and more
+  concepts successively.  In particular, an object-logic like
+  Isabelle/HOL continues the Isabelle/Pure setup by adding specific
+  components for automated reasoning (classical reasoner, tableau
+  prover, structured induction etc.) and derived specification
+  mechanisms (inductive predicates, recursive functions etc.).  All of
+  this is ultimately based on the generic data management by theory
+  and proof contexts introduced here.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Theory context \label{sec:context-theory}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{theory} is a data container with explicit name and unique
+  identifier.  Theories are related by a (nominal) sub-theory
+  relation, which corresponds to the dependency graph of the original
+  construction; each theory is derived from a certain sub-graph of
+  ancestor theories.
+
+  The \isa{merge} operation produces the least upper bound of two
+  theories, which actually degenerates into absorption of one theory
+  into the other (due to the nominal sub-theory relation).
+
+  The \isa{begin} operation starts a new theory by importing
+  several parent theories and entering a special \isa{draft} mode,
+  which is sustained until the final \isa{end} operation.  A draft
+  theory acts like a linear type, where updates invalidate earlier
+  versions.  An invalidated draft is called ``stale''.
+
+  The \isa{checkpoint} operation produces an intermediate stepping
+  stone that will survive the next update: both the original and the
+  changed theory remain valid and are related by the sub-theory
+  relation.  Checkpointing essentially recovers purely functional
+  theory values, at the expense of some extra internal bookkeeping.
+
+  The \isa{copy} operation produces an auxiliary version that has
+  the same data content, but is unrelated to the original: updates of
+  the copy do not affect the original, neither does the sub-theory
+  relation hold.
+
+  \medskip The example in \figref{fig:ex-theory} below shows a theory
+  graph derived from \isa{Pure}, with theory \isa{Length}
+  importing \isa{Nat} and \isa{List}.  The body of \isa{Length} consists of a sequence of updates, working mostly on
+  drafts.  Intermediate checkpoints may occur as well, due to the
+  history mechanism provided by the Isar top-level, cf.\
+  \secref{sec:isar-toplevel}.
+
+  \begin{figure}[htb]
+  \begin{center}
+  \begin{tabular}{rcccl}
+        &            & \isa{Pure} \\
+        &            & \isa{{\isasymdown}} \\
+        &            & \isa{FOL} \\
+        & $\swarrow$ &              & $\searrow$ & \\
+  \isa{Nat} &    &              &            & \isa{List} \\
+        & $\searrow$ &              & $\swarrow$ \\
+        &            & \isa{Length} \\
+        &            & \multicolumn{3}{l}{~~\hyperlink{keyword.imports}{\mbox{\isa{\isakeyword{imports}}}}} \\
+        &            & \multicolumn{3}{l}{~~\hyperlink{keyword.begin}{\mbox{\isa{\isakeyword{begin}}}}} \\
+        &            & $\vdots$~~ \\
+        &            & \isa{{\isasymbullet}}~~ \\
+        &            & $\vdots$~~ \\
+        &            & \isa{{\isasymbullet}}~~ \\
+        &            & $\vdots$~~ \\
+        &            & \multicolumn{3}{l}{~~\hyperlink{command.end}{\mbox{\isa{\isacommand{end}}}}} \\
+  \end{tabular}
+  \caption{A theory definition depending on ancestors}\label{fig:ex-theory}
+  \end{center}
+  \end{figure}
+
+  \medskip There is a separate notion of \emph{theory reference} for
+  maintaining a live link to an evolving theory context: updates on
+  drafts are propagated automatically.  Dynamic updating stops after
+  an explicit \isa{end} only.
+
+  Derived entities may store a theory reference in order to indicate
+  the context they belong to.  This implicitly assumes monotonic
+  reasoning, because the referenced context may become larger without
+  further notice.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{theory}\verb|type theory| \\
+  \indexdef{}{ML}{Theory.subthy}\verb|Theory.subthy: theory * theory -> bool| \\
+  \indexdef{}{ML}{Theory.merge}\verb|Theory.merge: theory * theory -> theory| \\
+  \indexdef{}{ML}{Theory.checkpoint}\verb|Theory.checkpoint: theory -> theory| \\
+  \indexdef{}{ML}{Theory.copy}\verb|Theory.copy: theory -> theory| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{theory\_ref}\verb|type theory_ref| \\
+  \indexdef{}{ML}{Theory.deref}\verb|Theory.deref: theory_ref -> theory| \\
+  \indexdef{}{ML}{Theory.check\_thy}\verb|Theory.check_thy: theory -> theory_ref| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|theory| represents theory contexts.  This is
+  essentially a linear type!  Most operations destroy the original
+  version, which then becomes ``stale''.
+
+  \item \verb|Theory.subthy|~\isa{{\isacharparenleft}thy\isactrlsub {\isadigit{1}}{\isacharcomma}\ thy\isactrlsub {\isadigit{2}}{\isacharparenright}}
+  compares theories according to the inherent graph structure of the
+  construction.  This sub-theory relation is a nominal approximation
+  of inclusion (\isa{{\isasymsubseteq}}) of the corresponding content.
+
+  \item \verb|Theory.merge|~\isa{{\isacharparenleft}thy\isactrlsub {\isadigit{1}}{\isacharcomma}\ thy\isactrlsub {\isadigit{2}}{\isacharparenright}}
+  absorbs one theory into the other.  This fails for unrelated
+  theories!
+
+  \item \verb|Theory.checkpoint|~\isa{thy} produces a safe
+  stepping stone in the linear development of \isa{thy}.  The next
+  update will result in two related, valid theories.
+
+  \item \verb|Theory.copy|~\isa{thy} produces a variant of \isa{thy} that holds a copy of the same data.  The result is not
+  related to the original; the original is unchanged.
+
+  \item \verb|theory_ref| represents a sliding reference to an
+  always valid theory; updates on the original are propagated
+  automatically.
+
+  \item \verb|Theory.deref|~\isa{thy{\isacharunderscore}ref} turns a \verb|theory_ref| into an \verb|theory| value.  As the referenced
+  theory evolves monotonically over time, later invocations of \verb|Theory.deref| may refer to a larger context.
+
+  \item \verb|Theory.check_thy|~\isa{thy} produces a \verb|theory_ref| from a valid \verb|theory| value.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Proof context \label{sec:context-proof}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A proof context is a container for pure data with a back-reference
+  to the theory it belongs to.  The \isa{init} operation creates a
+  proof context from a given theory.  Modifications to draft theories
+  are propagated to the proof context as usual, but there is also an
+  explicit \isa{transfer} operation to force resynchronization
+  with more substantial updates to the underlying theory.  The actual
+  context data does not require any special bookkeeping, thanks to the
+  lack of destructive features.
+
+  Entities derived in a proof context need to record inherent logical
+  requirements explicitly, since there is no separate context
+  identification as for theories.  For example, hypotheses used in
+  primitive derivations (cf.\ \secref{sec:thms}) are recorded
+  separately within the sequent \isa{{\isasymGamma}\ {\isasymturnstile}\ {\isasymphi}}, just to make double
+  sure.  Results could still leak into an alien proof context due to
+  programming errors, but Isabelle/Isar includes some extra validity
+  checks in critical positions, notably at the end of a sub-proof.
+
+  Proof contexts may be manipulated arbitrarily, although the common
+  discipline is to follow block structure as a mental model: a given
+  context is extended consecutively, and results are exported back
+  into the original context.  Note that the Isar proof states model
+  block-structured reasoning explicitly, using a stack of proof
+  contexts internally.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{Proof.context}\verb|type Proof.context| \\
+  \indexdef{}{ML}{ProofContext.init}\verb|ProofContext.init: theory -> Proof.context| \\
+  \indexdef{}{ML}{ProofContext.theory\_of}\verb|ProofContext.theory_of: Proof.context -> theory| \\
+  \indexdef{}{ML}{ProofContext.transfer}\verb|ProofContext.transfer: theory -> Proof.context -> Proof.context| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Proof.context| represents proof contexts.  Elements
+  of this type are essentially pure values, with a sliding reference
+  to the background theory.
+
+  \item \verb|ProofContext.init|~\isa{thy} produces a proof context
+  derived from \isa{thy}, initializing all data.
+
+  \item \verb|ProofContext.theory_of|~\isa{ctxt} selects the
+  background theory from \isa{ctxt}, dereferencing its internal
+  \verb|theory_ref|.
+
+  \item \verb|ProofContext.transfer|~\isa{thy\ ctxt} promotes the
+  background theory of \isa{ctxt} to the super theory \isa{thy}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Generic contexts \label{sec:generic-context}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A generic context is the disjoint sum of either a theory or proof
+  context.  Occasionally, this enables uniform treatment of generic
+  context data, typically extra-logical information.  Operations on
+  generic contexts include the usual injections, partial selections,
+  and combinators for lifting operations on either component of the
+  disjoint sum.
+
+  Moreover, there are total operations \isa{theory{\isacharunderscore}of} and \isa{proof{\isacharunderscore}of} to convert a generic context into either kind: a theory
+  can always be selected from the sum, while a proof context might
+  have to be constructed by an ad-hoc \isa{init} operation.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{Context.generic}\verb|type Context.generic| \\
+  \indexdef{}{ML}{Context.theory\_of}\verb|Context.theory_of: Context.generic -> theory| \\
+  \indexdef{}{ML}{Context.proof\_of}\verb|Context.proof_of: Context.generic -> Proof.context| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Context.generic| is the direct sum of \verb|theory| and \verb|Proof.context|, with the datatype
+  constructors \verb|Context.Theory| and \verb|Context.Proof|.
+
+  \item \verb|Context.theory_of|~\isa{context} always produces a
+  theory from the generic \isa{context}, using \verb|ProofContext.theory_of| as required.
+
+  \item \verb|Context.proof_of|~\isa{context} always produces a
+  proof context from the generic \isa{context}, using \verb|ProofContext.init| as required (note that this re-initializes the
+  context data with each invocation).
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Context data \label{sec:context-data}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The main purpose of theory and proof contexts is to manage arbitrary
+  data.  New data types can be declared incrementally at compile time.
+  There are separate declaration mechanisms for any of the three kinds
+  of contexts: theory, proof, generic.
+
+  \paragraph{Theory data} may refer to destructive entities, which are
+  maintained in direct correspondence to the linear evolution of
+  theory values, including explicit copies.\footnote{Most existing
+  instances of destructive theory data are merely historical relics
+  (e.g.\ the destructive theorem storage, and destructive hints for
+  the Simplifier and Classical rules).}  A theory data declaration
+  needs to implement the following SML signature:
+
+  \medskip
+  \begin{tabular}{ll}
+  \isa{{\isasymtype}\ T} & representing type \\
+  \isa{{\isasymval}\ empty{\isacharcolon}\ T} & empty default value \\
+  \isa{{\isasymval}\ copy{\isacharcolon}\ T\ {\isasymrightarrow}\ T} & refresh impure data \\
+  \isa{{\isasymval}\ extend{\isacharcolon}\ T\ {\isasymrightarrow}\ T} & re-initialize on import \\
+  \isa{{\isasymval}\ merge{\isacharcolon}\ T\ {\isasymtimes}\ T\ {\isasymrightarrow}\ T} & join on import \\
+  \end{tabular}
+  \medskip
+
+  \noindent The \isa{empty} value acts as initial default for
+  \emph{any} theory that does not declare actual data content; \isa{copy} maintains persistent integrity for impure data, it is just
+  the identity for pure values; \isa{extend} is acts like a
+  unitary version of \isa{merge}, both operations should also
+  include the functionality of \isa{copy} for impure data.
+
+  \paragraph{Proof context data} is purely functional.  A declaration
+  needs to implement the following SML signature:
+
+  \medskip
+  \begin{tabular}{ll}
+  \isa{{\isasymtype}\ T} & representing type \\
+  \isa{{\isasymval}\ init{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} & produce initial value \\
+  \end{tabular}
+  \medskip
+
+  \noindent The \isa{init} operation is supposed to produce a pure
+  value from the given background theory.
+
+  \paragraph{Generic data} provides a hybrid interface for both theory
+  and proof data.  The declaration is essentially the same as for
+  (pure) theory data, without \isa{copy}.  The \isa{init}
+  operation for proof contexts merely selects the current data value
+  from the background theory.
+
+  \bigskip A data declaration of type \isa{T} results in the
+  following interface:
+
+  \medskip
+  \begin{tabular}{ll}
+  \isa{init{\isacharcolon}\ theory\ {\isasymrightarrow}\ T} \\
+  \isa{get{\isacharcolon}\ context\ {\isasymrightarrow}\ T} \\
+  \isa{put{\isacharcolon}\ T\ {\isasymrightarrow}\ context\ {\isasymrightarrow}\ context} \\
+  \isa{map{\isacharcolon}\ {\isacharparenleft}T\ {\isasymrightarrow}\ T{\isacharparenright}\ {\isasymrightarrow}\ context\ {\isasymrightarrow}\ context} \\
+  \end{tabular}
+  \medskip
+
+  \noindent Here \isa{init} is only applicable to impure theory
+  data to install a fresh copy persistently (destructive update on
+  uninitialized has no permanent effect).  The other operations provide
+  access for the particular kind of context (theory, proof, or generic
+  context).  Note that this is a safe interface: there is no other way
+  to access the corresponding data slot of a context.  By keeping
+  these operations private, a component may maintain abstract values
+  authentically, without other components interfering.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML functor}{TheoryDataFun}\verb|functor TheoryDataFun| \\
+  \indexdef{}{ML functor}{ProofDataFun}\verb|functor ProofDataFun| \\
+  \indexdef{}{ML functor}{GenericDataFun}\verb|functor GenericDataFun| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|TheoryDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} declares data for
+  type \verb|theory| according to the specification provided as
+  argument structure.  The resulting structure provides data init and
+  access operations as described above.
+
+  \item \verb|ProofDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} is analogous to
+  \verb|TheoryDataFun| for type \verb|Proof.context|.
+
+  \item \verb|GenericDataFun|\isa{{\isacharparenleft}spec{\isacharparenright}} is analogous to
+  \verb|TheoryDataFun| for type \verb|Context.generic|.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Names \label{sec:names}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+In principle, a name is just a string, but there are various
+  convention for encoding additional structure.  For example, ``\isa{Foo{\isachardot}bar{\isachardot}baz}'' is considered as a qualified name consisting of
+  three basic name components.  The individual constituents of a name
+  may have further substructure, e.g.\ the string
+  ``\verb,\,\verb,<alpha>,'' encodes as a single symbol.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsubsection{Strings of symbols%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{symbol} constitutes the smallest textual unit in Isabelle
+  --- raw characters are normally not encountered at all.  Isabelle
+  strings consist of a sequence of symbols, represented as a packed
+  string or a list of strings.  Each symbol is in itself a small
+  string, which has either one of the following forms:
+
+  \begin{enumerate}
+
+  \item a single ASCII character ``\isa{c}'', for example
+  ``\verb,a,'',
+
+  \item a regular symbol ``\verb,\,\verb,<,\isa{ident}\verb,>,'',
+  for example ``\verb,\,\verb,<alpha>,'',
+
+  \item a control symbol ``\verb,\,\verb,<^,\isa{ident}\verb,>,'',
+  for example ``\verb,\,\verb,<^bold>,'',
+
+  \item a raw symbol ``\verb,\,\verb,<^raw:,\isa{text}\verb,>,''
+  where \isa{text} constists of printable characters excluding
+  ``\verb,.,'' and ``\verb,>,'', for example
+  ``\verb,\,\verb,<^raw:$\sum_{i = 1}^n$>,'',
+
+  \item a numbered raw control symbol ``\verb,\,\verb,<^raw,\isa{n}\verb,>, where \isa{n} consists of digits, for example
+  ``\verb,\,\verb,<^raw42>,''.
+
+  \end{enumerate}
+
+  \noindent The \isa{ident} syntax for symbol names is \isa{letter\ {\isacharparenleft}letter\ {\isacharbar}\ digit{\isacharparenright}\isactrlsup {\isacharasterisk}}, where \isa{letter\ {\isacharequal}\ A{\isachardot}{\isachardot}Za{\isachardot}{\isachardot}z} and \isa{digit\ {\isacharequal}\ {\isadigit{0}}{\isachardot}{\isachardot}{\isadigit{9}}}.  There are infinitely many
+  regular symbols and control symbols, but a fixed collection of
+  standard symbols is treated specifically.  For example,
+  ``\verb,\,\verb,<alpha>,'' is classified as a letter, which means it
+  may occur within regular Isabelle identifiers.
+
+  Since the character set underlying Isabelle symbols is 7-bit ASCII
+  and 8-bit characters are passed through transparently, Isabelle may
+  also process Unicode/UCS data in UTF-8 encoding.  Unicode provides
+  its own collection of mathematical symbols, but there is no built-in
+  link to the standard collection of Isabelle.
+
+  \medskip Output of Isabelle symbols depends on the print mode
+  (\secref{print-mode}).  For example, the standard {\LaTeX} setup of
+  the Isabelle document preparation system would present
+  ``\verb,\,\verb,<alpha>,'' as \isa{{\isasymalpha}}, and
+  ``\verb,\,\verb,<^bold>,\verb,\,\verb,<alpha>,'' as \isa{\isactrlbold {\isasymalpha}}.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{Symbol.symbol}\verb|type Symbol.symbol| \\
+  \indexdef{}{ML}{Symbol.explode}\verb|Symbol.explode: string -> Symbol.symbol list| \\
+  \indexdef{}{ML}{Symbol.is\_letter}\verb|Symbol.is_letter: Symbol.symbol -> bool| \\
+  \indexdef{}{ML}{Symbol.is\_digit}\verb|Symbol.is_digit: Symbol.symbol -> bool| \\
+  \indexdef{}{ML}{Symbol.is\_quasi}\verb|Symbol.is_quasi: Symbol.symbol -> bool| \\
+  \indexdef{}{ML}{Symbol.is\_blank}\verb|Symbol.is_blank: Symbol.symbol -> bool| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{Symbol.sym}\verb|type Symbol.sym| \\
+  \indexdef{}{ML}{Symbol.decode}\verb|Symbol.decode: Symbol.symbol -> Symbol.sym| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Symbol.symbol| represents individual Isabelle
+  symbols; this is an alias for \verb|string|.
+
+  \item \verb|Symbol.explode|~\isa{str} produces a symbol list
+  from the packed form.  This function supercedes \verb|String.explode| for virtually all purposes of manipulating text in
+  Isabelle!
+
+  \item \verb|Symbol.is_letter|, \verb|Symbol.is_digit|, \verb|Symbol.is_quasi|, \verb|Symbol.is_blank| classify standard
+  symbols according to fixed syntactic conventions of Isabelle, cf.\
+  \cite{isabelle-isar-ref}.
+
+  \item \verb|Symbol.sym| is a concrete datatype that represents
+  the different kinds of symbols explicitly, with constructors \verb|Symbol.Char|, \verb|Symbol.Sym|, \verb|Symbol.Ctrl|, \verb|Symbol.Raw|.
+
+  \item \verb|Symbol.decode| converts the string representation of a
+  symbol into the datatype version.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Basic names \label{sec:basic-names}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{basic name} essentially consists of a single Isabelle
+  identifier.  There are conventions to mark separate classes of basic
+  names, by attaching a suffix of underscores: one underscore means
+  \emph{internal name}, two underscores means \emph{Skolem name},
+  three underscores means \emph{internal Skolem name}.
+
+  For example, the basic name \isa{foo} has the internal version
+  \isa{foo{\isacharunderscore}}, with Skolem versions \isa{foo{\isacharunderscore}{\isacharunderscore}} and \isa{foo{\isacharunderscore}{\isacharunderscore}{\isacharunderscore}}, respectively.
+
+  These special versions provide copies of the basic name space, apart
+  from anything that normally appears in the user text.  For example,
+  system generated variables in Isar proof contexts are usually marked
+  as internal, which prevents mysterious name references like \isa{xaa} to appear in the text.
+
+  \medskip Manipulating binding scopes often requires on-the-fly
+  renamings.  A \emph{name context} contains a collection of already
+  used names.  The \isa{declare} operation adds names to the
+  context.
+
+  The \isa{invents} operation derives a number of fresh names from
+  a given starting point.  For example, the first three names derived
+  from \isa{a} are \isa{a}, \isa{b}, \isa{c}.
+
+  The \isa{variants} operation produces fresh names by
+  incrementing tentative names as base-26 numbers (with digits \isa{a{\isachardot}{\isachardot}z}) until all clashes are resolved.  For example, name \isa{foo} results in variants \isa{fooa}, \isa{foob}, \isa{fooc}, \dots, \isa{fooaa}, \isa{fooab} etc.; each renaming
+  step picks the next unused variant from this sequence.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{Name.internal}\verb|Name.internal: string -> string| \\
+  \indexdef{}{ML}{Name.skolem}\verb|Name.skolem: string -> string| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{Name.context}\verb|type Name.context| \\
+  \indexdef{}{ML}{Name.context}\verb|Name.context: Name.context| \\
+  \indexdef{}{ML}{Name.declare}\verb|Name.declare: string -> Name.context -> Name.context| \\
+  \indexdef{}{ML}{Name.invents}\verb|Name.invents: Name.context -> string -> int -> string list| \\
+  \indexdef{}{ML}{Name.variants}\verb|Name.variants: string list -> Name.context -> string list * Name.context| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Name.internal|~\isa{name} produces an internal name
+  by adding one underscore.
+
+  \item \verb|Name.skolem|~\isa{name} produces a Skolem name by
+  adding two underscores.
+
+  \item \verb|Name.context| represents the context of already used
+  names; the initial value is \verb|Name.context|.
+
+  \item \verb|Name.declare|~\isa{name} enters a used name into the
+  context.
+
+  \item \verb|Name.invents|~\isa{context\ name\ n} produces \isa{n} fresh names derived from \isa{name}.
+
+  \item \verb|Name.variants|~\isa{names\ context} produces fresh
+  variants of \isa{names}; the result is entered into the context.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Indexed names%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+An \emph{indexed name} (or \isa{indexname}) is a pair of a basic
+  name and a natural number.  This representation allows efficient
+  renaming by incrementing the second component only.  The canonical
+  way to rename two collections of indexnames apart from each other is
+  this: determine the maximum index \isa{maxidx} of the first
+  collection, then increment all indexes of the second collection by
+  \isa{maxidx\ {\isacharplus}\ {\isadigit{1}}}; the maximum index of an empty collection is
+  \isa{{\isacharminus}{\isadigit{1}}}.
+
+  Occasionally, basic names and indexed names are injected into the
+  same pair type: the (improper) indexname \isa{{\isacharparenleft}x{\isacharcomma}\ {\isacharminus}{\isadigit{1}}{\isacharparenright}} is used
+  to encode basic names.
+
+  \medskip Isabelle syntax observes the following rules for
+  representing an indexname \isa{{\isacharparenleft}x{\isacharcomma}\ i{\isacharparenright}} as a packed string:
+
+  \begin{itemize}
+
+  \item \isa{{\isacharquery}x} if \isa{x} does not end with a digit and \isa{i\ {\isacharequal}\ {\isadigit{0}}},
+
+  \item \isa{{\isacharquery}xi} if \isa{x} does not end with a digit,
+
+  \item \isa{{\isacharquery}x{\isachardot}i} otherwise.
+
+  \end{itemize}
+
+  Indexnames may acquire large index numbers over time.  Results are
+  normalized towards \isa{{\isadigit{0}}} at certain checkpoints, notably at
+  the end of a proof.  This works by producing variants of the
+  corresponding basic name components.  For example, the collection
+  \isa{{\isacharquery}x{\isadigit{1}}{\isacharcomma}\ {\isacharquery}x{\isadigit{7}}{\isacharcomma}\ {\isacharquery}x{\isadigit{4}}{\isadigit{2}}} becomes \isa{{\isacharquery}x{\isacharcomma}\ {\isacharquery}xa{\isacharcomma}\ {\isacharquery}xb}.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{indexname}\verb|type indexname| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|indexname| represents indexed names.  This is an
+  abbreviation for \verb|string * int|.  The second component is
+  usually non-negative, except for situations where \isa{{\isacharparenleft}x{\isacharcomma}\ {\isacharminus}{\isadigit{1}}{\isacharparenright}}
+  is used to embed basic names into this type.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Qualified names and name spaces%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{qualified name} consists of a non-empty sequence of basic
+  name components.  The packed representation uses a dot as separator,
+  as in ``\isa{A{\isachardot}b{\isachardot}c}''.  The last component is called \emph{base}
+  name, the remaining prefix \emph{qualifier} (which may be empty).
+  The idea of qualified names is to encode nested structures by
+  recording the access paths as qualifiers.  For example, an item
+  named ``\isa{A{\isachardot}b{\isachardot}c}'' may be understood as a local entity \isa{c}, within a local structure \isa{b}, within a global
+  structure \isa{A}.  Typically, name space hierarchies consist of
+  1--2 levels of qualification, but this need not be always so.
+
+  The empty name is commonly used as an indication of unnamed
+  entities, whenever this makes any sense.  The basic operations on
+  qualified names are smart enough to pass through such improper names
+  unchanged.
+
+  \medskip A \isa{naming} policy tells how to turn a name
+  specification into a fully qualified internal name (by the \isa{full} operation), and how fully qualified names may be accessed
+  externally.  For example, the default naming policy is to prefix an
+  implicit path: \isa{full\ x} produces \isa{path{\isachardot}x}, and the
+  standard accesses for \isa{path{\isachardot}x} include both \isa{x} and
+  \isa{path{\isachardot}x}.  Normally, the naming is implicit in the theory or
+  proof context; there are separate versions of the corresponding.
+
+  \medskip A \isa{name\ space} manages a collection of fully
+  internalized names, together with a mapping between external names
+  and internal names (in both directions).  The corresponding \isa{intern} and \isa{extern} operations are mostly used for
+  parsing and printing only!  The \isa{declare} operation augments
+  a name space according to the accesses determined by the naming
+  policy.
+
+  \medskip As a general principle, there is a separate name space for
+  each kind of formal entity, e.g.\ logical constant, type
+  constructor, type class, theorem.  It is usually clear from the
+  occurrence in concrete syntax (or from the scope) which kind of
+  entity a name refers to.  For example, the very same name \isa{c} may be used uniformly for a constant, type constructor, and
+  type class.
+
+  There are common schemes to name theorems systematically, according
+  to the name of the main logical entity involved, e.g.\ \isa{c{\isachardot}intro} for a canonical theorem related to constant \isa{c}.
+  This technique of mapping names from one space into another requires
+  some care in order to avoid conflicts.  In particular, theorem names
+  derived from a type constructor or type class are better suffixed in
+  addition to the usual qualification, e.g.\ \isa{c{\isacharunderscore}type{\isachardot}intro}
+  and \isa{c{\isacharunderscore}class{\isachardot}intro} for theorems related to type \isa{c}
+  and class \isa{c}, respectively.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{NameSpace.base\_name}\verb|NameSpace.base_name: string -> string| \\
+  \indexdef{}{ML}{NameSpace.qualifier}\verb|NameSpace.qualifier: string -> string| \\
+  \indexdef{}{ML}{NameSpace.append}\verb|NameSpace.append: string -> string -> string| \\
+  \indexdef{}{ML}{NameSpace.implode}\verb|NameSpace.implode: string list -> string| \\
+  \indexdef{}{ML}{NameSpace.explode}\verb|NameSpace.explode: string -> string list| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{NameSpace.naming}\verb|type NameSpace.naming| \\
+  \indexdef{}{ML}{NameSpace.default\_naming}\verb|NameSpace.default_naming: NameSpace.naming| \\
+  \indexdef{}{ML}{NameSpace.add\_path}\verb|NameSpace.add_path: string -> NameSpace.naming -> NameSpace.naming| \\
+  \indexdef{}{ML}{NameSpace.full\_name}\verb|NameSpace.full_name: NameSpace.naming -> binding -> string| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML type}{NameSpace.T}\verb|type NameSpace.T| \\
+  \indexdef{}{ML}{NameSpace.empty}\verb|NameSpace.empty: NameSpace.T| \\
+  \indexdef{}{ML}{NameSpace.merge}\verb|NameSpace.merge: NameSpace.T * NameSpace.T -> NameSpace.T| \\
+  \indexdef{}{ML}{NameSpace.declare}\verb|NameSpace.declare: NameSpace.naming -> binding -> NameSpace.T ->|\isasep\isanewline%
+\verb|  string * NameSpace.T| \\
+  \indexdef{}{ML}{NameSpace.intern}\verb|NameSpace.intern: NameSpace.T -> string -> string| \\
+  \indexdef{}{ML}{NameSpace.extern}\verb|NameSpace.extern: NameSpace.T -> string -> string| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|NameSpace.base_name|~\isa{name} returns the base name of a
+  qualified name.
+
+  \item \verb|NameSpace.qualifier|~\isa{name} returns the qualifier
+  of a qualified name.
+
+  \item \verb|NameSpace.append|~\isa{name\isactrlisub {\isadigit{1}}\ name\isactrlisub {\isadigit{2}}}
+  appends two qualified names.
+
+  \item \verb|NameSpace.implode|~\isa{name} and \verb|NameSpace.explode|~\isa{names} convert between the packed string
+  representation and the explicit list form of qualified names.
+
+  \item \verb|NameSpace.naming| represents the abstract concept of
+  a naming policy.
+
+  \item \verb|NameSpace.default_naming| is the default naming policy.
+  In a theory context, this is usually augmented by a path prefix
+  consisting of the theory name.
+
+  \item \verb|NameSpace.add_path|~\isa{path\ naming} augments the
+  naming policy by extending its path component.
+
+  \item \verb|NameSpace.full_name|~\isa{naming\ binding} turns a
+  name binding (usually a basic name) into the fully qualified
+  internal name, according to the given naming policy.
+
+  \item \verb|NameSpace.T| represents name spaces.
+
+  \item \verb|NameSpace.empty| and \verb|NameSpace.merge|~\isa{{\isacharparenleft}space\isactrlisub {\isadigit{1}}{\isacharcomma}\ space\isactrlisub {\isadigit{2}}{\isacharparenright}} are the canonical operations for
+  maintaining name spaces according to theory data management
+  (\secref{sec:context-data}).
+
+  \item \verb|NameSpace.declare|~\isa{naming\ bindings\ space} enters a
+  name binding as fully qualified internal name into the name space,
+  with external accesses determined by the naming policy.
+
+  \item \verb|NameSpace.intern|~\isa{space\ name} internalizes a
+  (partially qualified) external name.
+
+  This operation is mostly for parsing!  Note that fully qualified
+  names stemming from declarations are produced via \verb|NameSpace.full_name| and \verb|NameSpace.declare|
+  (or their derivatives for \verb|theory| and
+  \verb|Proof.context|).
+
+  \item \verb|NameSpace.extern|~\isa{space\ name} externalizes a
+  (fully qualified) internal name.
+
+  This operation is mostly for printing!  User code should not rely on
+  the precise result too much.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Proof.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,394 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Proof}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Proof\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{Structured proofs%
+}
+\isamarkuptrue%
+%
+\isamarkupsection{Variables \label{sec:variables}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Any variable that is not explicitly bound by \isa{{\isasymlambda}}-abstraction
+  is considered as ``free''.  Logically, free variables act like
+  outermost universal quantification at the sequent level: \isa{A\isactrlisub {\isadigit{1}}{\isacharparenleft}x{\isacharparenright}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n{\isacharparenleft}x{\isacharparenright}\ {\isasymturnstile}\ B{\isacharparenleft}x{\isacharparenright}} means that the result
+  holds \emph{for all} values of \isa{x}.  Free variables for
+  terms (not types) can be fully internalized into the logic: \isa{{\isasymturnstile}\ B{\isacharparenleft}x{\isacharparenright}} and \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} are interchangeable, provided
+  that \isa{x} does not occur elsewhere in the context.
+  Inspecting \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} more closely, we see that inside the
+  quantifier, \isa{x} is essentially ``arbitrary, but fixed'',
+  while from outside it appears as a place-holder for instantiation
+  (thanks to \isa{{\isasymAnd}} elimination).
+
+  The Pure logic represents the idea of variables being either inside
+  or outside the current scope by providing separate syntactic
+  categories for \emph{fixed variables} (e.g.\ \isa{x}) vs.\
+  \emph{schematic variables} (e.g.\ \isa{{\isacharquery}x}).  Incidently, a
+  universal result \isa{{\isasymturnstile}\ {\isasymAnd}x{\isachardot}\ B{\isacharparenleft}x{\isacharparenright}} has the HHF normal form \isa{{\isasymturnstile}\ B{\isacharparenleft}{\isacharquery}x{\isacharparenright}}, which represents its generality nicely without requiring
+  an explicit quantifier.  The same principle works for type
+  variables: \isa{{\isasymturnstile}\ B{\isacharparenleft}{\isacharquery}{\isasymalpha}{\isacharparenright}} represents the idea of ``\isa{{\isasymturnstile}\ {\isasymforall}{\isasymalpha}{\isachardot}\ B{\isacharparenleft}{\isasymalpha}{\isacharparenright}}'' without demanding a truly polymorphic framework.
+
+  \medskip Additional care is required to treat type variables in a
+  way that facilitates type-inference.  In principle, term variables
+  depend on type variables, which means that type variables would have
+  to be declared first.  For example, a raw type-theoretic framework
+  would demand the context to be constructed in stages as follows:
+  \isa{{\isasymGamma}\ {\isacharequal}\ {\isasymalpha}{\isacharcolon}\ type{\isacharcomma}\ x{\isacharcolon}\ {\isasymalpha}{\isacharcomma}\ a{\isacharcolon}\ A{\isacharparenleft}x\isactrlisub {\isasymalpha}{\isacharparenright}}.
+
+  We allow a slightly less formalistic mode of operation: term
+  variables \isa{x} are fixed without specifying a type yet
+  (essentially \emph{all} potential occurrences of some instance
+  \isa{x\isactrlisub {\isasymtau}} are fixed); the first occurrence of \isa{x}
+  within a specific term assigns its most general type, which is then
+  maintained consistently in the context.  The above example becomes
+  \isa{{\isasymGamma}\ {\isacharequal}\ x{\isacharcolon}\ term{\isacharcomma}\ {\isasymalpha}{\isacharcolon}\ type{\isacharcomma}\ A{\isacharparenleft}x\isactrlisub {\isasymalpha}{\isacharparenright}}, where type \isa{{\isasymalpha}} is fixed \emph{after} term \isa{x}, and the constraint
+  \isa{x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}} is an implicit consequence of the occurrence of
+  \isa{x\isactrlisub {\isasymalpha}} in the subsequent proposition.
+
+  This twist of dependencies is also accommodated by the reverse
+  operation of exporting results from a context: a type variable
+  \isa{{\isasymalpha}} is considered fixed as long as it occurs in some fixed
+  term variable of the context.  For example, exporting \isa{x{\isacharcolon}\ term{\isacharcomma}\ {\isasymalpha}{\isacharcolon}\ type\ {\isasymturnstile}\ x\isactrlisub {\isasymalpha}\ {\isacharequal}\ x\isactrlisub {\isasymalpha}} produces in the first step
+  \isa{x{\isacharcolon}\ term\ {\isasymturnstile}\ x\isactrlisub {\isasymalpha}\ {\isacharequal}\ x\isactrlisub {\isasymalpha}} for fixed \isa{{\isasymalpha}},
+  and only in the second step \isa{{\isasymturnstile}\ {\isacharquery}x\isactrlisub {\isacharquery}\isactrlisub {\isasymalpha}\ {\isacharequal}\ {\isacharquery}x\isactrlisub {\isacharquery}\isactrlisub {\isasymalpha}} for schematic \isa{{\isacharquery}x} and \isa{{\isacharquery}{\isasymalpha}}.
+
+  \medskip The Isabelle/Isar proof context manages the gory details of
+  term vs.\ type variables, with high-level principles for moving the
+  frontier between fixed and schematic variables.
+
+  The \isa{add{\isacharunderscore}fixes} operation explictly declares fixed
+  variables; the \isa{declare{\isacharunderscore}term} operation absorbs a term into
+  a context by fixing new type variables and adding syntactic
+  constraints.
+
+  The \isa{export} operation is able to perform the main work of
+  generalizing term and type variables as sketched above, assuming
+  that fixing variables and terms have been declared properly.
+
+  There \isa{import} operation makes a generalized fact a genuine
+  part of the context, by inventing fixed variables for the schematic
+  ones.  The effect can be reversed by using \isa{export} later,
+  potentially with an extended context; the result is equivalent to
+  the original modulo renaming of schematic variables.
+
+  The \isa{focus} operation provides a variant of \isa{import}
+  for nested propositions (with explicit quantification): \isa{{\isasymAnd}x\isactrlisub {\isadigit{1}}\ {\isasymdots}\ x\isactrlisub n{\isachardot}\ B{\isacharparenleft}x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub n{\isacharparenright}} is
+  decomposed by inventing fixed variables \isa{x\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlisub n} for the body.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{Variable.add\_fixes}\verb|Variable.add_fixes: |\isasep\isanewline%
+\verb|  string list -> Proof.context -> string list * Proof.context| \\
+  \indexdef{}{ML}{Variable.variant\_fixes}\verb|Variable.variant_fixes: |\isasep\isanewline%
+\verb|  string list -> Proof.context -> string list * Proof.context| \\
+  \indexdef{}{ML}{Variable.declare\_term}\verb|Variable.declare_term: term -> Proof.context -> Proof.context| \\
+  \indexdef{}{ML}{Variable.declare\_constraints}\verb|Variable.declare_constraints: term -> Proof.context -> Proof.context| \\
+  \indexdef{}{ML}{Variable.export}\verb|Variable.export: Proof.context -> Proof.context -> thm list -> thm list| \\
+  \indexdef{}{ML}{Variable.polymorphic}\verb|Variable.polymorphic: Proof.context -> term list -> term list| \\
+  \indexdef{}{ML}{Variable.import\_thms}\verb|Variable.import_thms: bool -> thm list -> Proof.context ->|\isasep\isanewline%
+\verb|  ((ctyp list * cterm list) * thm list) * Proof.context| \\
+  \indexdef{}{ML}{Variable.focus}\verb|Variable.focus: cterm -> Proof.context -> (cterm list * cterm) * Proof.context| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Variable.add_fixes|~\isa{xs\ ctxt} fixes term
+  variables \isa{xs}, returning the resulting internal names.  By
+  default, the internal representation coincides with the external
+  one, which also means that the given variables must not be fixed
+  already.  There is a different policy within a local proof body: the
+  given names are just hints for newly invented Skolem variables.
+
+  \item \verb|Variable.variant_fixes| is similar to \verb|Variable.add_fixes|, but always produces fresh variants of the given
+  names.
+
+  \item \verb|Variable.declare_term|~\isa{t\ ctxt} declares term
+  \isa{t} to belong to the context.  This automatically fixes new
+  type variables, but not term variables.  Syntactic constraints for
+  type and term variables are declared uniformly, though.
+
+  \item \verb|Variable.declare_constraints|~\isa{t\ ctxt} declares
+  syntactic constraints from term \isa{t}, without making it part
+  of the context yet.
+
+  \item \verb|Variable.export|~\isa{inner\ outer\ thms} generalizes
+  fixed type and term variables in \isa{thms} according to the
+  difference of the \isa{inner} and \isa{outer} context,
+  following the principles sketched above.
+
+  \item \verb|Variable.polymorphic|~\isa{ctxt\ ts} generalizes type
+  variables in \isa{ts} as far as possible, even those occurring
+  in fixed term variables.  The default policy of type-inference is to
+  fix newly introduced type variables, which is essentially reversed
+  with \verb|Variable.polymorphic|: here the given terms are detached
+  from the context as far as possible.
+
+  \item \verb|Variable.import_thms|~\isa{open\ thms\ ctxt} invents fixed
+  type and term variables for the schematic ones occurring in \isa{thms}.  The \isa{open} flag indicates whether the fixed names
+  should be accessible to the user, otherwise newly introduced names
+  are marked as ``internal'' (\secref{sec:names}).
+
+  \item \verb|Variable.focus|~\isa{B} decomposes the outermost \isa{{\isasymAnd}} prefix of proposition \isa{B}.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Assumptions \label{sec:assumptions}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+An \emph{assumption} is a proposition that it is postulated in the
+  current context.  Local conclusions may use assumptions as
+  additional facts, but this imposes implicit hypotheses that weaken
+  the overall statement.
+
+  Assumptions are restricted to fixed non-schematic statements, i.e.\
+  all generality needs to be expressed by explicit quantifiers.
+  Nevertheless, the result will be in HHF normal form with outermost
+  quantifiers stripped.  For example, by assuming \isa{{\isasymAnd}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ P\ x} we get \isa{{\isasymAnd}x\ {\isacharcolon}{\isacharcolon}\ {\isasymalpha}{\isachardot}\ P\ x\ {\isasymturnstile}\ P\ {\isacharquery}x} for schematic \isa{{\isacharquery}x}
+  of fixed type \isa{{\isasymalpha}}.  Local derivations accumulate more and
+  more explicit references to hypotheses: \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n\ {\isasymturnstile}\ B} where \isa{A\isactrlisub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ A\isactrlisub n} needs to
+  be covered by the assumptions of the current context.
+
+  \medskip The \isa{add{\isacharunderscore}assms} operation augments the context by
+  local assumptions, which are parameterized by an arbitrary \isa{export} rule (see below).
+
+  The \isa{export} operation moves facts from a (larger) inner
+  context into a (smaller) outer context, by discharging the
+  difference of the assumptions as specified by the associated export
+  rules.  Note that the discharged portion is determined by the
+  difference contexts, not the facts being exported!  There is a
+  separate flag to indicate a goal context, where the result is meant
+  to refine an enclosing sub-goal of a structured proof state.
+
+  \medskip The most basic export rule discharges assumptions directly
+  by means of the \isa{{\isasymLongrightarrow}} introduction rule:
+  \[
+  \infer[(\isa{{\isasymLongrightarrow}{\isacharunderscore}intro})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ A\ {\isasymturnstile}\ A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
+  \]
+
+  The variant for goal refinements marks the newly introduced
+  premises, which causes the canonical Isar goal refinement scheme to
+  enforce unification with local premises within the goal:
+  \[
+  \infer[(\isa{{\isacharhash}{\isasymLongrightarrow}{\isacharunderscore}intro})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ A\ {\isasymturnstile}\ {\isacharhash}A\ {\isasymLongrightarrow}\ B}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B}}
+  \]
+
+  \medskip Alternative versions of assumptions may perform arbitrary
+  transformations on export, as long as the corresponding portion of
+  hypotheses is removed from the given facts.  For example, a local
+  definition works by fixing \isa{x} and assuming \isa{x\ {\isasymequiv}\ t},
+  with the following export rule to reverse the effect:
+  \[
+  \infer[(\isa{{\isasymequiv}{\isacharminus}expand})]{\isa{{\isasymGamma}\ {\isacharbackslash}\ x\ {\isasymequiv}\ t\ {\isasymturnstile}\ B\ t}}{\isa{{\isasymGamma}\ {\isasymturnstile}\ B\ x}}
+  \]
+  This works, because the assumption \isa{x\ {\isasymequiv}\ t} was introduced in
+  a context with \isa{x} being fresh, so \isa{x} does not
+  occur in \isa{{\isasymGamma}} here.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{Assumption.export}\verb|type Assumption.export| \\
+  \indexdef{}{ML}{Assumption.assume}\verb|Assumption.assume: cterm -> thm| \\
+  \indexdef{}{ML}{Assumption.add\_assms}\verb|Assumption.add_assms: Assumption.export ->|\isasep\isanewline%
+\verb|  cterm list -> Proof.context -> thm list * Proof.context| \\
+  \indexdef{}{ML}{Assumption.add\_assumes}\verb|Assumption.add_assumes: |\isasep\isanewline%
+\verb|  cterm list -> Proof.context -> thm list * Proof.context| \\
+  \indexdef{}{ML}{Assumption.export}\verb|Assumption.export: bool -> Proof.context -> Proof.context -> thm -> thm| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Assumption.export| represents arbitrary export
+  rules, which is any function of type \verb|bool -> cterm list -> thm -> thm|,
+  where the \verb|bool| indicates goal mode, and the \verb|cterm list| the collection of assumptions to be discharged
+  simultaneously.
+
+  \item \verb|Assumption.assume|~\isa{A} turns proposition \isa{A} into a raw assumption \isa{A\ {\isasymturnstile}\ A{\isacharprime}}, where the conclusion
+  \isa{A{\isacharprime}} is in HHF normal form.
+
+  \item \verb|Assumption.add_assms|~\isa{r\ As} augments the context
+  by assumptions \isa{As} with export rule \isa{r}.  The
+  resulting facts are hypothetical theorems as produced by the raw
+  \verb|Assumption.assume|.
+
+  \item \verb|Assumption.add_assumes|~\isa{As} is a special case of
+  \verb|Assumption.add_assms| where the export rule performs \isa{{\isasymLongrightarrow}{\isacharunderscore}intro} or \isa{{\isacharhash}{\isasymLongrightarrow}{\isacharunderscore}intro}, depending on goal mode.
+
+  \item \verb|Assumption.export|~\isa{is{\isacharunderscore}goal\ inner\ outer\ thm}
+  exports result \isa{thm} from the the \isa{inner} context
+  back into the \isa{outer} one; \isa{is{\isacharunderscore}goal\ {\isacharequal}\ true} means
+  this is a goal context.  The result is in HHF normal form.  Note
+  that \verb|ProofContext.export| combines \verb|Variable.export|
+  and \verb|Assumption.export| in the canonical way.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Results \label{sec:results}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Local results are established by monotonic reasoning from facts
+  within a context.  This allows common combinations of theorems,
+  e.g.\ via \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} elimination, resolution rules, or equational
+  reasoning, see \secref{sec:thms}.  Unaccounted context manipulations
+  should be avoided, notably raw \isa{{\isasymAnd}{\isacharslash}{\isasymLongrightarrow}} introduction or ad-hoc
+  references to free variables or assumptions not present in the proof
+  context.
+
+  \medskip The \isa{SUBPROOF} combinator allows to structure a
+  tactical proof recursively by decomposing a selected sub-goal:
+  \isa{{\isacharparenleft}{\isasymAnd}x{\isachardot}\ A{\isacharparenleft}x{\isacharparenright}\ {\isasymLongrightarrow}\ B{\isacharparenleft}x{\isacharparenright}{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymdots}} is turned into \isa{B{\isacharparenleft}x{\isacharparenright}\ {\isasymLongrightarrow}\ {\isasymdots}}
+  after fixing \isa{x} and assuming \isa{A{\isacharparenleft}x{\isacharparenright}}.  This means
+  the tactic needs to solve the conclusion, but may use the premise as
+  a local fact, for locally fixed variables.
+
+  The \isa{prove} operation provides an interface for structured
+  backwards reasoning under program control, with some explicit sanity
+  checks of the result.  The goal context can be augmented by
+  additional fixed variables (cf.\ \secref{sec:variables}) and
+  assumptions (cf.\ \secref{sec:assumptions}), which will be available
+  as local facts during the proof and discharged into implications in
+  the result.  Type and term variables are generalized as usual,
+  according to the context.
+
+  The \isa{obtain} operation produces results by eliminating
+  existing facts by means of a given tactic.  This acts like a dual
+  conclusion: the proof demonstrates that the context may be augmented
+  by certain fixed variables and assumptions.  See also
+  \cite{isabelle-isar-ref} for the user-level \isa{{\isasymOBTAIN}} and
+  \isa{{\isasymGUESS}} elements.  Final results, which may not refer to
+  the parameters in the conclusion, need to exported explicitly into
+  the original context.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{SUBPROOF}\verb|SUBPROOF: ({context: Proof.context, schematics: ctyp list * cterm list,|\isasep\isanewline%
+\verb|    params: cterm list, asms: cterm list, concl: cterm,|\isasep\isanewline%
+\verb|    prems: thm list} -> tactic) -> Proof.context -> int -> tactic| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML}{Goal.prove}\verb|Goal.prove: Proof.context -> string list -> term list -> term ->|\isasep\isanewline%
+\verb|  ({prems: thm list, context: Proof.context} -> tactic) -> thm| \\
+  \indexdef{}{ML}{Goal.prove\_multi}\verb|Goal.prove_multi: Proof.context -> string list -> term list -> term list ->|\isasep\isanewline%
+\verb|  ({prems: thm list, context: Proof.context} -> tactic) -> thm list| \\
+  \end{mldecls}
+  \begin{mldecls}
+  \indexdef{}{ML}{Obtain.result}\verb|Obtain.result: (Proof.context -> tactic) ->|\isasep\isanewline%
+\verb|  thm list -> Proof.context -> (cterm list * thm list) * Proof.context| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|SUBPROOF|~\isa{tac\ ctxt\ i} decomposes the structure
+  of the specified sub-goal, producing an extended context and a
+  reduced goal, which needs to be solved by the given tactic.  All
+  schematic parameters of the goal are imported into the context as
+  fixed ones, which may not be instantiated in the sub-proof.
+
+  \item \verb|Goal.prove|~\isa{ctxt\ xs\ As\ C\ tac} states goal \isa{C} in the context augmented by fixed variables \isa{xs} and
+  assumptions \isa{As}, and applies tactic \isa{tac} to solve
+  it.  The latter may depend on the local assumptions being presented
+  as facts.  The result is in HHF normal form.
+
+  \item \verb|Goal.prove_multi| is simular to \verb|Goal.prove|, but
+  states several conclusions simultaneously.  The goal is encoded by
+  means of Pure conjunction; \verb|Goal.conjunction_tac| will turn this
+  into a collection of individual subgoals.
+
+  \item \verb|Obtain.result|~\isa{tac\ thms\ ctxt} eliminates the
+  given facts using a tactic, which results in additional fixed
+  variables and assumptions in the context.  Final results need to be
+  exported explicitly.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc-src/IsarImplementation/Thy/document/Tactic.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,497 @@
+%
+\begin{isabellebody}%
+\def\isabellecontext{Tactic}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{theory}\isamarkupfalse%
+\ Tactic\isanewline
+\isakeyword{imports}\ Base\isanewline
+\isakeyword{begin}%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isamarkupchapter{Tactical reasoning%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Tactical reasoning works by refining the initial claim in a
+  backwards fashion, until a solved form is reached.  A \isa{goal}
+  consists of several subgoals that need to be solved in order to
+  achieve the main statement; zero subgoals means that the proof may
+  be finished.  A \isa{tactic} is a refinement operation that maps
+  a goal to a lazy sequence of potential successors.  A \isa{tactical} is a combinator for composing tactics.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isamarkupsection{Goals \label{sec:tactical-goals}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+Isabelle/Pure represents a goal as a theorem stating that the
+  subgoals imply the main goal: \isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ C}.  The outermost goal structure is that of a Horn Clause: i.e.\
+  an iterated implication without any quantifiers\footnote{Recall that
+  outermost \isa{{\isasymAnd}x{\isachardot}\ {\isasymphi}{\isacharbrackleft}x{\isacharbrackright}} is always represented via schematic
+  variables in the body: \isa{{\isasymphi}{\isacharbrackleft}{\isacharquery}x{\isacharbrackright}}.  These variables may get
+  instantiated during the course of reasoning.}.  For \isa{n\ {\isacharequal}\ {\isadigit{0}}}
+  a goal is called ``solved''.
+
+  The structure of each subgoal \isa{A\isactrlsub i} is that of a
+  general Hereditary Harrop Formula \isa{{\isasymAnd}x\isactrlsub {\isadigit{1}}\ {\isasymdots}\ {\isasymAnd}x\isactrlsub k{\isachardot}\ H\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ H\isactrlsub m\ {\isasymLongrightarrow}\ B}.  Here \isa{x\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ x\isactrlsub k} are goal parameters, i.e.\
+  arbitrary-but-fixed entities of certain types, and \isa{H\isactrlsub {\isadigit{1}}{\isacharcomma}\ {\isasymdots}{\isacharcomma}\ H\isactrlsub m} are goal hypotheses, i.e.\ facts that may
+  be assumed locally.  Together, this forms the goal context of the
+  conclusion \isa{B} to be established.  The goal hypotheses may be
+  again arbitrary Hereditary Harrop Formulas, although the level of
+  nesting rarely exceeds 1--2 in practice.
+
+  The main conclusion \isa{C} is internally marked as a protected
+  proposition, which is represented explicitly by the notation \isa{{\isacharhash}C}.  This ensures that the decomposition into subgoals and main
+  conclusion is well-defined for arbitrarily structured claims.
+
+  \medskip Basic goal management is performed via the following
+  Isabelle/Pure rules:
+
+  \[
+  \infer[\isa{{\isacharparenleft}init{\isacharparenright}}]{\isa{C\ {\isasymLongrightarrow}\ {\isacharhash}C}}{} \qquad
+  \infer[\isa{{\isacharparenleft}finish{\isacharparenright}}]{\isa{C}}{\isa{{\isacharhash}C}}
+  \]
+
+  \medskip The following low-level variants admit general reasoning
+  with protected propositions:
+
+  \[
+  \infer[\isa{{\isacharparenleft}protect{\isacharparenright}}]{\isa{{\isacharhash}C}}{\isa{C}} \qquad
+  \infer[\isa{{\isacharparenleft}conclude{\isacharparenright}}]{\isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ C}}{\isa{A\isactrlsub {\isadigit{1}}\ {\isasymLongrightarrow}\ {\isasymdots}\ {\isasymLongrightarrow}\ A\isactrlsub n\ {\isasymLongrightarrow}\ {\isacharhash}C}}
+  \]%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{Goal.init}\verb|Goal.init: cterm -> thm| \\
+  \indexdef{}{ML}{Goal.finish}\verb|Goal.finish: thm -> thm| \\
+  \indexdef{}{ML}{Goal.protect}\verb|Goal.protect: thm -> thm| \\
+  \indexdef{}{ML}{Goal.conclude}\verb|Goal.conclude: thm -> thm| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|Goal.init|~\isa{C} initializes a tactical goal from
+  the well-formed proposition \isa{C}.
+
+  \item \verb|Goal.finish|~\isa{thm} checks whether theorem
+  \isa{thm} is a solved goal (no subgoals), and concludes the
+  result by removing the goal protection.
+
+  \item \verb|Goal.protect|~\isa{thm} protects the full statement
+  of theorem \isa{thm}.
+
+  \item \verb|Goal.conclude|~\isa{thm} removes the goal
+  protection, even if there are pending subgoals.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Tactics%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \isa{tactic} is a function \isa{goal\ {\isasymrightarrow}\ goal\isactrlsup {\isacharasterisk}\isactrlsup {\isacharasterisk}} that
+  maps a given goal state (represented as a theorem, cf.\
+  \secref{sec:tactical-goals}) to a lazy sequence of potential
+  successor states.  The underlying sequence implementation is lazy
+  both in head and tail, and is purely functional in \emph{not}
+  supporting memoing.\footnote{The lack of memoing and the strict
+  nature of SML requires some care when working with low-level
+  sequence operations, to avoid duplicate or premature evaluation of
+  results.}
+
+  An \emph{empty result sequence} means that the tactic has failed: in
+  a compound tactic expressions other tactics might be tried instead,
+  or the whole refinement step might fail outright, producing a
+  toplevel error message.  When implementing tactics from scratch, one
+  should take care to observe the basic protocol of mapping regular
+  error conditions to an empty result; only serious faults should
+  emerge as exceptions.
+
+  By enumerating \emph{multiple results}, a tactic can easily express
+  the potential outcome of an internal search process.  There are also
+  combinators for building proof tools that involve search
+  systematically, see also \secref{sec:tacticals}.
+
+  \medskip As explained in \secref{sec:tactical-goals}, a goal state
+  essentially consists of a list of subgoals that imply the main goal
+  (conclusion).  Tactics may operate on all subgoals or on a
+  particularly specified subgoal, but must not change the main
+  conclusion (apart from instantiating schematic goal variables).
+
+  Tactics with explicit \emph{subgoal addressing} are of the form
+  \isa{int\ {\isasymrightarrow}\ tactic} and may be applied to a particular subgoal
+  (counting from 1).  If the subgoal number is out of range, the
+  tactic should fail with an empty result sequence, but must not raise
+  an exception!
+
+  Operating on a particular subgoal means to replace it by an interval
+  of zero or more subgoals in the same place; other subgoals must not
+  be affected, apart from instantiating schematic variables ranging
+  over the whole goal state.
+
+  A common pattern of composing tactics with subgoal addressing is to
+  try the first one, and then the second one only if the subgoal has
+  not been solved yet.  Special care is required here to avoid bumping
+  into unrelated subgoals that happen to come after the original
+  subgoal.  Assuming that there is only a single initial subgoal is a
+  very common error when implementing tactics!
+
+  Tactics with internal subgoal addressing should expose the subgoal
+  index as \isa{int} argument in full generality; a hardwired
+  subgoal 1 inappropriate.
+  
+  \medskip The main well-formedness conditions for proper tactics are
+  summarized as follows.
+
+  \begin{itemize}
+
+  \item General tactic failure is indicated by an empty result, only
+  serious faults may produce an exception.
+
+  \item The main conclusion must not be changed, apart from
+  instantiating schematic variables.
+
+  \item A tactic operates either uniformly on all subgoals, or
+  specifically on a selected subgoal (without bumping into unrelated
+  subgoals).
+
+  \item Range errors in subgoal addressing produce an empty result.
+
+  \end{itemize}
+
+  Some of these conditions are checked by higher-level goal
+  infrastructure (\secref{sec:results}); others are not checked
+  explicitly, and violating them merely results in ill-behaved tactics
+  experienced by the user (e.g.\ tactics that insist in being
+  applicable only to singleton goals, or disallow composition with
+  basic tacticals).%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML type}{tactic}\verb|type tactic = thm -> thm Seq.seq| \\
+  \indexdef{}{ML}{no\_tac}\verb|no_tac: tactic| \\
+  \indexdef{}{ML}{all\_tac}\verb|all_tac: tactic| \\
+  \indexdef{}{ML}{print\_tac}\verb|print_tac: string -> tactic| \\[1ex]
+  \indexdef{}{ML}{PRIMITIVE}\verb|PRIMITIVE: (thm -> thm) -> tactic| \\[1ex]
+  \indexdef{}{ML}{SUBGOAL}\verb|SUBGOAL: (term * int -> tactic) -> int -> tactic| \\
+  \indexdef{}{ML}{CSUBGOAL}\verb|CSUBGOAL: (cterm * int -> tactic) -> int -> tactic| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|tactic| represents tactics.  The well-formedness
+  conditions described above need to be observed.  See also \hyperlink{file.~~/src/Pure/General/seq.ML}{\mbox{\isa{\isatt{{\isachartilde}{\isachartilde}{\isacharslash}src{\isacharslash}Pure{\isacharslash}General{\isacharslash}seq{\isachardot}ML}}}} for the underlying implementation of
+  lazy sequences.
+
+  \item \verb|int -> tactic| represents tactics with explicit
+  subgoal addressing, with well-formedness conditions as described
+  above.
+
+  \item \verb|no_tac| is a tactic that always fails, returning the
+  empty sequence.
+
+  \item \verb|all_tac| is a tactic that always succeeds, returning a
+  singleton sequence with unchanged goal state.
+
+  \item \verb|print_tac|~\isa{message} is like \verb|all_tac|, but
+  prints a message together with the goal state on the tracing
+  channel.
+
+  \item \verb|PRIMITIVE|~\isa{rule} turns a primitive inference rule
+  into a tactic with unique result.  Exception \verb|THM| is considered
+  a regular tactic failure and produces an empty result; other
+  exceptions are passed through.
+
+  \item \verb|SUBGOAL|~\isa{{\isacharparenleft}fn\ {\isacharparenleft}subgoal{\isacharcomma}\ i{\isacharparenright}\ {\isacharequal}{\isachargreater}\ tactic{\isacharparenright}} is the
+  most basic form to produce a tactic with subgoal addressing.  The
+  given abstraction over the subgoal term and subgoal number allows to
+  peek at the relevant information of the full goal state.  The
+  subgoal range is checked as required above.
+
+  \item \verb|CSUBGOAL| is similar to \verb|SUBGOAL|, but passes the
+  subgoal as \verb|cterm| instead of raw \verb|term|.  This
+  avoids expensive re-certification in situations where the subgoal is
+  used directly for primitive inferences.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Resolution and assumption tactics \label{sec:resolve-assume-tac}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+\emph{Resolution} is the most basic mechanism for refining a
+  subgoal using a theorem as object-level rule.
+  \emph{Elim-resolution} is particularly suited for elimination rules:
+  it resolves with a rule, proves its first premise by assumption, and
+  finally deletes that assumption from any new subgoals.
+  \emph{Destruct-resolution} is like elim-resolution, but the given
+  destruction rules are first turned into canonical elimination
+  format.  \emph{Forward-resolution} is like destruct-resolution, but
+  without deleting the selected assumption.  The \isa{r{\isacharslash}e{\isacharslash}d{\isacharslash}f}
+  naming convention is maintained for several different kinds of
+  resolution rules and tactics.
+
+  Assumption tactics close a subgoal by unifying some of its premises
+  against its conclusion.
+
+  \medskip All the tactics in this section operate on a subgoal
+  designated by a positive integer.  Other subgoals might be affected
+  indirectly, due to instantiation of schematic variables.
+
+  There are various sources of non-determinism, the tactic result
+  sequence enumerates all possibilities of the following choices (if
+  applicable):
+
+  \begin{enumerate}
+
+  \item selecting one of the rules given as argument to the tactic;
+
+  \item selecting a subgoal premise to eliminate, unifying it against
+  the first premise of the rule;
+
+  \item unifying the conclusion of the subgoal to the conclusion of
+  the rule.
+
+  \end{enumerate}
+
+  Recall that higher-order unification may produce multiple results
+  that are enumerated here.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{resolve\_tac}\verb|resolve_tac: thm list -> int -> tactic| \\
+  \indexdef{}{ML}{eresolve\_tac}\verb|eresolve_tac: thm list -> int -> tactic| \\
+  \indexdef{}{ML}{dresolve\_tac}\verb|dresolve_tac: thm list -> int -> tactic| \\
+  \indexdef{}{ML}{forward\_tac}\verb|forward_tac: thm list -> int -> tactic| \\[1ex]
+  \indexdef{}{ML}{assume\_tac}\verb|assume_tac: int -> tactic| \\
+  \indexdef{}{ML}{eq\_assume\_tac}\verb|eq_assume_tac: int -> tactic| \\[1ex]
+  \indexdef{}{ML}{match\_tac}\verb|match_tac: thm list -> int -> tactic| \\
+  \indexdef{}{ML}{ematch\_tac}\verb|ematch_tac: thm list -> int -> tactic| \\
+  \indexdef{}{ML}{dmatch\_tac}\verb|dmatch_tac: thm list -> int -> tactic| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|resolve_tac|~\isa{thms\ i} refines the goal state
+  using the given theorems, which should normally be introduction
+  rules.  The tactic resolves a rule's conclusion with subgoal \isa{i}, replacing it by the corresponding versions of the rule's
+  premises.
+
+  \item \verb|eresolve_tac|~\isa{thms\ i} performs elim-resolution
+  with the given theorems, which should normally be elimination rules.
+
+  \item \verb|dresolve_tac|~\isa{thms\ i} performs
+  destruct-resolution with the given theorems, which should normally
+  be destruction rules.  This replaces an assumption by the result of
+  applying one of the rules.
+
+  \item \verb|forward_tac| is like \verb|dresolve_tac| except that the
+  selected assumption is not deleted.  It applies a rule to an
+  assumption, adding the result as a new assumption.
+
+  \item \verb|assume_tac|~\isa{i} attempts to solve subgoal \isa{i}
+  by assumption (modulo higher-order unification).
+
+  \item \verb|eq_assume_tac| is similar to \verb|assume_tac|, but checks
+  only for immediate \isa{{\isasymalpha}}-convertibility instead of using
+  unification.  It succeeds (with a unique next state) if one of the
+  assumptions is equal to the subgoal's conclusion.  Since it does not
+  instantiate variables, it cannot make other subgoals unprovable.
+
+  \item \verb|match_tac|, \verb|ematch_tac|, and \verb|dmatch_tac| are
+  similar to \verb|resolve_tac|, \verb|eresolve_tac|, and \verb|dresolve_tac|, respectively, but do not instantiate schematic
+  variables in the goal state.
+
+  Flexible subgoals are not updated at will, but are left alone.
+  Strictly speaking, matching means to treat the unknowns in the goal
+  state as constants; these tactics merely discard unifiers that would
+  update the goal state.
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsubsection{Explicit instantiation within a subgoal context%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+The main resolution tactics (\secref{sec:resolve-assume-tac})
+  use higher-order unification, which works well in many practical
+  situations despite its daunting theoretical properties.
+  Nonetheless, there are important problem classes where unguided
+  higher-order unification is not so useful.  This typically involves
+  rules like universal elimination, existential introduction, or
+  equational substitution.  Here the unification problem involves
+  fully flexible \isa{{\isacharquery}P\ {\isacharquery}x} schemes, which are hard to manage
+  without further hints.
+
+  By providing a (small) rigid term for \isa{{\isacharquery}x} explicitly, the
+  remaining unification problem is to assign a (large) term to \isa{{\isacharquery}P}, according to the shape of the given subgoal.  This is
+  sufficiently well-behaved in most practical situations.
+
+  \medskip Isabelle provides separate versions of the standard \isa{r{\isacharslash}e{\isacharslash}d{\isacharslash}f} resolution tactics that allow to provide explicit
+  instantiations of unknowns of the given rule, wrt.\ terms that refer
+  to the implicit context of the selected subgoal.
+
+  An instantiation consists of a list of pairs of the form \isa{{\isacharparenleft}{\isacharquery}x{\isacharcomma}\ t{\isacharparenright}}, where \isa{{\isacharquery}x} is a schematic variable occurring in
+  the given rule, and \isa{t} is a term from the current proof
+  context, augmented by the local goal parameters of the selected
+  subgoal; cf.\ the \isa{focus} operation described in
+  \secref{sec:variables}.
+
+  Entering the syntactic context of a subgoal is a brittle operation,
+  because its exact form is somewhat accidental, and the choice of
+  bound variable names depends on the presence of other local and
+  global names.  Explicit renaming of subgoal parameters prior to
+  explicit instantiation might help to achieve a bit more robustness.
+
+  Type instantiations may be given as well, via pairs like \isa{{\isacharparenleft}{\isacharquery}{\isacharprime}a{\isacharcomma}\ {\isasymtau}{\isacharparenright}}.  Type instantiations are distinguished from term
+  instantiations by the syntactic form of the schematic variable.
+  Types are instantiated before terms are.  Since term instantiation
+  already performs type-inference as expected, explicit type
+  instantiations are seldom necessary.%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isatagmlref
+%
+\begin{isamarkuptext}%
+\begin{mldecls}
+  \indexdef{}{ML}{res\_inst\_tac}\verb|res_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
+  \indexdef{}{ML}{eres\_inst\_tac}\verb|eres_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
+  \indexdef{}{ML}{dres\_inst\_tac}\verb|dres_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\
+  \indexdef{}{ML}{forw\_inst\_tac}\verb|forw_inst_tac: Proof.context -> (indexname * string) list -> thm -> int -> tactic| \\[1ex]
+  \indexdef{}{ML}{rename\_tac}\verb|rename_tac: string list -> int -> tactic| \\
+  \end{mldecls}
+
+  \begin{description}
+
+  \item \verb|res_inst_tac|~\isa{ctxt\ insts\ thm\ i} instantiates the
+  rule \isa{thm} with the instantiations \isa{insts}, as described
+  above, and then performs resolution on subgoal \isa{i}.
+  
+  \item \verb|eres_inst_tac| is like \verb|res_inst_tac|, but performs
+  elim-resolution.
+
+  \item \verb|dres_inst_tac| is like \verb|res_inst_tac|, but performs
+  destruct-resolution.
+
+  \item \verb|forw_inst_tac| is like \verb|dres_inst_tac| except that
+  the selected assumption is not deleted.
+
+  \item \verb|rename_tac|~\isa{names\ i} renames the innermost
+  parameters of subgoal \isa{i} according to the provided \isa{names} (which need to be distinct indentifiers).
+
+  \end{description}%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\endisatagmlref
+{\isafoldmlref}%
+%
+\isadelimmlref
+%
+\endisadelimmlref
+%
+\isamarkupsection{Tacticals \label{sec:tacticals}%
+}
+\isamarkuptrue%
+%
+\begin{isamarkuptext}%
+A \emph{tactical} is a functional combinator for building up complex
+  tactics from simpler ones.  Typical tactical perform sequential
+  composition, disjunction (choice), iteration, or goal addressing.
+  Various search strategies may be expressed via tacticals.
+
+  \medskip FIXME%
+\end{isamarkuptext}%
+\isamarkuptrue%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+%
+\isatagtheory
+\isacommand{end}\isamarkupfalse%
+%
+\endisatagtheory
+{\isafoldtheory}%
+%
+\isadelimtheory
+%
+\endisadelimtheory
+\isanewline
+\end{isabellebody}%
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: "root"
+%%% End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Docs/MainDoc.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,470 @@
+(*<*)
+theory MainDoc
+imports Main
+begin
+
+ML {*
+fun pretty_term_type_only ctxt (t, T) =
+  (if fastype_of t = Sign.certify_typ (ProofContext.theory_of ctxt) T then ()
+   else error "term_type_only: type mismatch";
+   Syntax.pretty_typ ctxt T)
+
+val _ = ThyOutput.add_commands
+  [("term_type_only", ThyOutput.args (Args.term -- Args.typ_abbrev) (ThyOutput.output pretty_term_type_only))];
+*}
+(*>*)
+text{*
+
+\begin{abstract}
+This document lists the main types, functions and syntax provided by theory @{theory Main}. It is meant as a quick overview of what is available. The sophisicated class structure is only hinted at.
+\end{abstract}
+
+\section{HOL}
+
+The basic logic: @{prop "x = y"}, @{const True}, @{const False}, @{prop"Not P"}, @{prop"P & Q"}, @{prop "P | Q"}, @{prop "P --> Q"}, @{prop"ALL x. P"}, @{prop"EX x. P"}, @{prop"EX! x. P"}, @{term"THE x. P"}.
+
+Overloaded operators:
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{text "0"} & @{typeof HOL.zero}\\
+@{text "1"} & @{typeof HOL.one}\\
+@{const HOL.plus} & @{typeof HOL.plus}\\
+@{const HOL.minus} & @{typeof HOL.minus}\\
+@{const HOL.uminus} & @{typeof HOL.uminus}\\
+@{const HOL.times} & @{typeof HOL.times}\\
+@{const HOL.inverse} & @{typeof HOL.inverse}\\
+@{const HOL.divide} & @{typeof HOL.divide}\\
+@{const HOL.abs} & @{typeof HOL.abs}\\
+@{const HOL.sgn} & @{typeof HOL.sgn}\\
+@{const HOL.less_eq} & @{typeof HOL.less_eq}\\
+@{const HOL.less} & @{typeof HOL.less}\\
+@{const HOL.default} & @{typeof HOL.default}\\
+@{const HOL.undefined} & @{typeof HOL.undefined}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{supertabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"~(x = y)"} & @{term[source]"\<not> (x = y)"}\\
+@{term[source]"P \<longleftrightarrow> Q"} & @{term"P \<longleftrightarrow> Q"}\\
+@{term"If x y z"} & @{term[source]"If x y z"}\\
+@{term"Let e\<^isub>1 (%x. e\<^isub>2)"} & @{term[source]"Let e\<^isub>1 (\<lambda>x. e\<^isub>2)"}\\
+@{term"abs x"} & @{term[source]"abs x"}\\
+@{term"uminus x"} & @{term[source]"uminus x"}\\
+\end{supertabular}
+
+\section{Orderings}
+
+A collection of classes constraining @{text"\<le>"} and @{text"<"}:
+preorders, partial orders, linear orders, dense linear orders and wellorders.
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Orderings.Least} & @{typeof Orderings.Least}\\
+@{const Orderings.min} & @{typeof Orderings.min}\\
+@{const Orderings.max} & @{typeof Orderings.max}\\
+@{const Orderings.mono} & @{typeof Orderings.mono}\\
+\end{tabular}
+
+\subsubsection*{Syntax}
+
+\begin{supertabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term[source]"x \<ge> y"} & @{term"x \<ge> y"}\\
+@{term[source]"x > y"} & @{term"x > y"}\\
+@{term"ALL x<=y. P"} & @{term[source]"\<forall>x. x \<le> y \<longrightarrow> P"}\\
+@{term"ALL x<y. P"} & @{term[source]"\<forall>x. x < y \<longrightarrow> P"}\\
+@{term"ALL x>=y. P"} & @{term[source]"\<forall>x. x \<ge> y \<longrightarrow> P"}\\
+@{term"ALL x>y. P"} & @{term[source]"\<forall>x. x > y \<longrightarrow> P"}\\
+@{term"LEAST x. P"} & @{term[source]"Least (\<lambda>x. P)"}\\
+\end{supertabular}
+
+Similar for @{text"\<exists>"} instead of @{text"\<forall>"}.
+
+\section{Set}
+
+Sets are predicates: @{text[source]"'a set  =  'a \<Rightarrow> bool"}
+\bigskip
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const "{}"} & @{term_type_only "{}" "'a set"}\\
+@{const insert} & @{term_type_only insert "'a\<Rightarrow>'a set\<Rightarrow>'a set"}\\
+@{const Collect} & @{term_type_only Collect "('a\<Rightarrow>bool)\<Rightarrow>'a set"}\\
+@{const "op :"} & @{term_type_only "op :" "'a\<Rightarrow>'a set\<Rightarrow>bool"}\\
+@{const "op Un"} & @{term_type_only "op Un" "'a set\<Rightarrow>'a set \<Rightarrow> 'a set"}\\
+@{const "op Int"} & @{term_type_only "op Int" "'a set\<Rightarrow>'a set \<Rightarrow> 'a set"}\\
+@{const UNION} & @{term_type_only UNION "'a set\<Rightarrow>('a \<Rightarrow> 'b set) \<Rightarrow> 'b set"}\\
+@{const INTER} & @{term_type_only INTER "'a set\<Rightarrow>('a \<Rightarrow> 'b set) \<Rightarrow> 'b set"}\\
+@{const Union} & @{term_type_only Union "'a set set\<Rightarrow>'a set"}\\
+@{const Inter} & @{term_type_only Inter "'a set set\<Rightarrow>'a set"}\\
+@{const Pow} & @{term_type_only Pow "'a set \<Rightarrow>'a set set"}\\
+@{const UNIV} & @{term_type_only UNIV "'a set"}\\
+@{const image} & @{term_type_only image "('a\<Rightarrow>'b)\<Rightarrow>'a set\<Rightarrow>'b set"}\\
+@{const Ball} & @{term_type_only Ball "'a set\<Rightarrow>('a\<Rightarrow>bool)\<Rightarrow>bool"}\\
+@{const Bex} & @{term_type_only Bex "'a set\<Rightarrow>('a\<Rightarrow>bool)\<Rightarrow>bool"}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{supertabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{text"{x\<^isub>1,\<dots>,x\<^isub>n}"} & @{text"insert x\<^isub>1 (\<dots> (insert x\<^isub>n {})\<dots>)"}\\
+@{term"x ~: A"} & @{term[source]"\<not>(x \<in> A)"}\\
+@{term"A \<subseteq> B"} & @{term[source]"A \<le> B"}\\
+@{term"A \<subset> B"} & @{term[source]"A < B"}\\
+@{term[source]"A \<supseteq> B"} & @{term[source]"B \<le> A"}\\
+@{term[source]"A \<supset> B"} & @{term[source]"B < A"}\\
+@{term"{x. P}"} & @{term[source]"Collect(\<lambda>x. P)"}\\
+@{term"UN x:I. A"} & @{term[source]"UNION I (\<lambda>x. A)"}\\
+@{term"UN x. A"} & @{term[source]"UNION UNIV (\<lambda>x. A)"}\\
+@{term"INT x:I. A"} & @{term[source]"INTER I (\<lambda>x. A)"}\\
+@{term"INT x. A"} & @{term[source]"INTER UNIV (\<lambda>x. A)"}\\
+@{term"ALL x:A. P"} & @{term[source]"Ball A (\<lambda>x. P)"}\\
+@{term"EX x:A. P"} & @{term[source]"Bex A (\<lambda>x. P)"}\\
+@{term"range f"} & @{term[source]"f ` UNIV"}\\
+\end{supertabular}
+
+
+\section{Fun}
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const "Fun.id"} & @{typeof Fun.id}\\
+@{const "Fun.comp"} & @{typeof Fun.comp}\\
+@{const "Fun.inj_on"} & @{term_type_only Fun.inj_on "('a\<Rightarrow>'b)\<Rightarrow>'a set\<Rightarrow>bool"}\\
+@{const "Fun.inj"} & @{typeof Fun.inj}\\
+@{const "Fun.surj"} & @{typeof Fun.surj}\\
+@{const "Fun.bij"} & @{typeof Fun.bij}\\
+@{const "Fun.bij_betw"} & @{term_type_only Fun.bij_betw "('a\<Rightarrow>'b)\<Rightarrow>'a set\<Rightarrow>'b set\<Rightarrow>bool"}\\
+@{const "Fun.fun_upd"} & @{typeof Fun.fun_upd}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"fun_upd f x y"} & @{term[source]"fun_upd f x y"}\\
+@{text"f(x\<^isub>1:=y\<^isub>1,\<dots>,x\<^isub>n:=y\<^isub>n)"} & @{text"f(x\<^isub>1:=y\<^isub>1)\<dots>(x\<^isub>n:=y\<^isub>n)"}\\
+\end{tabular}
+
+
+\section{Fixed Points}
+
+Theory: @{theory Inductive}.
+
+Least and greatest fixed points in a complete lattice @{typ 'a}:
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Inductive.lfp} & @{typeof Inductive.lfp}\\
+@{const Inductive.gfp} & @{typeof Inductive.gfp}\\
+\end{tabular}
+
+Note that in particular sets (@{typ"'a \<Rightarrow> bool"}) are complete lattices.
+
+\section{Sum\_Type}
+
+Type constructor @{text"+"}.
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Sum_Type.Inl} & @{typeof Sum_Type.Inl}\\
+@{const Sum_Type.Inr} & @{typeof Sum_Type.Inr}\\
+@{const Sum_Type.Plus} & @{term_type_only Sum_Type.Plus "'a set\<Rightarrow>'b set\<Rightarrow>('a+'b)set"}
+\end{tabular}
+
+
+\section{Product\_Type}
+
+Types @{typ unit} and @{text"\<times>"}.
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const Product_Type.Unity} & @{typeof Product_Type.Unity}\\
+@{const Pair} & @{typeof Pair}\\
+@{const fst} & @{typeof fst}\\
+@{const snd} & @{typeof snd}\\
+@{const split} & @{typeof split}\\
+@{const curry} & @{typeof curry}\\
+@{const Product_Type.Times} & @{typeof Product_Type.Times}\\
+@{const Product_Type.Sigma} & @{term_type_only Product_Type.Sigma "'a set\<Rightarrow>('a\<Rightarrow>'b set)\<Rightarrow>('a*'b)set"}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"Pair a b"} & @{term[source]"Pair a b"}\\
+@{term"split (\<lambda>x y. t)"} & @{term[source]"split (\<lambda>x y. t)"}\\
+\end{tabular}
+
+Pairs may be nested. Nesting to the right is printed as a tuple,
+e.g.\ \mbox{@{term"(a,b,c)"}} is really @{text"(a,(b,c))"}.
+Pattern matching with pairs and tuples extends to all binders,
+e.g.\ @{prop"ALL (x,y):A. P"}, @{term"{(x,y). P}"}, etc.
+
+
+\section{Relation}
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const Relation.converse} & @{term_type_only Relation.converse "('a * 'b)set \<Rightarrow> ('b*'a)set"}\\
+@{const Relation.rel_comp} & @{term_type_only Relation.rel_comp "('a*'b)set\<Rightarrow>('c*'a)set\<Rightarrow>('c*'b)set"}\\
+@{const Relation.Image} & @{term_type_only Relation.Image "('a*'b)set\<Rightarrow>'a set\<Rightarrow>'b set"}\\
+@{const Relation.inv_image} & @{term_type_only Relation.inv_image "('a*'a)set\<Rightarrow>('b\<Rightarrow>'a)\<Rightarrow>('b*'b)set"}\\
+@{const Relation.Id_on} & @{term_type_only Relation.Id_on "'a set\<Rightarrow>('a*'a)set"}\\
+@{const Relation.Id} & @{term_type_only Relation.Id "('a*'a)set"}\\
+@{const Relation.Domain} & @{term_type_only Relation.Domain "('a*'b)set\<Rightarrow>'a set"}\\
+@{const Relation.Range} & @{term_type_only Relation.Range "('a*'b)set\<Rightarrow>'b set"}\\
+@{const Relation.Field} & @{term_type_only Relation.Field "('a*'a)set\<Rightarrow>'a set"}\\
+@{const Relation.refl_on} & @{term_type_only Relation.refl_on "'a set\<Rightarrow>('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.refl} & @{term_type_only Relation.refl "('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.sym} & @{term_type_only Relation.sym "('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.antisym} & @{term_type_only Relation.antisym "('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.trans} & @{term_type_only Relation.trans "('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.irrefl} & @{term_type_only Relation.irrefl "('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.total_on} & @{term_type_only Relation.total_on "'a set\<Rightarrow>('a*'a)set\<Rightarrow>bool"}\\
+@{const Relation.total} & @{term_type_only Relation.total "('a*'a)set\<Rightarrow>bool"}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"converse r"} & @{term[source]"converse r"}
+\end{tabular}
+
+\section{Equiv\_Relations}
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const Equiv_Relations.equiv} & @{term_type_only Equiv_Relations.equiv "'a set \<Rightarrow> ('a*'a)set\<Rightarrow>bool"}\\
+@{const Equiv_Relations.quotient} & @{term_type_only Equiv_Relations.quotient "'a set \<Rightarrow> ('a \<times> 'a) set \<Rightarrow> 'a set set"}\\
+@{const Equiv_Relations.congruent} & @{term_type_only Equiv_Relations.congruent "('a*'a)set\<Rightarrow>('a\<Rightarrow>'b)\<Rightarrow>bool"}\\
+@{const Equiv_Relations.congruent2} & @{term_type_only Equiv_Relations.congruent2 "('a*'a)set\<Rightarrow>('b*'b)set\<Rightarrow>('a\<Rightarrow>'b\<Rightarrow>'c)\<Rightarrow>bool"}\\
+%@ {const Equiv_Relations.} & @ {term_type_only Equiv_Relations. ""}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"congruent r f"} & @{term[source]"congruent r f"}\\
+@{term"congruent2 r r f"} & @{term[source]"congruent2 r r f"}\\
+\end{tabular}
+
+
+\section{Transitive\_Closure}
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Transitive_Closure.rtrancl} & @{term_type_only Transitive_Closure.rtrancl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
+@{const Transitive_Closure.trancl} & @{term_type_only Transitive_Closure.trancl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
+@{const Transitive_Closure.reflcl} & @{term_type_only Transitive_Closure.reflcl "('a*'a)set\<Rightarrow>('a*'a)set"}\\
+\end{tabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"rtrancl r"} & @{term[source]"rtrancl r"}\\
+@{term"trancl r"} & @{term[source]"trancl r"}\\
+@{term"reflcl r"} & @{term[source]"reflcl r"}
+\end{tabular}
+
+
+\section{Algebra}
+
+Theories @{theory OrderedGroup} and @{theory Ring_and_Field} define a large
+collection of classes describing common algebraic structures from semigroups
+up to fields. Everything is done in terms of @{const plus}, @{const times}
+and other overloaded operators.
+
+
+\section{Nat}
+
+@{datatype nat}
+\bigskip
+
+\begin{tabular}{@ {} lllllll @ {}}
+@{term "op + :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "op - :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "op * :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "op ^ :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "op div :: nat \<Rightarrow> nat \<Rightarrow> nat"}&
+@{term "op mod :: nat \<Rightarrow> nat \<Rightarrow> nat"}&
+@{term "op dvd :: nat \<Rightarrow> nat \<Rightarrow> bool"}\\
+@{term "op \<le> :: nat \<Rightarrow> nat \<Rightarrow> bool"} &
+@{term "op < :: nat \<Rightarrow> nat \<Rightarrow> bool"} &
+@{term "min :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "max :: nat \<Rightarrow> nat \<Rightarrow> nat"} &
+@{term "Min :: nat set \<Rightarrow> nat"} &
+@{term "Max :: nat set \<Rightarrow> nat"}\\
+\end{tabular}
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Nat.of_nat} & @{typeof Nat.of_nat}
+\end{tabular}
+
+\section{Int}
+
+Type @{typ int}
+\bigskip
+
+\begin{tabular}{@ {} llllllll @ {}}
+@{term "op + :: int \<Rightarrow> int \<Rightarrow> int"} &
+@{term "op - :: int \<Rightarrow> int \<Rightarrow> int"} &
+@{term "uminus :: int \<Rightarrow> int"} &
+@{term "op * :: int \<Rightarrow> int \<Rightarrow> int"} &
+@{term "op ^ :: int \<Rightarrow> nat \<Rightarrow> int"} &
+@{term "op div :: int \<Rightarrow> int \<Rightarrow> int"}&
+@{term "op mod :: int \<Rightarrow> int \<Rightarrow> int"}&
+@{term "op dvd :: int \<Rightarrow> int \<Rightarrow> bool"}\\
+@{term "op \<le> :: int \<Rightarrow> int \<Rightarrow> bool"} &
+@{term "op < :: int \<Rightarrow> int \<Rightarrow> bool"} &
+@{term "min :: int \<Rightarrow> int \<Rightarrow> int"} &
+@{term "max :: int \<Rightarrow> int \<Rightarrow> int"} &
+@{term "Min :: int set \<Rightarrow> int"} &
+@{term "Max :: int set \<Rightarrow> int"}\\
+@{term "abs :: int \<Rightarrow> int"} &
+@{term "sgn :: int \<Rightarrow> int"}\\
+\end{tabular}
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Int.nat} & @{typeof Int.nat}\\
+@{const Int.of_int} & @{typeof Int.of_int}\\
+@{const Int.Ints} & @{term_type_only Int.Ints "'a::ring_1 set"}\\
+\end{tabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{term"of_nat::nat\<Rightarrow>int"} & @{term[source]"of_nat"}\\
+\end{tabular}
+
+
+\section{Wellfounded}
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const Wellfounded.wf} & @{term_type_only Wellfounded.wf "('a*'a)set\<Rightarrow>bool"}\\
+@{const Wellfounded.acyclic} & @{term_type_only Wellfounded.acyclic "('a*'a)set\<Rightarrow>bool"}\\
+@{const Wellfounded.acc} & @{term_type_only Wellfounded.acc "('a*'a)set\<Rightarrow>'a set"}\\
+@{const Wellfounded.measure} & @{term_type_only Wellfounded.measure "('a\<Rightarrow>nat)\<Rightarrow>('a*'a)set"}\\
+@{const Wellfounded.lex_prod} & @{term_type_only Wellfounded.lex_prod "('a*'a)set\<Rightarrow>('b*'b)set\<Rightarrow>(('a*'b)*('a*'b))set"}\\
+@{const Wellfounded.mlex_prod} & @{term_type_only Wellfounded.mlex_prod "('a\<Rightarrow>nat)\<Rightarrow>('a*'a)set\<Rightarrow>('a*'a)set"}\\
+@{const Wellfounded.less_than} & @{term_type_only Wellfounded.less_than "(nat*nat)set"}\\
+@{const Wellfounded.pred_nat} & @{term_type_only Wellfounded.pred_nat "(nat*nat)set"}\\
+\end{supertabular}
+
+
+\section{Power}
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Power.power} & @{typeof Power.power}
+\end{tabular}
+
+
+\section{Iterated Functions and Relations}
+
+Theory: @{theory Relation_Power}
+
+Iterated functions \ @{term[source]"(f::'a\<Rightarrow>'a) ^ n"} \
+and relations \ @{term[source]"(r::('a\<times>'a)set) ^ n"}.
+
+
+\section{Option}
+
+@{datatype option}
+\bigskip
+
+\begin{tabular}{@ {} l @ {~::~} l @ {}}
+@{const Option.the} & @{typeof Option.the}\\
+@{const Option.map} & @{typ[source]"('a \<Rightarrow> 'b) \<Rightarrow> 'a option \<Rightarrow> 'b option"}\\
+@{const Option.set} & @{term_type_only Option.set "'a option \<Rightarrow> 'a set"}
+\end{tabular}
+
+\section{List}
+
+@{datatype list}
+\bigskip
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const List.append} & @{typeof List.append}\\
+@{const List.butlast} & @{typeof List.butlast}\\
+@{const List.concat} & @{typeof List.concat}\\
+@{const List.distinct} & @{typeof List.distinct}\\
+@{const List.drop} & @{typeof List.drop}\\
+@{const List.dropWhile} & @{typeof List.dropWhile}\\
+@{const List.filter} & @{typeof List.filter}\\
+@{const List.foldl} & @{typeof List.foldl}\\
+@{const List.foldr} & @{typeof List.foldr}\\
+@{const List.hd} & @{typeof List.hd}\\
+@{const List.last} & @{typeof List.last}\\
+@{const List.length} & @{typeof List.length}\\
+@{const List.lenlex} & @{term_type_only List.lenlex "('a*'a)set\<Rightarrow>('a list * 'a list)set"}\\
+@{const List.lex} & @{term_type_only List.lex "('a*'a)set\<Rightarrow>('a list * 'a list)set"}\\
+@{const List.lexn} & @{term_type_only List.lexn "('a*'a)set\<Rightarrow>nat\<Rightarrow>('a list * 'a list)set"}\\
+@{const List.lexord} & @{term_type_only List.lexord "('a*'a)set\<Rightarrow>('a list * 'a list)set"}\\
+@{const List.listrel} & @{term_type_only List.listrel "('a*'a)set\<Rightarrow>('a list * 'a list)set"}\\
+@{const List.lists} & @{term_type_only List.lists "'a set\<Rightarrow>'a list set"}\\
+@{const List.listset} & @{term_type_only List.listset "'a set list \<Rightarrow> 'a list set"}\\
+@{const List.listsum} & @{typeof List.listsum}\\
+@{const List.list_all2} & @{typeof List.list_all2}\\
+@{const List.list_update} & @{typeof List.list_update}\\
+@{const List.map} & @{typeof List.map}\\
+@{const List.measures} & @{term_type_only List.measures "('a\<Rightarrow>nat)list\<Rightarrow>('a*'a)set"}\\
+@{const List.remdups} & @{typeof List.remdups}\\
+@{const List.removeAll} & @{typeof List.removeAll}\\
+@{const List.remove1} & @{typeof List.remove1}\\
+@{const List.replicate} & @{typeof List.replicate}\\
+@{const List.rev} & @{typeof List.rev}\\
+@{const List.rotate} & @{typeof List.rotate}\\
+@{const List.rotate1} & @{typeof List.rotate1}\\
+@{const List.set} & @{term_type_only List.set "'a list \<Rightarrow> 'a set"}\\
+@{const List.sort} & @{typeof List.sort}\\
+@{const List.sorted} & @{typeof List.sorted}\\
+@{const List.splice} & @{typeof List.splice}\\
+@{const List.sublist} & @{typeof List.sublist}\\
+@{const List.take} & @{typeof List.take}\\
+@{const List.takeWhile} & @{typeof List.takeWhile}\\
+@{const List.tl} & @{typeof List.tl}\\
+@{const List.upt} & @{typeof List.upt}\\
+@{const List.upto} & @{typeof List.upto}\\
+@{const List.zip} & @{typeof List.zip}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{supertabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{text"[x\<^isub>1,\<dots>,x\<^isub>n]"} & @{text"x\<^isub>1 # \<dots> # x\<^isub>n # []"}\\
+@{term"[m..<n]"} & @{term[source]"upt m n"}\\
+@{term"[i..j]"} & @{term[source]"upto i j"}\\
+@{text"[e. x \<leftarrow> xs]"} & @{term"map (%x. e) xs"}\\
+@{term"[x \<leftarrow> xs. b]"} & @{term[source]"filter (\<lambda>x. b) xs"} \\
+@{term"xs[n := x]"} & @{term[source]"list_update xs n x"}\\
+@{term"\<Sum>x\<leftarrow>xs. e"} & @{term[source]"listsum (map (\<lambda>x. e) xs)"}\\
+\end{supertabular}
+\medskip
+
+Comprehension: @{text"[e. q\<^isub>1, \<dots>, q\<^isub>n]"} where each
+qualifier @{text q\<^isub>i} is either a generator @{text"pat \<leftarrow> e"} or a
+guard, i.e.\ boolean expression.
+
+\section{Map}
+
+Maps model partial functions and are often used as finite tables. However,
+the domain of a map may be infinite.
+
+@{text"'a \<rightharpoonup> 'b  =  'a \<Rightarrow> 'b option"}
+\bigskip
+
+\begin{supertabular}{@ {} l @ {~::~} l @ {}}
+@{const Map.empty} & @{typeof Map.empty}\\
+@{const Map.map_add} & @{typeof Map.map_add}\\
+@{const Map.map_comp} & @{typeof Map.map_comp}\\
+@{const Map.restrict_map} & @{term_type_only Map.restrict_map "('a\<Rightarrow>'b option)\<Rightarrow>'a set\<Rightarrow>('a\<Rightarrow>'b option)"}\\
+@{const Map.dom} & @{term_type_only Map.dom "('a\<Rightarrow>'b option)\<Rightarrow>'a set"}\\
+@{const Map.ran} & @{term_type_only Map.ran "('a\<Rightarrow>'b option)\<Rightarrow>'b set"}\\
+@{const Map.map_le} & @{typeof Map.map_le}\\
+@{const Map.map_of} & @{typeof Map.map_of}\\
+@{const Map.map_upds} & @{typeof Map.map_upds}\\
+\end{supertabular}
+
+\subsubsection*{Syntax}
+
+\begin{tabular}{@ {} l @ {\quad$\equiv$\quad} l @ {}}
+@{text"empty"} & @{term"\<lambda>x. None"}\\
+@{term"m(x:=Some y)"} & @{term[source]"m(x:=Some y)"}\\
+@{text"m(x\<^isub>1\<mapsto>y\<^isub>1,\<dots>,x\<^isub>n\<mapsto>y\<^isub>n)"} & @{text[source]"m(x\<^isub>1\<mapsto>y\<^isub>1)\<dots>(x\<^isub>n\<mapsto>y\<^isub>n)"}\\
+@{term"map_upds m xs ys"} & @{term[source]"map_upds m xs ys"}\\
+\end{tabular}
+
+*}
+(*<*)
+end
+(*>*)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Docs/ROOT.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,2 @@
+use_thy "MainDoc";
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/Docs/document/root.tex	Fri Mar 06 15:31:26 2009 +0100
@@ -0,0 +1,65 @@
+\documentclass[11pt,a4paper]{article}
+\usepackage{isabelle,isabellesym}
+
+% further packages required for unusual symbols (see also
+% isabellesym.sty), use only when needed
+
+%\usepackage{amssymb}
+  %for \<leadsto>, \<box>, \<diamond>, \<sqsupset>, \<mho>, \<Join>,
+  %\<lhd>, \<lesssim>, \<greatersim>, \<lessapprox>, \<greaterapprox>,
+  %\<triangleq>, \<yen>, \<lozenge>
+
+%\usepackage[greek,english]{babel}
+  %option greek for \<euro>
+  %option english (default language) for \<guillemotleft>, \<guillemotright>
+
+%\usepackage[latin1]{inputenc}
+  %for \<onesuperior>, \<onequarter>, \<twosuperior>, \<onehalf>,
+  %\<threesuperior>, \<threequarters>, \<degree>
+
+%\usepackage[only,bigsqcap]{stmaryrd}
+  %for \<Sqinter>
+
+%\usepackage{eufrak}
+  %for \<AA> ... \<ZZ>, \<aa> ... \<zz> (also included in amssymb)
+
+%\usepackage{textcomp}
+  %for \<cent>, \<currency>
+
+% this should be the last package used
+\usepackage{pdfsetup}
+
+% urls in roman style, theory text in math-similar italics
+\urlstyle{rm}
+\isabellestyle{it}
+
+% for uniform font size
+\renewcommand{\isastyle}{\isastyleminor}
+
+\parindent 0pt\parskip 0.5ex
+
+\usepackage{supertabular}
+
+\begin{document}
+
+\title{What's in Main}
+\author{}
+\date{}
+\maketitle
+
+%\setcounter{tocdepth}{1}
+%\tableofcontents
+
+% generated text of all theories
+\input{session}
+
+% optional bibliography
+%\bibliographystyle{abbrv}
+%\bibliography{root}
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
--- a/src/HOL/Nominal/nominal_fresh_fun.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_fresh_fun.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -72,7 +72,7 @@
  let 
    val thy = theory_of_thm thm;
 (* the parsing function returns a qualified name, we get back the base name *)
-   val atom_basename = Sign.base_name atom_name;
+   val atom_basename = NameSpace.base_name atom_name;
    val goal = List.nth(prems_of thm, i-1);
    val ps = Logic.strip_params goal;
    val Ts = rev (map snd ps);
@@ -159,7 +159,7 @@
     NONE => all_tac thm
   | SOME atom_name  =>    
   let 
-    val atom_basename = Sign.base_name atom_name;
+    val atom_basename = NameSpace.base_name atom_name;
     val pt_name_inst = get_dyn_thm thy ("pt_"^atom_basename^"_inst") atom_basename;
     val at_name_inst = get_dyn_thm thy ("at_"^atom_basename^"_inst") atom_basename;
     fun inst_fresh vars params i st =
--- a/src/HOL/Nominal/nominal_inductive.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_inductive.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -199,7 +199,7 @@
     val atomTs = distinct op = (maps (map snd o #2) prems);
     val ind_sort = if null atomTs then HOLogic.typeS
       else Sign.certify_sort thy (map (fn T => Sign.intern_class thy
-        ("fs_" ^ Sign.base_name (fst (dest_Type T)))) atomTs);
+        ("fs_" ^ NameSpace.base_name (fst (dest_Type T)))) atomTs);
     val ([fs_ctxt_tyname], _) = Name.variants ["'n"] (Variable.names_of ctxt');
     val ([fs_ctxt_name], ctxt'') = Variable.variant_fixes ["z"] ctxt';
     val fsT = TFree (fs_ctxt_tyname, ind_sort);
@@ -273,7 +273,7 @@
 
     val perm_pi_simp = PureThy.get_thms thy "perm_pi_simp";
     val pt2_atoms = map (fn aT => PureThy.get_thm thy
-      ("pt_" ^ Sign.base_name (fst (dest_Type aT)) ^ "2")) atomTs;
+      ("pt_" ^ NameSpace.base_name (fst (dest_Type aT)) ^ "2")) atomTs;
     val eqvt_ss = Simplifier.theory_context thy HOL_basic_ss
       addsimps (eqvt_thms @ perm_pi_simp @ pt2_atoms)
       addsimprocs [mk_perm_bool_simproc ["Fun.id"],
@@ -281,7 +281,7 @@
     val fresh_bij = PureThy.get_thms thy "fresh_bij";
     val perm_bij = PureThy.get_thms thy "perm_bij";
     val fs_atoms = map (fn aT => PureThy.get_thm thy
-      ("fs_" ^ Sign.base_name (fst (dest_Type aT)) ^ "1")) atomTs;
+      ("fs_" ^ NameSpace.base_name (fst (dest_Type aT)) ^ "1")) atomTs;
     val exists_fresh' = PureThy.get_thms thy "exists_fresh'";
     val fresh_atm = PureThy.get_thms thy "fresh_atm";
     val swap_simps = PureThy.get_thms thy "swap_simps";
@@ -545,7 +545,7 @@
     ctxt'' |>
     Proof.theorem_i NONE (fn thss => fn ctxt =>
       let
-        val rec_name = space_implode "_" (map Sign.base_name names);
+        val rec_name = space_implode "_" (map NameSpace.base_name names);
         val rec_qualified = Binding.qualify false rec_name;
         val ind_case_names = RuleCases.case_names induct_cases;
         val induct_cases' = InductivePackage.partition_rules' raw_induct
@@ -575,7 +575,7 @@
              Attrib.internal (K (RuleCases.consumes 1))]),
            strong_inducts) |> snd |>
         LocalTheory.notes Thm.theoremK (map (fn ((name, elim), (_, cases)) =>
-            ((Binding.name (NameSpace.qualified (Sign.base_name name) "strong_cases"),
+            ((Binding.name (NameSpace.qualified (NameSpace.base_name name) "strong_cases"),
               [Attrib.internal (K (RuleCases.case_names (map snd cases))),
                Attrib.internal (K (RuleCases.consumes 1))]), [([elim], [])]))
           (strong_cases ~~ induct_cases')) |> snd
@@ -665,7 +665,7 @@
   in
     ctxt |>
     LocalTheory.notes Thm.theoremK (map (fn (name, ths) =>
-        ((Binding.name (NameSpace.qualified (Sign.base_name name) "eqvt"),
+        ((Binding.name (NameSpace.qualified (NameSpace.base_name name) "eqvt"),
           [Attrib.internal (K NominalThmDecls.eqvt_add)]), [(ths, [])]))
       (names ~~ transp thss)) |> snd
   end;
--- a/src/HOL/Nominal/nominal_inductive2.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_inductive2.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -229,7 +229,7 @@
     val atoms = map (fst o dest_Type) atomTs;
     val ind_sort = if null atomTs then HOLogic.typeS
       else Sign.certify_sort thy (map (fn a => Sign.intern_class thy
-        ("fs_" ^ Sign.base_name a)) atoms);
+        ("fs_" ^ NameSpace.base_name a)) atoms);
     val ([fs_ctxt_tyname], _) = Name.variants ["'n"] (Variable.names_of ctxt');
     val ([fs_ctxt_name], ctxt'') = Variable.variant_fixes ["z"] ctxt';
     val fsT = TFree (fs_ctxt_tyname, ind_sort);
@@ -296,7 +296,7 @@
 
     val perm_pi_simp = PureThy.get_thms thy "perm_pi_simp";
     val pt2_atoms = map (fn a => PureThy.get_thm thy
-      ("pt_" ^ Sign.base_name a ^ "2")) atoms;
+      ("pt_" ^ NameSpace.base_name a ^ "2")) atoms;
     val eqvt_ss = Simplifier.theory_context thy HOL_basic_ss
       addsimps (eqvt_thms @ perm_pi_simp @ pt2_atoms)
       addsimprocs [mk_perm_bool_simproc ["Fun.id"],
@@ -324,7 +324,7 @@
         val atom = fst (dest_Type T);
         val {at_inst, ...} = NominalAtoms.the_atom_info thy atom;
         val fs_atom = PureThy.get_thm thy
-          ("fs_" ^ Sign.base_name atom ^ "1");
+          ("fs_" ^ NameSpace.base_name atom ^ "1");
         val avoid_th = Drule.instantiate'
           [SOME (ctyp_of thy (fastype_of p))] [SOME (cterm_of thy p)]
           ([at_inst, fin, fs_atom] MRS @{thm at_set_avoiding});
@@ -452,7 +452,7 @@
     ctxt'' |>
     Proof.theorem_i NONE (fn thss => fn ctxt =>
       let
-        val rec_name = space_implode "_" (map Sign.base_name names);
+        val rec_name = space_implode "_" (map NameSpace.base_name names);
         val rec_qualified = Binding.qualify false rec_name;
         val ind_case_names = RuleCases.case_names induct_cases;
         val induct_cases' = InductivePackage.partition_rules' raw_induct
--- a/src/HOL/Nominal/nominal_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -49,9 +49,9 @@
 
 fun dt_cases (descr: descr) (_, args, constrs) =
   let
-    fun the_bname i = Sign.base_name (#1 (valOf (AList.lookup (op =) descr i)));
+    fun the_bname i = NameSpace.base_name (#1 (valOf (AList.lookup (op =) descr i)));
     val bnames = map the_bname (distinct op = (List.concat (map dt_recs args)));
-  in map (fn (c, _) => space_implode "_" (Sign.base_name c :: bnames)) constrs end;
+  in map (fn (c, _) => space_implode "_" (NameSpace.base_name c :: bnames)) constrs end;
 
 
 fun induct_cases descr =
@@ -364,7 +364,7 @@
         val pi2 = Free ("pi2", permT);
         val pt_inst = pt_inst_of thy2 a;
         val pt2' = pt_inst RS pt2;
-        val pt2_ax = PureThy.get_thm thy2 (NameSpace.map_base (fn s => "pt_" ^ s ^ "2") a);
+        val pt2_ax = PureThy.get_thm thy2 (NameSpace.map_base_name (fn s => "pt_" ^ s ^ "2") a);
       in List.take (map standard (split_conj_thm
         (Goal.prove_global thy2 [] []
            (augment_sort thy2 [pt_class_of thy2 a]
@@ -399,7 +399,7 @@
         val pt_inst = pt_inst_of thy2 a;
         val pt3' = pt_inst RS pt3;
         val pt3_rev' = at_inst RS (pt_inst RS pt3_rev);
-        val pt3_ax = PureThy.get_thm thy2 (NameSpace.map_base (fn s => "pt_" ^ s ^ "3") a);
+        val pt3_ax = PureThy.get_thm thy2 (NameSpace.map_base_name (fn s => "pt_" ^ s ^ "3") a);
       in List.take (map standard (split_conj_thm
         (Goal.prove_global thy2 [] []
           (augment_sort thy2 [pt_class_of thy2 a] (Logic.mk_implies
@@ -664,7 +664,7 @@
               asm_full_simp_tac (simpset_of thy addsimps
                 [Rep RS perm_closed RS Abs_inverse]) 1,
               asm_full_simp_tac (HOL_basic_ss addsimps [PureThy.get_thm thy
-                ("pt_" ^ Sign.base_name atom ^ "3")]) 1]) thy
+                ("pt_" ^ NameSpace.base_name atom ^ "3")]) 1]) thy
           end)
         (Abs_inverse_thms ~~ Rep_inverse_thms ~~ Rep_thms ~~ perm_defs ~~
            new_type_names ~~ tyvars ~~ perm_closed_thms);
@@ -798,7 +798,7 @@
         val def = Logic.mk_equals (lhs, Const (abs_name, T' --> T) $ rhs);
         val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq
           (Const (rep_name, T --> T') $ lhs, rhs));
-        val def_name = (Sign.base_name cname) ^ "_def";
+        val def_name = (NameSpace.base_name cname) ^ "_def";
         val ([def_thm], thy') = thy |>
           Sign.add_consts_i [(cname', constrT, mx)] |>
           (PureThy.add_defs false o map Thm.no_attributes) [(Binding.name def_name, def)]
@@ -889,7 +889,7 @@
           map (fn ((cname, dts), constr_rep_thm) =>
         let
           val cname = Sign.intern_const thy8
-            (NameSpace.append tname (Sign.base_name cname));
+            (NameSpace.append tname (NameSpace.base_name cname));
           val permT = mk_permT (Type (atom, []));
           val pi = Free ("pi", permT);
 
@@ -945,7 +945,7 @@
         if null dts then NONE else SOME
         let
           val cname = Sign.intern_const thy8
-            (NameSpace.append tname (Sign.base_name cname));
+            (NameSpace.append tname (NameSpace.base_name cname));
 
           fun make_inj ((dts, dt), (j, args1, args2, eqs)) =
             let
@@ -987,7 +987,7 @@
       in List.concat (map (fn (cname, dts) => map (fn atom =>
         let
           val cname = Sign.intern_const thy8
-            (NameSpace.append tname (Sign.base_name cname));
+            (NameSpace.append tname (NameSpace.base_name cname));
           val atomT = Type (atom, []);
 
           fun process_constr ((dts, dt), (j, args1, args2)) =
@@ -1100,7 +1100,7 @@
            (fn _ => indtac dt_induct indnames 1 THEN
             ALLGOALS (asm_full_simp_tac (simpset_of thy8 addsimps
               (abs_supp @ supp_atm @
-               PureThy.get_thms thy8 ("fs_" ^ Sign.base_name atom ^ "1") @
+               PureThy.get_thms thy8 ("fs_" ^ NameSpace.base_name atom ^ "1") @
                List.concat supp_thms))))),
          length new_type_names))
       end) atoms;
@@ -1232,9 +1232,9 @@
     val fin_set_fresh = map (fn s =>
       at_inst_of thy9 s RS at_fin_set_fresh) dt_atoms;
     val pt1_atoms = map (fn Type (s, _) =>
-      PureThy.get_thm thy9 ("pt_" ^ Sign.base_name s ^ "1")) dt_atomTs;
+      PureThy.get_thm thy9 ("pt_" ^ NameSpace.base_name s ^ "1")) dt_atomTs;
     val pt2_atoms = map (fn Type (s, _) =>
-      PureThy.get_thm thy9 ("pt_" ^ Sign.base_name s ^ "2") RS sym) dt_atomTs;
+      PureThy.get_thm thy9 ("pt_" ^ NameSpace.base_name s ^ "2") RS sym) dt_atomTs;
     val exists_fresh' = PureThy.get_thms thy9 "exists_fresh'";
     val fs_atoms = PureThy.get_thms thy9 "fin_supp";
     val abs_supp = PureThy.get_thms thy9 "abs_supp";
@@ -1559,7 +1559,7 @@
 
     val rec_fin_supp_thms = map (fn aT =>
       let
-        val name = Sign.base_name (fst (dest_Type aT));
+        val name = NameSpace.base_name (fst (dest_Type aT));
         val fs_name = PureThy.get_thm thy11 ("fs_" ^ name ^ "1");
         val aset = HOLogic.mk_setT aT;
         val finite = Const ("Finite_Set.finite", aset --> HOLogic.boolT);
@@ -1598,7 +1598,7 @@
 
     val rec_fresh_thms = map (fn ((aT, eqvt_ths), finite_prems) =>
       let
-        val name = Sign.base_name (fst (dest_Type aT));
+        val name = NameSpace.base_name (fst (dest_Type aT));
         val fs_name = PureThy.get_thm thy11 ("fs_" ^ name ^ "1");
         val a = Free ("a", aT);
         val freshs = map (fn (f, fT) => HOLogic.mk_Trueprop
@@ -2012,10 +2012,10 @@
     val (reccomb_defs, thy12) =
       thy11
       |> Sign.add_consts_i (map (fn ((name, T), T') =>
-          (Sign.base_name name, rec_fn_Ts @ [T] ---> T', NoSyn))
+          (NameSpace.base_name name, rec_fn_Ts @ [T] ---> T', NoSyn))
           (reccomb_names ~~ recTs ~~ rec_result_Ts))
       |> (PureThy.add_defs false o map Thm.no_attributes) (map (fn ((((name, comb), set), T), T') =>
-          (Binding.name (Sign.base_name name ^ "_def"), Logic.mk_equals (comb, absfree ("x", T,
+          (Binding.name (NameSpace.base_name name ^ "_def"), Logic.mk_equals (comb, absfree ("x", T,
            Const ("The", (T' --> HOLogic.boolT) --> T') $ absfree ("y", T',
              set $ Free ("x", T) $ Free ("y", T'))))))
                (reccomb_names ~~ reccombs ~~ rec_sets ~~ recTs ~~ rec_result_Ts));
--- a/src/HOL/Nominal/nominal_permeq.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_permeq.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -110,7 +110,7 @@
           Type("fun",[Type("List.list",[Type("*",[Type(n,_),_])]),_])) $ pi $ (f $ x)) => 
             (if (applicable_app f) then
               let
-                val name = Sign.base_name n
+                val name = NameSpace.base_name n
                 val at_inst = PureThy.get_thm sg ("at_" ^ name ^ "_inst")
                 val pt_inst = PureThy.get_thm sg ("pt_" ^ name ^ "_inst")
               in SOME ((at_inst RS (pt_inst RS perm_eq_app)) RS eq_reflection) end
@@ -198,8 +198,8 @@
          Type ("fun", [Type ("List.list", [Type ("*", [U as Type (uname,_),_])]),_])) $ 
           pi2 $ t)) =>
     let
-      val tname' = Sign.base_name tname
-      val uname' = Sign.base_name uname
+      val tname' = NameSpace.base_name tname
+      val uname' = NameSpace.base_name uname
     in
       if pi1 <> pi2 then  (* only apply the composition rule in this case *)
         if T = U then    
--- a/src/HOL/Nominal/nominal_primrec.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_primrec.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -207,7 +207,7 @@
     val frees = ls @ x :: rs;
     val raw_rhs = list_abs_free (frees,
       list_comb (Const (rec_name, dummyT), fs @ [Free x]))
-    val def_name = Thm.def_name (Sign.base_name fname);
+    val def_name = Thm.def_name (NameSpace.base_name fname);
     val rhs = singleton (Syntax.check_terms ctxt) raw_rhs;
     val SOME var = get_first (fn ((b, _), mx) =>
       if Binding.name_of b = fname then SOME (b, mx) else NONE) fixes;
@@ -286,7 +286,7 @@
       fold_map (apfst (snd o snd) oo
         LocalTheory.define Thm.definitionK o fst) defs';
     val qualify = Binding.qualify false
-      (space_implode "_" (map (Sign.base_name o #1) defs));
+      (space_implode "_" (map (NameSpace.base_name o #1) defs));
     val names_atts' = map (apfst qualify) names_atts;
     val cert = cterm_of (ProofContext.theory_of lthy');
 
--- a/src/HOL/Nominal/nominal_thmdecls.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Nominal/nominal_thmdecls.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -115,7 +115,7 @@
                (Var (n,ty))) =>
              let
                 (* FIXME: this should be an operation the library *)
-                val class_name = (NameSpace.map_base (fn s => "pt_"^s) tyatm)
+                val class_name = (NameSpace.map_base_name (fn s => "pt_"^s) tyatm)
              in
                 if (Sign.of_sort thy (ty,[class_name]))
                 then [(pi,typi)]
--- a/src/HOL/Orderings.thy	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Orderings.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -968,9 +968,7 @@
 context order
 begin
 
-definition
-  mono :: "('a \<Rightarrow> 'b\<Colon>order) \<Rightarrow> bool"
-where
+definition mono :: "('a \<Rightarrow> 'b\<Colon>order) \<Rightarrow> bool" where
   "mono f \<longleftrightarrow> (\<forall>x y. x \<le> y \<longrightarrow> f x \<le> f y)"
 
 lemma monoI [intro?]:
@@ -983,11 +981,76 @@
   shows "mono f \<Longrightarrow> x \<le> y \<Longrightarrow> f x \<le> f y"
   unfolding mono_def by iprover
 
+definition strict_mono :: "('a \<Rightarrow> 'b\<Colon>order) \<Rightarrow> bool" where
+  "strict_mono f \<longleftrightarrow> (\<forall>x y. x < y \<longrightarrow> f x < f y)"
+
+lemma strict_monoI [intro?]:
+  assumes "\<And>x y. x < y \<Longrightarrow> f x < f y"
+  shows "strict_mono f"
+  using assms unfolding strict_mono_def by auto
+
+lemma strict_monoD [dest?]:
+  "strict_mono f \<Longrightarrow> x < y \<Longrightarrow> f x < f y"
+  unfolding strict_mono_def by auto
+
+lemma strict_mono_mono [dest?]:
+  assumes "strict_mono f"
+  shows "mono f"
+proof (rule monoI)
+  fix x y
+  assume "x \<le> y"
+  show "f x \<le> f y"
+  proof (cases "x = y")
+    case True then show ?thesis by simp
+  next
+    case False with `x \<le> y` have "x < y" by simp
+    with assms strict_monoD have "f x < f y" by auto
+    then show ?thesis by simp
+  qed
+qed
+
 end
 
 context linorder
 begin
 
+lemma strict_mono_eq:
+  assumes "strict_mono f"
+  shows "f x = f y \<longleftrightarrow> x = y"
+proof
+  assume "f x = f y"
+  show "x = y" proof (cases x y rule: linorder_cases)
+    case less with assms strict_monoD have "f x < f y" by auto
+    with `f x = f y` show ?thesis by simp
+  next
+    case equal then show ?thesis .
+  next
+    case greater with assms strict_monoD have "f y < f x" by auto
+    with `f x = f y` show ?thesis by simp
+  qed
+qed simp
+
+lemma strict_mono_less_eq:
+  assumes "strict_mono f"
+  shows "f x \<le> f y \<longleftrightarrow> x \<le> y"
+proof
+  assume "x \<le> y"
+  with assms strict_mono_mono monoD show "f x \<le> f y" by auto
+next
+  assume "f x \<le> f y"
+  show "x \<le> y" proof (rule ccontr)
+    assume "\<not> x \<le> y" then have "y < x" by simp
+    with assms strict_monoD have "f y < f x" by auto
+    with `f x \<le> f y` show False by simp
+  qed
+qed
+  
+lemma strict_mono_less:
+  assumes "strict_mono f"
+  shows "f x < f y \<longleftrightarrow> x < y"
+  using assms
+    by (auto simp add: less_le Orderings.less_le strict_mono_eq strict_mono_less_eq)
+
 lemma min_of_mono:
   fixes f :: "'a \<Rightarrow> 'b\<Colon>linorder"
   shows "mono f \<Longrightarrow> min (f m) (f n) = f (min m n)"
--- a/src/HOL/SizeChange/Graphs.thy	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/SizeChange/Graphs.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -351,7 +351,7 @@
 
 lemma in_tcl: 
   "has_edge (tcl G) a x b = (\<exists>n>0. has_edge (G ^ n) a x b)"
-  apply (auto simp: tcl_is_SUP in_SUP simp del: power_graph.simps)
+  apply (auto simp: tcl_is_SUP in_SUP simp del: power_graph.simps power_Suc)
   apply (rule_tac x = "n - 1" in exI, auto)
   done
 
--- a/src/HOL/Statespace/distinct_tree_prover.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Statespace/distinct_tree_prover.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -352,14 +352,14 @@
   | distinctTree_tac _ _ _ = no_tac;
 
 fun distinctFieldSolver names = mk_solver' "distinctFieldSolver"
-     (fn ss => case #context (#1 (rep_ss ss)) of
+     (fn ss => case try Simplifier.the_context ss of
                  SOME ctxt => SUBGOAL (distinctTree_tac names ctxt)
                 | NONE => fn i => no_tac)
 
 fun distinct_simproc names =
   Simplifier.simproc @{theory HOL} "DistinctTreeProver.distinct_simproc" ["x = y"]
     (fn thy => fn ss => fn (Const ("op =",_)$x$y) =>
-        case #context (#1 (rep_ss ss)) of
+        case try Simplifier.the_context ss of
         SOME ctxt => Option.map (fn neq => neq_to_eq_False OF [neq]) 
                       (get_fst_success (neq_x_y ctxt x y) names)
        | NONE => NONE
--- a/src/HOL/Statespace/state_fun.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Statespace/state_fun.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -146,7 +146,7 @@
           
           val ct = cterm_of thy 
                     (Const ("StateFun.lookup",lT)$destr$n$(fst (mk_upds s)));
-          val ctxt = the (#context (#1 (rep_ss ss)));
+          val ctxt = Simplifier.the_context ss;
           val basic_ss = #1 (StateFunData.get (Context.Proof ctxt));
           val ss' = Simplifier.context 
                      (Config.map MetaSimplifier.simp_depth_limit (K 100) ctxt) basic_ss;
@@ -241,7 +241,7 @@
                       end
                | mk_updterm _ t = init_seed t;
 
-	     val ctxt = the (#context (#1 (rep_ss ss))) |>
+	     val ctxt = Simplifier.the_context ss |>
                         Config.map MetaSimplifier.simp_depth_limit (K 100);
              val ss1 = Simplifier.context ctxt ss';
              val ss2 = Simplifier.context ctxt 
@@ -336,17 +336,17 @@
     [] => ""
    | c::cs => String.implode (Char.toUpper c::cs ))
 
-fun mkName (Type (T,args)) = concat (map mkName args) ^ mkUpper (NameSpace.base T)
-  | mkName (TFree (x,_)) = mkUpper (NameSpace.base x)
-  | mkName (TVar ((x,_),_)) = mkUpper (NameSpace.base x);
+fun mkName (Type (T,args)) = concat (map mkName args) ^ mkUpper (NameSpace.base_name T)
+  | mkName (TFree (x,_)) = mkUpper (NameSpace.base_name x)
+  | mkName (TVar ((x,_),_)) = mkUpper (NameSpace.base_name x);
 
 fun is_datatype thy n = is_some (Symtab.lookup (DatatypePackage.get_datatypes thy) n);
 
-fun mk_map ("List.list") = Syntax.const "List.map"
-  | mk_map n = Syntax.const ("StateFun." ^  "map_" ^ NameSpace.base n);
+fun mk_map "List.list" = Syntax.const "List.map"
+  | mk_map n = Syntax.const ("StateFun.map_" ^ NameSpace.base_name n);
 
 fun gen_constr_destr comp prfx thy (Type (T,[])) = 
-      Syntax.const (deco prfx (mkUpper (NameSpace.base T)))
+      Syntax.const (deco prfx (mkUpper (NameSpace.base_name T)))
   | gen_constr_destr comp prfx thy (T as Type ("fun",_)) =
      let val (argTs,rangeT) = strip_type T;
      in comp 
@@ -360,11 +360,11 @@
      then (* datatype args are recursively embedded into val *)
          (case argTs of
            [argT] => comp 
-                     ((Syntax.const (deco prfx (mkUpper (NameSpace.base T)))))
+                     ((Syntax.const (deco prfx (mkUpper (NameSpace.base_name T)))))
                      ((mk_map T $ gen_constr_destr comp prfx thy argT))
           | _ => raise (TYPE ("StateFun.gen_constr_destr",[T'],[])))
      else (* type args are not recursively embedded into val *)
-           Syntax.const (deco prfx (concat (map mkName argTs) ^ mkUpper (NameSpace.base T)))
+           Syntax.const (deco prfx (concat (map mkName argTs) ^ mkUpper (NameSpace.base_name T)))
   | gen_constr_destr thy _ _ T = raise (TYPE ("StateFun.gen_constr_destr",[T],[]));
                    
 val mk_constr = gen_constr_destr (fn a => fn b => Syntax.const "Fun.comp" $ a $ b) ""
--- a/src/HOL/Statespace/state_space.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Statespace/state_space.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -236,14 +236,14 @@
   | distinctTree_tac _ _ = no_tac;
 
 val distinctNameSolver = mk_solver' "distinctNameSolver"
-     (fn ss => case #context (#1 (rep_ss ss)) of
+     (fn ss => case try Simplifier.the_context ss of
                  SOME ctxt => SUBGOAL (distinctTree_tac ctxt)
                 | NONE => fn i => no_tac)
 
 val distinct_simproc =
   Simplifier.simproc @{theory HOL} "StateSpace.distinct_simproc" ["x = y"]
     (fn thy => fn ss => (fn (Const ("op =",_)$(x as Free _)$(y as Free _)) =>
-        (case #context (#1 (rep_ss ss)) of
+        (case try Simplifier.the_context ss of
           SOME ctxt => Option.map (fn neq => DistinctTreeProver.neq_to_eq_False OF [neq])
                        (neq_x_y ctxt x y)
         | NONE => NONE)
@@ -645,7 +645,7 @@
 fun update_tr ctxt [s,Free (n,_),v] = gen_update_tr false ctxt n v s;
 
 fun update_tr' ctxt [_$Free (prj,_),_$Free (inj,_),n as (_$Free (name,_)),(Const (k,_)$v),s] =
-     if NameSpace.base k = NameSpace.base KN then
+     if NameSpace.base_name k = NameSpace.base_name KN then
         (case get_comp (Context.Proof ctxt) name of
           SOME (T,_) => if inj=inject_name T andalso prj=project_name T then
                            Syntax.const "_statespace_update" $ s $ n $ v
--- a/src/HOL/Tools/TFL/post.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/TFL/post.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -223,7 +223,7 @@
  *---------------------------------------------------------------------------*)
 fun define_i strict thy cs ss congs wfs fid R eqs =
   let val {functional,pats} = Prim.mk_functional thy eqs
-      val (thy, def) = Prim.wfrec_definition0 thy (Sign.base_name fid) R functional
+      val (thy, def) = Prim.wfrec_definition0 thy (NameSpace.base_name fid) R functional
       val {induct, rules, tcs} = 
           simplify_defn strict thy cs ss congs wfs fid pats def
       val rules' = 
@@ -248,7 +248,7 @@
 
 fun defer_i thy congs fid eqs =
  let val {rules,R,theory,full_pats_TCs,SV,...} =
-             Prim.lazyR_def thy (Sign.base_name fid) congs eqs
+             Prim.lazyR_def thy (NameSpace.base_name fid) congs eqs
      val f = func_of_cond_eqn (concl (R.CONJUNCT1 rules handle U.ERR _ => rules));
      val dummy = writeln "Proving induction theorem ...";
      val induction = Prim.mk_induction theory
--- a/src/HOL/Tools/TFL/tfl.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/TFL/tfl.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -349,7 +349,7 @@
           | L => mk_functional_err
  ("The following clauses are redundant (covered by preceding clauses): " ^
                    commas (map (fn i => Int.toString (i + 1)) L))
- in {functional = Abs(Sign.base_name fname, ftype,
+ in {functional = Abs(NameSpace.base_name fname, ftype,
                       abstract_over (atom,
                                      absfree(aname,atype, case_tm))),
      pats = patts2}
--- a/src/HOL/Tools/datatype_abs_proofs.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_abs_proofs.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -235,10 +235,10 @@
     val (reccomb_defs, thy2) =
       thy1
       |> Sign.add_consts_i (map (fn ((name, T), T') =>
-          (Sign.base_name name, reccomb_fn_Ts @ [T] ---> T', NoSyn))
+          (NameSpace.base_name name, reccomb_fn_Ts @ [T] ---> T', NoSyn))
           (reccomb_names ~~ recTs ~~ rec_result_Ts))
       |> (PureThy.add_defs false o map Thm.no_attributes) (map (fn ((((name, comb), set), T), T') =>
-          (Binding.name (Sign.base_name name ^ "_def"), Logic.mk_equals (comb, absfree ("x", T,
+          (Binding.name (NameSpace.base_name name ^ "_def"), Logic.mk_equals (comb, absfree ("x", T,
            Const ("The", (T' --> HOLogic.boolT) --> T') $ absfree ("y", T',
              set $ Free ("x", T) $ Free ("y", T'))))))
                (reccomb_names ~~ reccombs ~~ rec_sets ~~ recTs ~~ rec_result_Ts))
@@ -316,8 +316,8 @@
           val fns = (List.concat (Library.take (i, case_dummy_fns))) @
             fns2 @ (List.concat (Library.drop (i + 1, case_dummy_fns)));
           val reccomb = Const (recname, (map fastype_of fns) @ [T] ---> T');
-          val decl = ((Binding.name (Sign.base_name name), caseT), NoSyn);
-          val def = (Binding.name (Sign.base_name name ^ "_def"),
+          val decl = ((Binding.name (NameSpace.base_name name), caseT), NoSyn);
+          val def = (Binding.name (NameSpace.base_name name ^ "_def"),
             Logic.mk_equals (list_comb (Const (name, caseT), fns1),
               list_comb (reccomb, (List.concat (Library.take (i, case_dummy_fns))) @
                 fns2 @ (List.concat (Library.drop (i + 1, case_dummy_fns))) )));
--- a/src/HOL/Tools/datatype_aux.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_aux.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -224,7 +224,7 @@
   | mk_fun_dtyp (T :: Ts) U = DtType ("fun", [T, mk_fun_dtyp Ts U]);
 
 fun name_of_typ (Type (s, Ts)) =
-      let val s' = Sign.base_name s
+      let val s' = NameSpace.base_name s
       in space_implode "_" (List.filter (not o equal "") (map name_of_typ Ts) @
         [if Syntax.is_identifier s' then s' else "x"])
       end
--- a/src/HOL/Tools/datatype_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -174,9 +174,9 @@
 
 fun dt_cases (descr: descr) (_, args, constrs) =
   let
-    fun the_bname i = Sign.base_name (#1 (the (AList.lookup (op =) descr i)));
+    fun the_bname i = NameSpace.base_name (#1 (the (AList.lookup (op =) descr i)));
     val bnames = map the_bname (distinct (op =) (maps dt_recs args));
-  in map (fn (c, _) => space_implode "_" (Sign.base_name c :: bnames)) constrs end;
+  in map (fn (c, _) => space_implode "_" (NameSpace.base_name c :: bnames)) constrs end;
 
 
 fun induct_cases descr =
@@ -519,7 +519,7 @@
     val cs = map (apsnd (map norm_constr)) raw_cs;
     val dtyps_of_typ = map (dtyp_of_typ (map (rpair (map fst vs) o fst) cs))
       o fst o strip_type;
-    val new_type_names = map NameSpace.base (the_default (map fst cs) alt_names);
+    val new_type_names = map NameSpace.base_name (the_default (map fst cs) alt_names);
 
     fun mk_spec (i, (tyco, constr)) = (i, (tyco,
       map (DtTFree o fst) vs,
--- a/src/HOL/Tools/datatype_prop.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_prop.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -47,7 +47,7 @@
   let
     fun type_name (TFree (name, _)) = implode (tl (explode name))
       | type_name (Type (name, _)) = 
-          let val name' = Sign.base_name name
+          let val name' = NameSpace.base_name name
           in if Syntax.is_identifier name' then name' else "x" end;
   in indexify_names (map type_name Ts) end;
 
--- a/src/HOL/Tools/datatype_realizer.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_realizer.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -168,7 +168,7 @@
         val Ts = map (typ_of_dtyp descr sorts) cargs;
         val frees = Name.variant_list ["P", "y"] (DatatypeProp.make_tnames Ts) ~~ Ts;
         val free_ts = map Free frees;
-        val r = Free ("r" ^ NameSpace.base cname, Ts ---> rT)
+        val r = Free ("r" ^ NameSpace.base_name cname, Ts ---> rT)
       in (r, list_all_free (frees, Logic.mk_implies (HOLogic.mk_Trueprop
         (HOLogic.mk_eq (Free ("y", T), list_comb (Const (cname, Ts ---> T), free_ts))),
           HOLogic.mk_Trueprop (Free ("P", rT --> HOLogic.boolT) $
--- a/src/HOL/Tools/datatype_rep_proofs.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/datatype_rep_proofs.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -236,7 +236,7 @@
         val lhs = list_comb (Const (cname, constrT), l_args);
         val rhs = mk_univ_inj r_args n i;
         val def = Logic.mk_equals (lhs, Const (abs_name, Univ_elT --> T) $ rhs);
-        val def_name = Sign.base_name cname ^ "_def";
+        val def_name = NameSpace.base_name cname ^ "_def";
         val eqn = HOLogic.mk_Trueprop (HOLogic.mk_eq
           (Const (rep_name, T --> Univ_elT) $ lhs, rhs));
         val ([def_thm], thy') =
@@ -343,7 +343,7 @@
         
         val (fs, eqns, isos) = Library.foldl process_dt (([], [], []), ds);
         val fTs = map fastype_of fs;
-        val defs = map (fn (rec_name, (T, iso_name)) => (Binding.name (Sign.base_name iso_name ^ "_def"),
+        val defs = map (fn (rec_name, (T, iso_name)) => (Binding.name (NameSpace.base_name iso_name ^ "_def"),
           Logic.mk_equals (Const (iso_name, T --> Univ_elT),
             list_comb (Const (rec_name, fTs @ [T] ---> Univ_elT), fs)))) (rec_names ~~ isos);
         val (def_thms, thy') =
--- a/src/HOL/Tools/function_package/size.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/function_package/size.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -87,7 +87,7 @@
       recTs1 ~~ alt_names' |>
       map (fn (T as Type (s, _), optname) =>
         let
-          val s' = the_default (Sign.base_name s) optname ^ "_size";
+          val s' = the_default (NameSpace.base_name s) optname ^ "_size";
           val s'' = Sign.full_bname thy s'
         in
           (s'',
@@ -140,7 +140,7 @@
     val ((size_def_thms, size_def_thms'), thy') =
       thy
       |> Sign.add_consts_i (map (fn (s, T) =>
-           (Sign.base_name s, param_size_fTs @ [T] ---> HOLogic.natT, NoSyn))
+           (NameSpace.base_name s, param_size_fTs @ [T] ---> HOLogic.natT, NoSyn))
            (size_names ~~ recTs1))
       |> PureThy.add_defs false
         (map (Thm.no_attributes o apsnd (Logic.mk_equals o apsnd (app fs)))
@@ -221,8 +221,8 @@
 fun add_size_thms (new_type_names as name :: _) thy =
   let
     val info as {descr, alt_names, ...} = DatatypePackage.the_datatype thy name;
-    val prefix = NameSpace.map_base (K (space_implode "_"
-      (the_default (map Sign.base_name new_type_names) alt_names))) name;
+    val prefix = NameSpace.map_base_name (K (space_implode "_"
+      (the_default (map NameSpace.base_name new_type_names) alt_names))) name;
     val no_size = exists (fn (_, (_, _, constrs)) => exists (fn (_, cargs) => exists (fn dt =>
       is_rec_type dt andalso not (null (fst (strip_dtyp dt)))) cargs) constrs) descr
   in if no_size then thy
--- a/src/HOL/Tools/inductive_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/inductive_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -698,7 +698,7 @@
       ctxt1 |>
       LocalTheory.note kind ((rec_qualified (Binding.name "intros"), []), intrs') ||>>
       fold_map (fn (name, (elim, cases)) =>
-        LocalTheory.note kind ((Binding.name (NameSpace.qualified (Sign.base_name name) "cases"),
+        LocalTheory.note kind ((Binding.name (NameSpace.qualified (NameSpace.base_name name) "cases"),
           [Attrib.internal (K (RuleCases.case_names cases)),
            Attrib.internal (K (RuleCases.consumes 1)),
            Attrib.internal (K (Induct.cases_pred name)),
--- a/src/HOL/Tools/inductive_realizer.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/inductive_realizer.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -68,8 +68,8 @@
     val (Const (s, _), ts) = strip_comb (HOLogic.dest_Trueprop
       (Logic.strip_imp_concl (prop_of (hd intrs))));
     val params = map dest_Var (Library.take (nparms, ts));
-    val tname = space_implode "_" (Sign.base_name s ^ "T" :: vs);
-    fun constr_of_intr intr = (Sign.base_name (name_of_thm intr),
+    val tname = space_implode "_" (NameSpace.base_name s ^ "T" :: vs);
+    fun constr_of_intr intr = (NameSpace.base_name (name_of_thm intr),
       map (Logic.unvarifyT o snd) (rev (Term.add_vars (prop_of intr) []) \\ params) @
         filter_out (equal Extraction.nullT) (map
           (Logic.unvarifyT o Extraction.etype_of thy vs []) (prems_of intr)),
@@ -112,7 +112,7 @@
     val rT = if n then Extraction.nullT
       else Type (space_implode "_" (s ^ "T" :: vs),
         map (fn a => TVar (("'" ^ a, 0), HOLogic.typeS)) vs @ Tvs);
-    val r = if n then Extraction.nullt else Var ((Sign.base_name s, 0), rT);
+    val r = if n then Extraction.nullt else Var ((NameSpace.base_name s, 0), rT);
     val S = list_comb (h, params @ xs);
     val rvs = relevant_vars S;
     val vs' = map fst rvs \\ vs;
@@ -195,7 +195,7 @@
           in if conclT = Extraction.nullT
             then list_abs_free (map dest_Free xs, HOLogic.unit)
             else list_abs_free (map dest_Free xs, list_comb
-              (Free ("r" ^ Sign.base_name (name_of_thm intr),
+              (Free ("r" ^ NameSpace.base_name (name_of_thm intr),
                 map fastype_of (rev args) ---> conclT), rev args))
           end
 
@@ -217,7 +217,7 @@
       end) (premss ~~ dummies);
     val frees = fold Term.add_frees fs [];
     val Ts = map fastype_of fs;
-    fun name_of_fn intr = "r" ^ Sign.base_name (name_of_thm intr)
+    fun name_of_fn intr = "r" ^ NameSpace.base_name (name_of_thm intr)
   in
     fst (fold_map (fn concl => fn names =>
       let val T = Extraction.etype_of thy vs [] concl
@@ -245,7 +245,7 @@
       |-> (fn dtinfo => pair ((map fst dts), SOME dtinfo))
     handle DatatypeAux.Datatype_Empty name' =>
       let
-        val name = Sign.base_name name';
+        val name = NameSpace.base_name name';
         val dname = Name.variant used "Dummy"
       in
         thy
@@ -296,7 +296,7 @@
 
     val thy1' = thy1 |>
       Theory.copy |>
-      Sign.add_types (map (fn s => (Sign.base_name s, ar, NoSyn)) tnames) |>
+      Sign.add_types (map (fn s => (NameSpace.base_name s, ar, NoSyn)) tnames) |>
       fold (fn s => AxClass.axiomatize_arity
         (s, replicate ar HOLogic.typeS, HOLogic.typeS)) tnames |>
         Extraction.add_typeof_eqns_i ty_eqs;
@@ -335,7 +335,7 @@
         let
           val Const (s, T) = head_of (HOLogic.dest_Trueprop
             (Logic.strip_assums_concl rintr));
-          val s' = Sign.base_name s;
+          val s' = NameSpace.base_name s;
           val T' = Logic.unvarifyT T
         in (((Binding.name s', T'), NoSyn), (Const (s, T'), Free (s', T'))) end) rintrs));
     val rlzparams = map (fn Var ((s, _), T) => (s, Logic.unvarifyT T))
@@ -349,7 +349,7 @@
         {quiet_mode = false, verbose = false, kind = Thm.theoremK, alt_name = Binding.empty,
           coind = false, no_elim = false, no_ind = false, skip_mono = false, fork_mono = false}
         rlzpreds rlzparams (map (fn (rintr, intr) =>
-          ((Binding.name (Sign.base_name (name_of_thm intr)), []),
+          ((Binding.name (NameSpace.base_name (name_of_thm intr)), []),
            subst_atomic rlzpreds' (Logic.unvarify rintr)))
              (rintrs ~~ maps snd rss)) [] ||>
       Sign.absolute_path;
--- a/src/HOL/Tools/old_primrec_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/old_primrec_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -212,7 +212,7 @@
                     ((map snd ls) @ [dummyT])
                     (list_comb (Const (rec_name, dummyT),
                                 fs @ map Bound (0 ::(length ls downto 1))))
-    val def_name = Sign.base_name fname ^ "_" ^ Sign.base_name tname ^ "_def";
+    val def_name = NameSpace.base_name fname ^ "_" ^ NameSpace.base_name tname ^ "_def";
     val def_prop =
       singleton (Syntax.check_terms (ProofContext.init thy))
         (Logic.mk_equals (Const (fname, dummyT), rhs));
@@ -269,7 +269,7 @@
             else primrec_err ("functions " ^ commas_quote (map fst nameTs2) ^
               "\nare not mutually recursive");
     val primrec_name =
-      if alt_name = "" then (space_implode "_" (map (Sign.base_name o #1) defs)) else alt_name;
+      if alt_name = "" then (space_implode "_" (map (NameSpace.base_name o #1) defs)) else alt_name;
     val (defs_thms', thy') =
       thy
       |> Sign.add_path primrec_name
--- a/src/HOL/Tools/primrec_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/primrec_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -191,7 +191,7 @@
                     (map snd ls @ [dummyT])
                     (list_comb (Const (rec_name, dummyT),
                                 fs @ map Bound (0 :: (length ls downto 1))))
-    val def_name = Thm.def_name (Sign.base_name fname);
+    val def_name = Thm.def_name (NameSpace.base_name fname);
     val rhs = singleton (Syntax.check_terms ctxt) raw_rhs;
     val SOME var = get_first (fn ((b, _), mx) =>
       if Binding.name_of b = fname then SOME (b, mx) else NONE) fixes;
@@ -247,7 +247,7 @@
     val _ = if gen_eq_set (op =) (names1, names2) then ()
       else primrec_error ("functions " ^ commas_quote names2 ^
         "\nare not mutually recursive");
-    val prefix = space_implode "_" (map (Sign.base_name o #1) defs);
+    val prefix = space_implode "_" (map (NameSpace.base_name o #1) defs);
     val qualify = Binding.qualify false prefix;
     val spec' = (map o apfst)
       (fn (b, attrs) => (qualify b, Code.add_default_eqn_attrib :: attrs)) spec;
--- a/src/HOL/Tools/recdef_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/recdef_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -193,7 +193,7 @@
     val _ = requires_recdef thy;
 
     val name = Sign.intern_const thy raw_name;
-    val bname = Sign.base_name name;
+    val bname = NameSpace.base_name name;
     val _ = writeln ("Defining recursive function " ^ quote name ^ " ...");
 
     val ((eq_names, eqs), raw_eq_atts) = apfst split_list (split_list eq_srcs);
@@ -233,7 +233,7 @@
 fun gen_defer_recdef tfl_fn eval_thms raw_name eqs raw_congs thy =
   let
     val name = Sign.intern_const thy raw_name;
-    val bname = Sign.base_name name;
+    val bname = NameSpace.base_name name;
 
     val _ = requires_recdef thy;
     val _ = writeln ("Deferred recursive function " ^ quote name ^ " ...");
--- a/src/HOL/Tools/record_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/record_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -122,7 +122,7 @@
 (* syntax *)
 
 fun prune n xs = Library.drop (n, xs);
-fun prefix_base s = NameSpace.map_base (fn bname => s ^ bname);
+fun prefix_base s = NameSpace.map_base_name (fn bname => s ^ bname);
 
 val Trueprop = HOLogic.mk_Trueprop;
 fun All xs t = Term.list_all_free (xs, t);
@@ -702,7 +702,7 @@
                      SOME flds
                      => (let
                           val (f::fs) = but_last (map fst flds);
-                          val flds' = Sign.extern_const thy f :: map NameSpace.base fs;
+                          val flds' = Sign.extern_const thy f :: map NameSpace.base_name fs;
                           val (args',more) = split_last args;
                          in (flds'~~args')@field_lst more end
                          handle Library.UnequalLengths => [("",t)])
@@ -804,7 +804,7 @@
                            => (let
                                 val (f :: fs) = but_last flds;
                                 val flds' = apfst (Sign.extern_const thy) f
-                                  :: map (apfst NameSpace.base) fs;
+                                  :: map (apfst NameSpace.base_name) fs;
                                 val (args', more) = split_last args;
                                 val alphavars = map varifyT (but_last alphas);
                                 val subst = fold2 (curry (Sign.typ_match thy))
@@ -1069,7 +1069,7 @@
              val {sel_upd={selectors,updates,...},extfields,...} = RecordsData.get thy;
 
              (*fun mk_abs_var x t = (x, fastype_of t);*)
-             fun sel_name u = NameSpace.base (unsuffix updateN u);
+             fun sel_name u = NameSpace.base_name (unsuffix updateN u);
 
              fun seed s (upd as Const (more,Type(_,[mT,_]))$ k $ r) =
                   if has_field extfields s (domain_type' mT) then upd else seed s r
@@ -1463,7 +1463,7 @@
       in map rewrite_rule [abs_inject, abs_inverse, abs_induct] end;
   in
     thy
-    |> TypecopyPackage.add_typecopy (suffix ext_typeN (Sign.base_name name), alphas) repT NONE
+    |> TypecopyPackage.add_typecopy (suffix ext_typeN (NameSpace.base_name name), alphas) repT NONE
     |-> (fn (name, _) => `(fn thy => get_thms thy name))
   end;
 
@@ -1474,7 +1474,7 @@
 
 fun extension_definition full name fields names alphas zeta moreT more vars thy =
   let
-    val base = Sign.base_name;
+    val base = NameSpace.base_name;
     val fieldTs = (map snd fields);
     val alphas_zeta = alphas@[zeta];
     val alphas_zetaTs = map (fn n => TFree (n, HOLogic.typeS)) alphas_zeta;
@@ -1760,7 +1760,7 @@
     val alphas = map fst args;
     val name = Sign.full_bname thy bname;
     val full = Sign.full_bname_path thy bname;
-    val base = Sign.base_name;
+    val base = NameSpace.base_name;
 
     val (bfields, field_syntax) = split_list (map (fn (x, T, mx) => ((x, T), mx)) raw_fields);
 
--- a/src/HOL/Tools/res_atp.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/res_atp.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -34,8 +34,6 @@
 val convergence = 3.2;    (*Higher numbers allow longer inference chains*)
 val follow_defs = false;  (*Follow definitions. Makes problems bigger.*)
 val include_all = true;
-val include_simpset = false;
-val include_claset = false;
 val include_atpset = true;
   
 (***************************************************************)
@@ -380,7 +378,7 @@
 
 (*Ignore blacklisted basenames*)
 fun add_multi_names ((a, ths), pairs) =
-  if (Sign.base_name a) mem_string ResAxioms.multi_base_blacklist  then pairs
+  if (NameSpace.base_name a) mem_string ResAxioms.multi_base_blacklist  then pairs
   else add_single_names ((a, ths), pairs);
 
 fun is_multi (a, ths) = length ths > 1 orelse String.isSuffix ".axioms" a;
@@ -409,17 +407,11 @@
                      (fn () => ("Including all " ^ Int.toString (length ths) ^ " theorems")))
                   (name_thm_pairs ctxt))
         else
-        let val claset_thms =
-                if include_claset then ResAxioms.claset_rules_of ctxt
-                else []
-            val simpset_thms =
-                if include_simpset then ResAxioms.simpset_rules_of ctxt
-                else []
-            val atpset_thms =
+        let val atpset_thms =
                 if include_atpset then ResAxioms.atpset_rules_of ctxt
                 else []
             val _ = (Output.debug (fn () => "ATP theorems: ");  app display_thm atpset_thms)
-        in  claset_thms @ simpset_thms @ atpset_thms  end
+        in  atpset_thms  end
       val user_rules = filter check_named
                          (map ResAxioms.pairname
                            (if null user_thms then whitelist else user_thms))
--- a/src/HOL/Tools/res_axioms.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/res_axioms.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -15,8 +15,6 @@
   val expand_defs_tac: thm -> tactic
   val combinators: thm -> thm
   val neg_conjecture_clauses: thm -> int -> thm list * (string * typ) list
-  val claset_rules_of: Proof.context -> (string * thm) list   (*FIXME DELETE*)
-  val simpset_rules_of: Proof.context -> (string * thm) list  (*FIXME DELETE*)
   val atpset_rules_of: Proof.context -> (string * thm) list
   val suppress_endtheory: bool ref     (*for emergency use where endtheory causes problems*)
   val setup: theory -> theory
@@ -342,7 +340,7 @@
 
 (*Skolemize a named theorem, with Skolem functions as additional premises.*)
 fun skolem_thm (s, th) =
-  if member (op =) multi_base_blacklist (Sign.base_name s) orelse bad_for_atp th then []
+  if member (op =) multi_base_blacklist (NameSpace.base_name s) orelse bad_for_atp th then []
   else
     let
       val ctxt0 = Variable.thm_context th
@@ -378,24 +376,10 @@
   end;
 
 
-(**** Extract and Clausify theorems from a theory's claset and simpset ****)
+(**** Rules from the context ****)
 
 fun pairname th = (Thm.get_name_hint th, th);
 
-fun rules_of_claset cs =
-  let val {safeIs,safeEs,hazIs,hazEs,...} = rep_cs cs
-      val intros = safeIs @ hazIs
-      val elims  = map Classical.classical_rule (safeEs @ hazEs)
-  in map pairname (intros @ elims) end;
-
-fun rules_of_simpset ss =
-  let val ({rules,...}, _) = rep_ss ss
-      val simps = Net.entries rules
-  in map (fn r => (#name r, #thm r)) simps end;
-
-fun claset_rules_of ctxt = rules_of_claset (local_claset_of ctxt);
-fun simpset_rules_of ctxt = rules_of_simpset (local_simpset_of ctxt);
-
 fun atpset_rules_of ctxt = map pairname (ResAtpset.get ctxt);
 
 
@@ -444,7 +428,7 @@
     val new_facts = (PureThy.facts_of thy, []) |-> Facts.fold_static (fn (name, ths) =>
       if already_seen thy name then I else cons (name, ths));
     val new_thms = (new_facts, []) |-> fold (fn (name, ths) =>
-      if member (op =) multi_base_blacklist (Sign.base_name name) then I
+      if member (op =) multi_base_blacklist (NameSpace.base_name name) then I
       else fold_index (fn (i, th) =>
         if bad_for_atp th orelse is_some (lookup_cache thy th) then I
         else cons (name ^ "_" ^ string_of_int (i + 1), Thm.transfer thy th)) ths);
--- a/src/HOL/Tools/specification_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/Tools/specification_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -24,7 +24,7 @@
                 val ctype = domain_type (type_of P)
                 val cname_full = Sign.intern_const thy cname
                 val cdefname = if thname = ""
-                               then Thm.def_name (Sign.base_name cname)
+                               then Thm.def_name (NameSpace.base_name cname)
                                else thname
                 val def_eq = Logic.mk_equals (Const(cname_full,ctype),
                                               HOLogic.choice_const ctype $  P)
@@ -50,7 +50,7 @@
                         val ctype = domain_type (type_of P)
                         val cname_full = Sign.intern_const thy cname
                         val cdefname = if thname = ""
-                                       then Thm.def_name (Sign.base_name cname)
+                                       then Thm.def_name (NameSpace.base_name cname)
                                        else thname
                         val co = Const(cname_full,ctype)
                         val thy' = Theory.add_finals_i covld [co] thy
@@ -154,7 +154,7 @@
         fun mk_exist (c,prop) =
             let
                 val T = type_of c
-                val cname = Sign.base_name (fst (dest_Const c))
+                val cname = NameSpace.base_name (fst (dest_Const c))
                 val vname = if Syntax.is_identifier cname
                             then cname
                             else "x"
--- a/src/HOL/ex/Quickcheck_Generators.thy	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOL/ex/Quickcheck_Generators.thy	Fri Mar 06 15:31:26 2009 +0100
@@ -138,7 +138,7 @@
     let
       val this_ty = Type (hd tycos, map TFree vs);
       val this_ty' = StateMonad.liftT (term_ty this_ty) @{typ seed};
-      val random_name = NameSpace.base @{const_name random};
+      val random_name = NameSpace.base_name @{const_name random};
       val random'_name = random_name ^ "_" ^ Class.type_name (hd tycos) ^ "'";
       fun random ty = Sign.mk_const thy (@{const_name random}, [ty]);
       val random' = Free (random'_name,
--- a/src/HOLCF/Tools/domain/domain_axioms.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOLCF/Tools/domain/domain_axioms.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -22,7 +22,7 @@
   val dc_rep = %%:(dname^"_rep");
   val x_name'= "x";
   val x_name = idx_name eqs x_name' (n+1);
-  val dnam = Sign.base_name dname;
+  val dnam = NameSpace.base_name dname;
 
   val abs_iso_ax = ("abs_iso", mk_trp(dc_rep`(dc_abs`%x_name') === %:x_name'));
   val rep_iso_ax = ("rep_iso", mk_trp(dc_abs`(dc_rep`%x_name') === %:x_name'));
--- a/src/HOLCF/Tools/domain/domain_extender.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOLCF/Tools/domain/domain_extender.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -103,7 +103,7 @@
 			 (Sign.full_bname thy''' dname, map (Syntax.read_typ_global thy''') vs))
                    o fst) eqs''';
     val cons''' = map snd eqs''';
-    fun thy_type  (dname,tvars)  = (Sign.base_name dname, length tvars, NoSyn);
+    fun thy_type  (dname,tvars)  = (NameSpace.base_name dname, length tvars, NoSyn);
     fun thy_arity (dname,tvars)  = (dname, map (snd o dest_TFree) tvars, pcpoS);
     val thy'' = thy''' |> Sign.add_types     (map thy_type  dtnvs)
 		       |> fold (AxClass.axiomatize_arity o thy_arity) dtnvs;
@@ -114,7 +114,7 @@
     val new_dts = map (fn ((s,Ts),_) => (s, map (fst o dest_TFree) Ts)) eqs';
     fun strip ss = Library.drop (find_index_eq "'" ss +1, ss);
     fun typid (Type  (id,_)) =
-          let val c = hd (Symbol.explode (Sign.base_name id))
+          let val c = hd (Symbol.explode (NameSpace.base_name id))
           in if Symbol.is_letter c then c else "t" end
       | typid (TFree (id,_)   ) = hd (strip (tl (Symbol.explode id)))
       | typid (TVar ((id,_),_)) = hd (tl (Symbol.explode id));
@@ -133,7 +133,7 @@
       ||>> Domain_Theorems.comp_theorems (comp_dnam, eqs);
   in
     theorems_thy
-    |> Sign.add_path (Sign.base_name comp_dnam)
+    |> Sign.add_path (NameSpace.base_name comp_dnam)
     |> (snd o (PureThy.add_thmss [((Binding.name "rews", List.concat rewss @ take_rews), [])]))
     |> Sign.parent_path
   end;
--- a/src/HOLCF/Tools/domain/domain_syntax.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOLCF/Tools/domain/domain_syntax.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -25,7 +25,7 @@
 in
   val dtype  = Type(dname,typevars);
   val dtype2 = foldr1 mk_ssumT (map prod cons');
-  val dnam = Sign.base_name dname;
+  val dnam = NameSpace.base_name dname;
   val const_rep  = (dnam^"_rep" ,              dtype  ->> dtype2, NoSyn);
   val const_abs  = (dnam^"_abs" ,              dtype2 ->> dtype , NoSyn);
   val const_when = (dnam^"_when", List.foldr (op ->>) (dtype ->> freetvar "t") (map when_type cons'), NoSyn);
--- a/src/HOLCF/Tools/domain/domain_theorems.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOLCF/Tools/domain/domain_theorems.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -606,7 +606,7 @@
 
 in
   thy
-    |> Sign.add_path (Sign.base_name dname)
+    |> Sign.add_path (NameSpace.base_name dname)
     |> (snd o (PureThy.add_thmss (map (Thm.no_attributes o apfst Binding.name) [
         ("iso_rews" , iso_rews  ),
         ("exhaust"  , [exhaust] ),
--- a/src/HOLCF/Tools/fixrec_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/HOLCF/Tools/fixrec_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -181,7 +181,7 @@
     val fixpoint = mk_fix (lambda_ctuple lhss (mk_ctuple rhss));
     
     fun one_def (l as Free(n,_)) r =
-          let val b = Sign.base_name n
+          let val b = NameSpace.base_name n
           in ((Binding.name (b^"_def"), []), r) end
       | one_def _ _ = fixrec_err "fixdefs: lhs not of correct form";
     fun defs [] _ = []
@@ -230,7 +230,7 @@
 
 fun taken_names (t : term) : bstring list =
   let
-    fun taken (Const(a,_), bs) = insert (op =) (Sign.base_name a) bs
+    fun taken (Const(a,_), bs) = insert (op =) (NameSpace.base_name a) bs
       | taken (Free(a,_) , bs) = insert (op =) a bs
       | taken (f $ u     , bs) = taken (f, taken (u, bs))
       | taken (Abs(a,_,t), bs) = taken (t, insert (op =) a bs)
--- a/src/Pure/General/binding.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/General/binding.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -10,17 +10,18 @@
 signature BINDING =
 sig
   type binding
-  val dest: binding -> (string * bool) list * (string * bool) list * bstring
+  val dest: binding -> (string * bool) list * bstring
   val verbose: bool ref
   val str_of: binding -> string
   val make: bstring * Position.T -> binding
+  val pos_of: binding -> Position.T
   val name: bstring -> binding
-  val pos_of: binding -> Position.T
   val name_of: binding -> string
   val map_name: (bstring -> bstring) -> binding -> binding
   val empty: binding
   val is_empty: binding -> bool
   val qualify: bool -> string -> binding -> binding
+  val prefix_of: binding -> (string * bool) list
   val map_prefix: ((string * bool) list -> (string * bool) list) -> binding -> binding
   val add_prefix: bool -> string -> binding -> binding
 end;
@@ -32,13 +33,11 @@
 
 (* datatype *)
 
-type component = string * bool;   (*name with mandatory flag*)
-
 datatype binding = Binding of
- {prefix: component list,         (*system prefix*)
-  qualifier: component list,      (*user qualifier*)
-  name: bstring,                  (*base name*)
-  pos: Position.T};               (*source position*)
+ {prefix: (string * bool) list,     (*system prefix*)
+  qualifier: (string * bool) list,  (*user qualifier*)
+  name: bstring,                    (*base name*)
+  pos: Position.T};                 (*source position*)
 
 fun make_binding (prefix, qualifier, name, pos) =
   Binding {prefix = prefix, qualifier = qualifier, name = name, pos = pos};
@@ -46,7 +45,7 @@
 fun map_binding f (Binding {prefix, qualifier, name, pos}) =
   make_binding (f (prefix, qualifier, name, pos));
 
-fun dest (Binding {prefix, qualifier, name, ...}) = (prefix, qualifier, name);
+fun dest (Binding {prefix, qualifier, name, ...}) = (prefix @ qualifier, name);
 
 
 (* diagnostic output *)
@@ -92,6 +91,8 @@
 
 (* system prefix *)
 
+fun prefix_of (Binding {prefix, ...}) = prefix;
+
 fun map_prefix f = map_binding (fn (prefix, qualifier, name, pos) =>
   (f prefix, qualifier, name, pos));
 
--- a/src/Pure/General/graph.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/General/graph.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -21,7 +21,6 @@
   val maximals: 'a T -> key list
   val subgraph: (key -> bool) -> 'a T -> 'a T
   val map_nodes: ('a -> 'b) -> 'a T -> 'b T
-  val fold_map_nodes: (key * 'a -> 'b -> 'c * 'b) -> 'a T -> 'b -> 'c T * 'b
   val get_node: 'a T -> key -> 'a                                     (*exception UNDEF*)
   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
   val map_node_yield: key -> ('a -> 'b * 'a) -> 'a T -> 'b * 'a T
@@ -116,9 +115,6 @@
 
 fun map_nodes f (Graph tab) = Graph (Table.map (fn (i, ps) => (f i, ps)) tab);
 
-fun fold_map_nodes f (Graph tab) =
-  apfst Graph o Table.fold_map (fn (k, (i, ps)) => f (k, i) #> apfst (rpair ps)) tab;
-
 fun get_node G = #1 o get_entry G;
 
 fun map_node x f = map_entry x (fn (i, ps) => (f i, ps));
--- a/src/Pure/General/name_space.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/General/name_space.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -25,9 +25,9 @@
   val explode: string -> string list
   val append: string -> string -> string
   val qualified: string -> string -> string
-  val base: string -> string
+  val base_name: string -> string
   val qualifier: string -> string
-  val map_base: (string -> string) -> string -> string
+  val map_base_name: (string -> string) -> string -> string
   type T
   val empty: T
   val intern: T -> xstring -> string
@@ -78,14 +78,14 @@
   if path = "" orelse name = "" then name
   else path ^ separator ^ name;
 
-fun base "" = ""
-  | base name = List.last (explode_name name);
+fun base_name "" = ""
+  | base_name name = List.last (explode_name name);
 
 fun qualifier "" = ""
   | qualifier name = implode_name (#1 (split_last (explode_name name)));
 
-fun map_base _ "" = ""
-  | map_base f name =
+fun map_base_name _ "" = ""
+  | map_base_name f name =
       let val names = explode_name name
       in implode_name (nth_map (length names - 1) f names) end;
 
@@ -123,7 +123,7 @@
 datatype T =
   NameSpace of
     (string list * string list) Symtab.table *   (*internals, hidden internals*)
-    string list Symtab.table;                    (*externals*)
+    xstring list Symtab.table;                   (*externals*)
 
 val empty = NameSpace (Symtab.empty, Symtab.empty);
 
@@ -153,15 +153,15 @@
 
 fun extern_flags {long_names, short_names, unique_names} space name =
   let
-    fun valid unique xname =
-      let val (name', uniq) = lookup space xname
-      in name = name' andalso (uniq orelse not unique) end;
+    fun valid require_unique xname =
+      let val (name', is_unique) = lookup space xname
+      in name = name' andalso (not require_unique orelse is_unique) end;
 
     fun ext [] = if valid false name then name else hidden name
       | ext (nm :: nms) = if valid unique_names nm then nm else ext nms;
   in
     if long_names then name
-    else if short_names then base name
+    else if short_names then base_name name
     else ext (get_accesses space name)
   end;
 
@@ -204,7 +204,7 @@
     let val names = valid_accesses space name in
       space
       |> add_name' name name
-      |> fold (del_name name) (if fully then names else names inter_string [base name])
+      |> fold (del_name name) (if fully then names else names inter_string [base_name name])
       |> fold (del_name_extra name) (get_accesses space name)
     end;
 
@@ -278,8 +278,8 @@
 
 fun full_name naming binding =
   let
-    val (prefix, qualifier, bname) = Binding.dest binding;
-    val naming' = apply_prefix (prefix @ qualifier) naming;
+    val (prfx, bname) = Binding.dest binding;
+    val naming' = apply_prefix prfx naming;
   in full naming' bname end;
 
 
@@ -287,8 +287,8 @@
 
 fun declare naming binding space =
   let
-    val (prefix, qualifier, bname) = Binding.dest binding;
-    val naming' = apply_prefix (prefix @ qualifier) naming;
+    val (prfx, bname) = Binding.dest binding;
+    val naming' = apply_prefix prfx naming;
     val name = full naming' bname;
     val names = explode_name name;
 
--- a/src/Pure/General/table.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/General/table.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -24,7 +24,6 @@
   val map': (key -> 'a -> 'b) -> 'a table -> 'b table
   val fold: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a
   val fold_rev: (key * 'b -> 'a -> 'a) -> 'b table -> 'a -> 'a
-  val fold_map: (key * 'b -> 'a -> 'c * 'a) -> 'b table -> 'a -> 'c table * 'a
   val dest: 'a table -> (key * 'a) list
   val keys: 'a table -> key list
   val exists: (key * 'a -> bool) -> 'a table -> bool
@@ -112,25 +111,6 @@
           fold left (f p1 (fold mid (f p2 (fold right x))));
   in fold end;
 
-fun fold_map_table f =
-  let
-    fun fold_map Empty s = (Empty, s)
-      | fold_map (Branch2 (left, p as (k, x), right)) s =
-          s
-          |> fold_map left
-          ||>> f p
-          ||>> fold_map right
-          |-> (fn ((l, e), r) => pair (Branch2 (l, (k, e), r)))
-      | fold_map (Branch3 (left, p1 as (k1, x1), mid, p2 as (k2, x2), right)) s =
-          s
-          |> fold_map left
-          ||>> f p1
-          ||>> fold_map mid
-          ||>> f p2
-          ||>> fold_map right
-          |-> (fn ((((l, e1), m), e2), r) => pair (Branch3 (l, (k1, e1), m, (k2, e2), r)))
-  in fold_map end;
-
 fun dest tab = fold_rev_table cons tab [];
 fun keys tab = fold_rev_table (cons o #1) tab [];
 
@@ -366,7 +346,7 @@
 
 fun join f (table1, table2) =
   let fun add (key, y) tab = modify key (fn NONE => y | SOME x => f key (x, y)) tab;
-  in fold_table add table2 table1 end;
+  in if pointer_eq (table1, table2) then table1 else fold_table add table2 table1 end;
 
 fun merge eq = join (fn key => fn xy => if eq xy then raise SAME else raise DUP key);
 
@@ -398,7 +378,6 @@
 val map' = map_table;
 val fold = fold_table;
 val fold_rev = fold_rev_table;
-val fold_map = fold_map_table;
 
 end;
 
--- a/src/Pure/Isar/calculation.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/calculation.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -114,7 +114,7 @@
 
 fun print_calculation false _ _ = ()
   | print_calculation true ctxt calc = Pretty.writeln
-      (ProofContext.pretty_fact ctxt (ProofContext.full_bname ctxt calculationN, calc));
+      (ProofContext.pretty_fact ctxt (ProofContext.full_name ctxt (Binding.name calculationN), calc));
 
 
 (* also and finally *)
--- a/src/Pure/Isar/class_target.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/class_target.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -300,7 +300,7 @@
   map (fn (c, (_, (ty, t))) => (t, Const (c, ty))) o these_operations thy;
 
 fun redeclare_const thy c =
-  let val b = Sign.base_name c
+  let val b = NameSpace.base_name c
   in Sign.intern_const thy b = c ? Variable.declare_const (b, c) end;
 
 fun synchronize_class_syntax sort base_sort ctxt =
@@ -358,7 +358,7 @@
 
 (* class target *)
 
-val class_prefix = Logic.const_of_class o Sign.base_name;
+val class_prefix = Logic.const_of_class o NameSpace.base_name;
 
 fun declare class pos ((c, mx), dict) thy =
   let
@@ -475,7 +475,7 @@
 
 fun type_name "*" = "prod"
   | type_name "+" = "sum"
-  | type_name s = sanatize_name (NameSpace.base s);
+  | type_name s = sanatize_name (NameSpace.base_name s);
 
 fun resort_terms pp algebra consts constraints ts =
   let
--- a/src/Pure/Isar/element.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/element.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -202,7 +202,7 @@
   let val head =
     if Thm.has_name_hint th then
       Pretty.block [Pretty.command kind,
-        Pretty.brk 1, Pretty.str (Sign.base_name (Thm.get_name_hint th) ^ ":")]
+        Pretty.brk 1, Pretty.str (NameSpace.base_name (Thm.get_name_hint th) ^ ":")]
     else Pretty.command kind
   in Pretty.block (Pretty.fbreaks (head :: prts)) end;
 
--- a/src/Pure/Isar/isar_cmd.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/isar_cmd.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -150,10 +150,12 @@
     val oracle = SymbolPos.content (SymbolPos.explode (oracle_txt, pos));
     val txt =
       "local\n\
-      \  val name = " ^ quote name ^ ";\n\
+      \  val name = " ^ ML_Syntax.print_string name ^ ";\n\
+      \  val pos = " ^ ML_Syntax.print_position pos ^ ";\n\
+      \  val binding = Binding.make (name, pos);\n\
       \  val oracle = " ^ oracle ^ ";\n\
       \in\n\
-      \  val " ^ name ^ " = snd (Context.>>> (Context.map_theory_result (Thm.add_oracle (name, oracle))));\n\
+      \  val " ^ name ^ " = snd (Context.>>> (Context.map_theory_result (Thm.add_oracle (binding, oracle))));\n\
       \end;\n";
   in Context.theory_map (ML_Context.exec (fn () => ML_Context.eval false pos txt)) end;
 
--- a/src/Pure/Isar/proof.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/proof.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -1006,7 +1006,7 @@
     fun after_local' [[th]] = put_thms false (AutoBind.thisN, SOME [th]);
     fun after_global' [[th]] = ProofContext.put_thms false (AutoBind.thisN, SOME [th]);
     val after_qed' = (after_local', after_global');
-    val this_name = ProofContext.full_bname goal_ctxt AutoBind.thisN;
+    val this_name = ProofContext.full_name goal_ctxt (Binding.name AutoBind.thisN);
 
     val result_ctxt =
       state
--- a/src/Pure/Isar/proof_context.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/proof_context.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -23,7 +23,6 @@
   val set_stmt: bool -> Proof.context -> Proof.context
   val naming_of: Proof.context -> NameSpace.naming
   val full_name: Proof.context -> binding -> string
-  val full_bname: Proof.context -> bstring -> string
   val consts_of: Proof.context -> Consts.T
   val const_syntax_name: Proof.context -> string -> string
   val the_const_constraint: Proof.context -> string -> typ
@@ -243,9 +242,7 @@
   map_mode (fn (_, pattern, schematic, abbrev) => (stmt, pattern, schematic, abbrev));
 
 val naming_of = #naming o rep_context;
-
 val full_name = NameSpace.full_name o naming_of;
-fun full_bname thy = NameSpace.full_name (naming_of thy) o Binding.name;
 
 val syntax_of = #syntax o rep_context;
 val syn_of = LocalSyntax.syn_of o syntax_of;
@@ -266,11 +263,9 @@
 
 fun transfer_syntax thy =
   map_syntax (LocalSyntax.rebuild thy) #>
-  map_consts (fn consts as (local_consts, global_consts) =>
-    let val thy_consts = Sign.consts_of thy in
-      if Consts.eq_consts (thy_consts, global_consts) then consts
-      else (Consts.merge (local_consts, thy_consts), thy_consts)
-    end);
+  map_consts (fn (local_consts, _) =>
+    let val thy_consts = Sign.consts_of thy
+    in (Consts.merge (local_consts, thy_consts), thy_consts) end);
 
 fun transfer thy = Context.transfer_proof thy #> transfer_syntax thy;
 
--- a/src/Pure/Isar/proof_display.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/proof_display.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -75,7 +75,7 @@
 
 fun pretty_fact_name (kind, "") = Pretty.str kind
   | pretty_fact_name (kind, name) = Pretty.block [Pretty.str kind, Pretty.brk 1,
-      Pretty.str (NameSpace.base name), Pretty.str ":"];
+      Pretty.str (NameSpace.base_name name), Pretty.str ":"];
 
 fun pretty_facts ctxt =
   flat o (separate [Pretty.fbrk, Pretty.str "and "]) o
--- a/src/Pure/Isar/skip_proof.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/skip_proof.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -20,7 +20,7 @@
 (* oracle setup *)
 
 val (_, skip_proof) = Context.>>> (Context.map_theory_result
-  (Thm.add_oracle ("skip_proof", fn (thy, prop) =>
+  (Thm.add_oracle (Binding.name "skip_proof", fn (thy, prop) =>
     if ! quick_and_dirty then Thm.cterm_of thy prop
     else error "Proof may be skipped in quick_and_dirty mode only!")));
 
--- a/src/Pure/Isar/theory_target.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Isar/theory_target.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -188,7 +188,7 @@
     val arg = (b', Term.close_schematic_term rhs');
     val similar_body = Type.similar_types (rhs, rhs');
     (* FIXME workaround based on educated guess *)
-    val (prefix', _, _) = Binding.dest b';
+    val prefix' = Binding.prefix_of b';
     val class_global = Binding.name_of b = Binding.name_of b'
       andalso not (null prefix')
       andalso (fst o snd o split_last) prefix' = Class_Target.class_prefix target;
@@ -330,7 +330,7 @@
 
 fun init_lthy (ta as Target {target, instantiation, overloading, ...}) =
   Data.put ta #>
-  LocalTheory.init (NameSpace.base target)
+  LocalTheory.init (NameSpace.base_name target)
    {pretty = pretty ta,
     abbrev = abbrev ta,
     define = define ta,
--- a/src/Pure/ML/ml_antiquote.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/ML/ml_antiquote.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -110,7 +110,7 @@
 
 fun type_ syn = (Args.context -- Scan.lift Args.name_source >> (fn (ctxt, c) =>
     #1 (Term.dest_Type (ProofContext.read_tyname ctxt c))
-    |> syn ? Sign.base_name
+    |> syn ? NameSpace.base_name
     |> ML_Syntax.print_string));
 
 val _ = inline "type_name" (type_ false);
--- a/src/Pure/ProofGeneral/proof_general_emacs.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/ProofGeneral/proof_general_emacs.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -39,7 +39,7 @@
           then XML.output_markup (name, props)
           else Markup.no_output;
         val (bg2, en2) =
-          if (case ts of [XML.Text _] => false | _ => true) then Markup.no_output
+          if null ts then Markup.no_output
           else if name = Markup.stateN then (special "O" ^ "\n", "\n" ^ special "P")
           else if name = Markup.sendbackN then (special "W", special "X")
           else if name = Markup.hiliteN then (special "0", special "1")
--- a/src/Pure/Thy/thm_deps.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/Thy/thm_deps.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -33,7 +33,7 @@
                | _ => ["global"]);
             val parents = filter_out (fn s => s = "") (map (#1 o #2) thms');
             val entry =
-              {name = Sign.base_name name,
+              {name = NameSpace.base_name name,
                ID = name,
                dir = space_implode "/" (session @ prefix),
                unfold = false,
--- a/src/Pure/axclass.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/axclass.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -158,7 +158,7 @@
 
 (* maintain instances *)
 
-fun instance_name (a, c) = NameSpace.base c ^ "_" ^ NameSpace.base a;
+fun instance_name (a, c) = NameSpace.base_name c ^ "_" ^ NameSpace.base_name a;
 
 val get_instances = #1 o #2 o AxClassData.get;
 val map_instances = AxClassData.map o apsnd o apfst;
@@ -367,7 +367,7 @@
       | NONE => error ("Illegal type for instantiation of class parameter: "
         ^ quote (c ^ " :: " ^ Syntax.string_of_typ_global thy T));
     val name_inst = instance_name (tyco, class) ^ "_inst";
-    val c' = NameSpace.base c ^ "_" ^ NameSpace.base tyco;
+    val c' = NameSpace.base_name c ^ "_" ^ NameSpace.base_name tyco;
     val T' = Type.strip_sorts T;
   in
     thy
@@ -391,7 +391,7 @@
     val (c', eq) = get_inst_param thy (c, tyco);
     val prop = Logic.mk_equals (Const (c', T), t);
     val name' = Thm.def_name_optional
-      (NameSpace.base c ^ "_" ^ NameSpace.base tyco) name;
+      (NameSpace.base_name c ^ "_" ^ NameSpace.base_name tyco) name;
   in
     thy
     |> Thm.add_def false false (Binding.name name', prop)
--- a/src/Pure/codegen.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/codegen.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -938,7 +938,7 @@
   in e () end;
 
 val (_, evaluation_conv) = Context.>>> (Context.map_theory_result
-  (Thm.add_oracle ("evaluation", fn ct =>
+  (Thm.add_oracle (Binding.name "evaluation", fn ct =>
     let
       val thy = Thm.theory_of_cterm ct;
       val t = Thm.term_of ct;
--- a/src/Pure/consts.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/consts.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -8,7 +8,6 @@
 signature CONSTS =
 sig
   type T
-  val eq_consts: T * T -> bool
   val abbrevs_of: T -> string list -> (term * term) list
   val dest: T ->
    {constants: (typ * term option) NameSpace.table,
@@ -52,23 +51,21 @@
 datatype T = Consts of
  {decls: ((decl * abbrev option) * serial) NameSpace.table,
   constraints: typ Symtab.table,
-  rev_abbrevs: (term * term) list Symtab.table} * stamp;
-
-fun eq_consts (Consts (_, s1), Consts (_, s2)) = s1 = s2;
+  rev_abbrevs: (term * term) list Symtab.table};
 
 fun make_consts (decls, constraints, rev_abbrevs) =
-  Consts ({decls = decls, constraints = constraints, rev_abbrevs = rev_abbrevs}, stamp ());
+  Consts {decls = decls, constraints = constraints, rev_abbrevs = rev_abbrevs};
 
-fun map_consts f (Consts ({decls, constraints, rev_abbrevs}, _)) =
+fun map_consts f (Consts {decls, constraints, rev_abbrevs}) =
   make_consts (f (decls, constraints, rev_abbrevs));
 
-fun abbrevs_of (Consts ({rev_abbrevs, ...}, _)) modes =
+fun abbrevs_of (Consts {rev_abbrevs, ...}) modes =
   maps (Symtab.lookup_list rev_abbrevs) modes;
 
 
 (* dest consts *)
 
-fun dest (Consts ({decls = (space, decls), constraints, ...}, _)) =
+fun dest (Consts {decls = (space, decls), constraints, ...}) =
  {constants = (space,
     Symtab.fold (fn (c, (({T, ...}, abbr), _)) =>
       Symtab.update (c, (T, Option.map #rhs abbr))) decls Symtab.empty),
@@ -77,7 +74,7 @@
 
 (* lookup consts *)
 
-fun the_const (Consts ({decls = (_, tab), ...}, _)) c =
+fun the_const (Consts {decls = (_, tab), ...}) c =
   (case Symtab.lookup tab c of
     SOME (decl, _) => decl
   | NONE => raise TYPE ("Unknown constant: " ^ quote c, [], []));
@@ -99,7 +96,7 @@
 
 val is_monomorphic = null oo type_arguments;
 
-fun the_constraint (consts as Consts ({constraints, ...}, _)) c =
+fun the_constraint (consts as Consts {constraints, ...}) c =
   (case Symtab.lookup constraints c of
     SOME T => T
   | NONE => type_scheme consts c);
@@ -107,7 +104,7 @@
 
 (* name space and syntax *)
 
-fun space_of (Consts ({decls = (space, _), ...}, _)) = space;
+fun space_of (Consts {decls = (space, _), ...}) = space;
 
 val intern = NameSpace.intern o space_of;
 val extern = NameSpace.extern o space_of;
@@ -120,7 +117,7 @@
 fun syntax consts (c, mx) =
   let
     val ({T, authentic, ...}, _) = the_const consts c handle TYPE (msg, _, _) => error msg;
-    val c' = if authentic then Syntax.constN ^ c else NameSpace.base c;
+    val c' = if authentic then Syntax.constN ^ c else NameSpace.base_name c;
   in (c', T, mx) end;
 
 fun syntax_name consts c = #1 (syntax consts (c, NoSyn));
@@ -267,17 +264,16 @@
     val expand_term = certify pp tsig true consts;
     val force_expand = mode = PrintMode.internal;
 
+    val _ = Term.exists_subterm Term.is_Var raw_rhs andalso
+      error ("Illegal schematic variables on rhs of abbreviation: " ^ Binding.str_of b);
+
     val rhs = raw_rhs
       |> Term.map_types (Type.cert_typ tsig)
-      |> cert_term;
+      |> cert_term
+      |> Term.close_schematic_term;
     val normal_rhs = expand_term rhs;
     val T = Term.fastype_of rhs;
     val lhs = Const (NameSpace.full_name naming b, T);
-
-    fun err msg = (warning (* FIXME should be error *) (msg ^ " on rhs of abbreviation:\n" ^
-      Pretty.string_of_term pp (Logic.mk_equals (lhs, rhs))); true);
-    val _ = Term.exists_subterm Term.is_Var rhs andalso err "Illegal schematic variables";
-    val _ = null (Term.hidden_polymorphism rhs) orelse err "Extra type variables";
   in
     consts |> map_consts (fn (decls, constraints, rev_abbrevs) =>
       let
@@ -307,8 +303,8 @@
 val empty = make_consts (NameSpace.empty_table, Symtab.empty, Symtab.empty);
 
 fun merge
-   (Consts ({decls = decls1, constraints = constraints1, rev_abbrevs = rev_abbrevs1}, _),
-    Consts ({decls = decls2, constraints = constraints2, rev_abbrevs = rev_abbrevs2}, _)) =
+   (Consts {decls = decls1, constraints = constraints1, rev_abbrevs = rev_abbrevs1},
+    Consts {decls = decls2, constraints = constraints2, rev_abbrevs = rev_abbrevs2}) =
   let
     val decls' = NameSpace.merge_tables (eq_snd (op =)) (decls1, decls2)
       handle Symtab.DUP c => err_dup_const c;
--- a/src/Pure/logic.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/logic.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -230,7 +230,7 @@
 (* class relations *)
 
 fun name_classrel (c1, c2) =
-  NameSpace.base c1 ^ "_" ^ NameSpace.base c2;
+  NameSpace.base_name c1 ^ "_" ^ NameSpace.base_name c2;
 
 fun mk_classrel (c1, c2) = mk_inclass (Term.aT [c1], c2);
 
@@ -243,8 +243,8 @@
 (* type arities *)
 
 fun name_arities (t, _, S) =
-  let val b = NameSpace.base t
-  in S |> map (fn c => NameSpace.base c ^ "_" ^ b) end;
+  let val b = NameSpace.base_name t
+  in S |> map (fn c => NameSpace.base_name c ^ "_" ^ b) end;
 
 fun name_arity (t, dom, c) = hd (name_arities (t, dom, [c]));
 
--- a/src/Pure/old_term.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/old_term.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -39,7 +39,7 @@
 
 (*Accumulates the names in the term, suppressing duplicates.
   Includes Frees and Consts.  For choosing unambiguous bound var names.*)
-fun add_term_names (Const(a,_), bs) = insert (op =) (NameSpace.base a) bs
+fun add_term_names (Const(a,_), bs) = insert (op =) (NameSpace.base_name a) bs
   | add_term_names (Free(a,_), bs) = insert (op =) a bs
   | add_term_names (f$u, bs) = add_term_names (f, add_term_names(u, bs))
   | add_term_names (Abs(_,_,t), bs) = add_term_names(t,bs)
--- a/src/Pure/primitive_defs.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/primitive_defs.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -81,7 +81,7 @@
 fun mk_defpair (lhs, rhs) =
   (case Term.head_of lhs of
     Const (name, _) =>
-      (NameSpace.base name ^ "_def", Logic.mk_equals (lhs, rhs))
+      (NameSpace.base_name name ^ "_def", Logic.mk_equals (lhs, rhs))
   | _ => raise TERM ("Malformed definition: head of lhs not a constant", [lhs, rhs]));
 
 end;
--- a/src/Pure/sign.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/sign.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -14,7 +14,6 @@
     consts: Consts.T}
   val naming_of: theory -> NameSpace.naming
   val full_name: theory -> binding -> string
-  val base_name: string -> bstring
   val full_bname: theory -> bstring -> string
   val full_bname_path: theory -> string -> bstring -> string
   val syn_of: theory -> Syntax.syntax
@@ -185,7 +184,6 @@
 (* naming *)
 
 val naming_of = #naming o rep_sg;
-val base_name = NameSpace.base;
 
 val full_name = NameSpace.full_name o naming_of;
 fun full_bname thy = NameSpace.full_name (naming_of thy) o Binding.name;
--- a/src/Pure/term.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/term.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -490,7 +490,7 @@
 
 fun declare_term_names tm =
   fold_aterms
-    (fn Const (a, _) => Name.declare (NameSpace.base a)
+    (fn Const (a, _) => Name.declare (NameSpace.base_name a)
       | Free (a, _) => Name.declare a
       | _ => I) tm #>
   fold_types declare_typ_names tm;
@@ -721,7 +721,7 @@
 fun lambda v t =
   let val x =
     (case v of
-      Const (x, _) => NameSpace.base x
+      Const (x, _) => NameSpace.base_name x
     | Free (x, _) => x
     | Var ((x, _), _) => x
     | _ => Name.uu)
@@ -805,8 +805,8 @@
 fun close_schematic_term t =
   let
     val extra_types = map (fn v => Const ("TYPE", itselfT (TVar v))) (hidden_polymorphism t);
-    val extra_terms = map Var (rev (add_vars t []));
-  in fold_rev lambda (extra_types @ extra_terms) t end;
+    val extra_terms = map Var (add_vars t []);
+  in fold lambda (extra_terms @ extra_types) t end;
 
 
 
--- a/src/Pure/thm.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Pure/thm.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -151,7 +151,7 @@
   val proof_of: thm -> proof
   val join_proof: thm -> unit
   val extern_oracles: theory -> xstring list
-  val add_oracle: bstring * ('a -> cterm) -> theory -> (string * ('a -> thm)) * theory
+  val add_oracle: binding * ('a -> cterm) -> theory -> (string * ('a -> thm)) * theory
 end;
 
 structure Thm:> THM =
@@ -1698,7 +1698,7 @@
 
 structure Oracles = TheoryDataFun
 (
-  type T = stamp NameSpace.table;
+  type T = serial NameSpace.table;
   val empty = NameSpace.empty_table;
   val copy = I;
   val extend = I;
@@ -1708,13 +1708,12 @@
 
 val extern_oracles = map #1 o NameSpace.extern_table o Oracles.get;
 
-fun add_oracle (bname, oracle) thy =
+fun add_oracle (b, oracle) thy =
   let
     val naming = Sign.naming_of thy;
-    val name = NameSpace.full_name naming (Binding.name bname);
-    val thy' = thy |> Oracles.map (fn (space, tab) =>
-      (NameSpace.declare naming (Binding.name bname) space |> snd,
-        Symtab.update_new (name, stamp ()) tab handle Symtab.DUP dup => err_dup_ora dup));
+    val (name, tab') = NameSpace.bind naming (b, serial ()) (Oracles.get thy)
+      handle Symtab.DUP _ => err_dup_ora (Binding.str_of b);
+    val thy' = Oracles.put tab' thy;
   in ((name, invoke_oracle (Theory.check_thy thy') name oracle), thy') end;
 
 end;
--- a/src/Tools/Compute_Oracle/compute.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Tools/Compute_Oracle/compute.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -371,7 +371,7 @@
 fun merge_shyps shyps1 shyps2 = Sorttab.keys (add_shyps shyps2 (add_shyps shyps1 Sorttab.empty))
 
 val (_, export_oracle) = Context.>>> (Context.map_theory_result
-  (Thm.add_oracle ("compute", fn (thy, hyps, shyps, prop) =>
+  (Thm.add_oracle (Binding.name "compute", fn (thy, hyps, shyps, prop) =>
     let
         val shyptab = add_shyps shyps Sorttab.empty
         fun delete s shyptab = Sorttab.delete s shyptab handle Sorttab.UNDEF _ => shyptab
--- a/src/Tools/code/code_haskell.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Tools/code/code_haskell.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -34,7 +34,7 @@
 fun pr_haskell_stmt naming labelled_name syntax_class syntax_tyco syntax_const
     init_syms deresolve is_cons contr_classparam_typs deriving_show =
   let
-    val deresolve_base = NameSpace.base o deresolve;
+    val deresolve_base = NameSpace.base_name o deresolve;
     fun class_name class = case syntax_class class
      of NONE => deresolve class
       | SOME class => class;
@@ -143,7 +143,7 @@
                 @ str "="
                 :: str "error"
                 @@ (str o (fn s => s ^ ";") o ML_Syntax.print_string
-                    o NameSpace.base o NameSpace.qualifier) name
+                    o NameSpace.base_name o NameSpace.qualifier) name
               )
             ]
           end
@@ -155,7 +155,7 @@
               let
                 val consts = map_filter
                   (fn c => if (is_some o syntax_const) c
-                    then NONE else (SOME o NameSpace.base o deresolve) c)
+                    then NONE else (SOME o NameSpace.base_name o deresolve) c)
                     ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
                 val vars = init_syms
                   |> Code_Name.intro_vars consts
@@ -255,7 +255,7 @@
                   let
                     val (c_inst_name, (_, tys)) = c_inst;
                     val const = if (is_some o syntax_const) c_inst_name
-                      then NONE else (SOME o NameSpace.base o deresolve) c_inst_name;
+                      then NONE else (SOME o NameSpace.base_name o deresolve) c_inst_name;
                     val proto_rhs = Code_Thingol.eta_expand k (c_inst, []);
                     val (vs, rhs) = unfold_abs_pure proto_rhs;
                     val vars = init_syms
@@ -360,7 +360,7 @@
     val reserved_names = Code_Name.make_vars reserved_names;
     fun pr_stmt qualified = pr_haskell_stmt naming labelled_name
       syntax_class syntax_tyco syntax_const reserved_names
-      (if qualified then deresolver else NameSpace.base o deresolver)
+      (if qualified then deresolver else NameSpace.base_name o deresolver)
       is_cons contr_classparam_typs
       (if string_classes then deriving_show else K false);
     fun pr_module name content =
@@ -379,7 +379,7 @@
           |> map_filter (try deresolver);
         val qualified = is_none module_name andalso
           map deresolver stmt_names @ deps'
-          |> map NameSpace.base
+          |> map NameSpace.base_name
           |> has_duplicates (op =);
         val imports = deps'
           |> map NameSpace.qualifier
--- a/src/Tools/code/code_ml.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Tools/code/code_ml.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -47,7 +47,7 @@
   let
     val pr_label_classrel = translate_string (fn "." => "__" | c => c)
       o NameSpace.qualifier;
-    val pr_label_classparam = NameSpace.base o NameSpace.qualifier;
+    val pr_label_classparam = NameSpace.base_name o NameSpace.qualifier;
     fun pr_dicts fxy ds =
       let
         fun pr_dictvar (v, (_, 1)) = Code_Name.first_upper v ^ "_"
@@ -163,7 +163,7 @@
     fun pr_stmt (MLExc (name, n)) =
           let
             val exc_str =
-              (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
+              (ML_Syntax.print_string o NameSpace.base_name o NameSpace.qualifier) name;
           in
             concat (
               str (if n = 0 then "val" else "fun")
@@ -179,7 +179,7 @@
           let
             val consts = map_filter
               (fn c => if (is_some o syntax_const) c
-                then NONE else (SOME o NameSpace.base o deresolve) c)
+                then NONE else (SOME o NameSpace.base_name o deresolve) c)
                 (Code_Thingol.fold_constnames (insert (op =)) t []);
             val vars = reserved_names
               |> Code_Name.intro_vars consts;
@@ -204,7 +204,7 @@
                   let
                     val consts = map_filter
                       (fn c => if (is_some o syntax_const) c
-                        then NONE else (SOME o NameSpace.base o deresolve) c)
+                        then NONE else (SOME o NameSpace.base_name o deresolve) c)
                         ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
                     val vars = reserved_names
                       |> Code_Name.intro_vars consts
@@ -473,7 +473,7 @@
     fun pr_stmt (MLExc (name, n)) =
           let
             val exc_str =
-              (ML_Syntax.print_string o NameSpace.base o NameSpace.qualifier) name;
+              (ML_Syntax.print_string o NameSpace.base_name o NameSpace.qualifier) name;
           in
             concat (
               str "let"
@@ -488,7 +488,7 @@
           let
             val consts = map_filter
               (fn c => if (is_some o syntax_const) c
-                then NONE else (SOME o NameSpace.base o deresolve) c)
+                then NONE else (SOME o NameSpace.base_name o deresolve) c)
                 (Code_Thingol.fold_constnames (insert (op =)) t []);
             val vars = reserved_names
               |> Code_Name.intro_vars consts;
@@ -508,7 +508,7 @@
               let
                 val consts = map_filter
                   (fn c => if (is_some o syntax_const) c
-                    then NONE else (SOME o NameSpace.base o deresolve) c)
+                    then NONE else (SOME o NameSpace.base_name o deresolve) c)
                     ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
                 val vars = reserved_names
                   |> Code_Name.intro_vars consts
@@ -524,7 +524,7 @@
                   let
                     val consts = map_filter
                       (fn c => if (is_some o syntax_const) c
-                        then NONE else (SOME o NameSpace.base o deresolve) c)
+                        then NONE else (SOME o NameSpace.base_name o deresolve) c)
                         ((fold o Code_Thingol.fold_constnames) (insert (op =)) (t :: ts) []);
                     val vars = reserved_names
                       |> Code_Name.intro_vars consts
@@ -552,7 +552,7 @@
                   let
                     val consts = map_filter
                       (fn c => if (is_some o syntax_const) c
-                        then NONE else (SOME o NameSpace.base o deresolve) c)
+                        then NONE else (SOME o NameSpace.base_name o deresolve) c)
                         ((fold o Code_Thingol.fold_constnames)
                           (insert (op =)) (map (snd o fst) eqs) []);
                     val vars = reserved_names
--- a/src/Tools/code/code_thingol.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Tools/code/code_thingol.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -246,15 +246,15 @@
     in NameSpace.append prefix base end;
 in
 
-fun namify_class thy = namify thy NameSpace.base thyname_of_class;
+fun namify_class thy = namify thy NameSpace.base_name thyname_of_class;
 fun namify_classrel thy = namify thy (fn (class1, class2) => 
-  NameSpace.base class2 ^ "_" ^ NameSpace.base class1) (fn thy => thyname_of_class thy o fst);
+  NameSpace.base_name class2 ^ "_" ^ NameSpace.base_name class1) (fn thy => thyname_of_class thy o fst);
   (*order fits nicely with composed projections*)
 fun namify_tyco thy "fun" = "Pure.fun"
-  | namify_tyco thy tyco = namify thy NameSpace.base thyname_of_tyco tyco;
+  | namify_tyco thy tyco = namify thy NameSpace.base_name thyname_of_tyco tyco;
 fun namify_instance thy = namify thy (fn (class, tyco) => 
-  NameSpace.base class ^ "_" ^ NameSpace.base tyco) thyname_of_instance;
-fun namify_const thy = namify thy NameSpace.base thyname_of_const;
+  NameSpace.base_name class ^ "_" ^ NameSpace.base_name tyco) thyname_of_instance;
+fun namify_const thy = namify thy NameSpace.base_name thyname_of_const;
 
 end; (* local *)
 
--- a/src/Tools/nbe.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/Tools/nbe.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -466,7 +466,7 @@
 (* evaluation oracle *)
 
 val (_, norm_oracle) = Context.>>> (Context.map_theory_result
-  (Thm.add_oracle ("norm", fn (thy, t, naming, program, vs_ty_t, deps) =>
+  (Thm.add_oracle (Binding.name "norm", fn (thy, t, naming, program, vs_ty_t, deps) =>
     Thm.cterm_of thy (Logic.mk_equals (t, eval thy t naming program vs_ty_t deps)))));
 
 fun add_triv_classes thy =
--- a/src/ZF/Tools/datatype_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/ZF/Tools/datatype_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -74,7 +74,7 @@
                    Syntax.string_of_term_global thy t);
 
   val rec_names = map (#1 o dest_Const) rec_hds
-  val rec_base_names = map Sign.base_name rec_names
+  val rec_base_names = map NameSpace.base_name rec_names
   val big_rec_base_name = space_implode "_" rec_base_names
 
   val thy_path = thy |> Sign.add_path big_rec_base_name
--- a/src/ZF/Tools/induct_tacs.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/ZF/Tools/induct_tacs.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -157,7 +157,7 @@
 
   in
     thy
-    |> Sign.add_path (Sign.base_name big_rec_name)
+    |> Sign.add_path (NameSpace.base_name big_rec_name)
     |> PureThy.add_thmss [((Binding.name "simps", simps), [Simplifier.simp_add])] |> snd
     |> DatatypesData.put (Symtab.update (big_rec_name, dt_info) (DatatypesData.get thy))
     |> ConstructorsData.put (fold_rev Symtab.update con_pairs (ConstructorsData.get thy))
--- a/src/ZF/Tools/inductive_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/ZF/Tools/inductive_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -80,7 +80,7 @@
   val rec_names = map (#1 o dest_Const) rec_hds
   and (Const(_,recT),rec_params) = strip_comb (hd rec_tms);
 
-  val rec_base_names = map Sign.base_name rec_names;
+  val rec_base_names = map NameSpace.base_name rec_names;
   val dummy = assert_all Syntax.is_identifier rec_base_names
     (fn a => "Base name of recursive set not an identifier: " ^ a);
 
@@ -377,7 +377,7 @@
        mutual recursion to invariably be a disjoint sum.*)
      fun mk_predpair rec_tm =
        let val rec_name = (#1 o dest_Const o head_of) rec_tm
-           val pfree = Free(pred_name ^ "_" ^ Sign.base_name rec_name,
+           val pfree = Free(pred_name ^ "_" ^ NameSpace.base_name rec_name,
                             elem_factors ---> FOLogic.oT)
            val qconcl =
              List.foldr FOLogic.mk_all
--- a/src/ZF/Tools/primrec_package.ML	Fri Mar 06 15:31:07 2009 +0100
+++ b/src/ZF/Tools/primrec_package.ML	Fri Mar 06 15:31:26 2009 +0100
@@ -139,7 +139,7 @@
     (** make definition **)
 
     (*the recursive argument*)
-    val rec_arg = Free (Name.variant (map #1 (ls@rs)) (Sign.base_name big_rec_name),
+    val rec_arg = Free (Name.variant (map #1 (ls@rs)) (NameSpace.base_name big_rec_name),
                         Ind_Syntax.iT)
 
     val def_tm = Logic.mk_equals
@@ -153,7 +153,7 @@
             writeln ("primrec def:\n" ^
                      Syntax.string_of_term_global thy def_tm)
       else();
-      (Sign.base_name fname ^ "_" ^ Sign.base_name big_rec_name ^ "_def",
+      (NameSpace.base_name fname ^ "_" ^ NameSpace.base_name big_rec_name ^ "_def",
        def_tm)
   end;
 
@@ -168,7 +168,7 @@
     val def = process_fun thy (fname, ftype, ls, rs, con_info, eqns);
 
     val ([def_thm], thy1) = thy
-      |> Sign.add_path (Sign.base_name fname)
+      |> Sign.add_path (NameSpace.base_name fname)
       |> PureThy.add_defs false [Thm.no_attributes (apfst Binding.name def)];
 
     val rewrites = def_thm :: map mk_meta_eq (#rec_rewrites con_info)