Theory Spec

(*:maxLineLen=78:*)

theory Spec
  imports Main Base
begin

chapter ‹Specifications›

text ‹
  The Isabelle/Isar theory format integrates specifications and proofs, with
  support for interactive development by continuous document editing. There is
  a separate document preparation system (see \chref{ch:document-prep}), for
  typesetting formal developments together with informal text. The resulting
  hyper-linked PDF documents can be used both for WWW presentation and printed
  copies.

  The Isar proof language (see \chref{ch:proofs}) is embedded into the theory
  language as a proper sub-language. Proof mode is entered by stating some
  theorem or lemma at the theory level, and left again with the final
  conclusion (e.g.\ via qed).
›


section ‹Defining theories \label{sec:begin-thy}›

text ‹
  \begin{matharray}{rcl}
    @{command_def "theory"} & : & toplevel → theory› \\
    @{command_def (global) "end"} & : & theory → toplevel› \\
    @{command_def "thy_deps"}* & : & theory →› \\
  \end{matharray}

  Isabelle/Isar theories are defined via theory files, which consist of an
  outermost sequence of definition--statement--proof elements. Some
  definitions are self-sufficient (e.g.\ fun in Isabelle/HOL), with
  foundational proofs performed internally. Other definitions require an
  explicit proof as justification (e.g.\ function and termination in
  Isabelle/HOL). Plain statements like theorem or lemma are merely a
  special case of that, defining a theorem from a given proposition and its
  proof.

  The theory body may be sub-structured by means of ‹local theory targets›,
  such as locale and class. It is also possible to use context beginend blocks to delimited a local theory context: a ‹named context› to
  augment a locale or class specification, or an ‹unnamed context› to refer
  to local parameters and assumptions that are discharged later. See
  \secref{sec:target} for more details.

  
  A theory is commenced by the theory command, which indicates imports of
  previous theories, according to an acyclic foundational order. Before the
  initial theory command, there may be optional document header material
  (like section or text, see \secref{sec:markup}). The document header
  is outside of the formal theory context, though.

  A theory is concluded by a final @{command (global) "end"} command, one that
  does not belong to a local theory target. No further commands may follow
  such a global @{command (global) "end"}.

  rail@@{command theory} @{syntax system_name}
      @'imports' (@{syntax system_name} +) 
      keywords? abbrevs? @'begin'
    ;
    keywords: @'keywords' (keyword_decls + @'and')
    ;
    keyword_decls: (@{syntax string} +) ('::' @{syntax name} @{syntax tags})?
    ;
    abbrevs: @'abbrevs' (((text+) '=' (text+)) + @'and')
    ;
    @@{command thy_deps} (thy_bounds thy_bounds?)?
    ;
    thy_bounds: @{syntax name} | '(' (@{syntax name} + @'|') ')'

   theory A imports B1 … Bn begin starts a new theory A› based on the
  merge of existing theories B1 … Bn. Due to the possibility to import
  more than one ancestor, the resulting theory structure of an Isabelle
  session forms a directed acyclic graph (DAG). Isabelle takes care that
  sources contributing to the development graph are always up-to-date: changed
  files are automatically rechecked whenever a theory header specification is
  processed.

  Empty imports are only allowed in the bootstrap process of the special
  theory theoryPure, which is the start of any other formal development
  based on Isabelle. Regular user theories usually refer to some more complex
  entry point, such as theory theoryMain in Isabelle/HOL.

  The @{keyword_def "keywords"} specification declares outer syntax
  (\chref{ch:outer-syntax}) that is introduced in this theory later on (rare
  in end-user applications). Both minor keywords and major keywords of the
  Isar command language need to be specified, in order to make parsing of
  proof documents work properly. Command keywords need to be classified
  according to their structural role in the formal text. Examples may be seen
  in Isabelle/HOL sources itself, such as @{keyword "keywords"}~‹"typedef"›
  :: thy_goal_defn› or @{keyword "keywords"}~‹"datatype"› :: thy_defn› for
  theory-level definitions with and without proof, respectively. Additional
  @{syntax tags} provide defaults for document preparation
  (\secref{sec:document-markers}).

  The @{keyword_def "abbrevs"} specification declares additional abbreviations
  for syntactic completion. The default for a new keyword is just its name,
  but completion may be avoided by defining @{keyword "abbrevs"} with empty
  text.

   @{command (global) "end"} concludes the current theory definition. Note
  that some other commands, e.g.\ local theory targets locale or class
  may involve a begin that needs to be matched by @{command (local) "end"},
  according to the usual rules for nested blocks.

   thy_deps visualizes the theory hierarchy as a directed acyclic graph.
  By default, all imported theories are shown. This may be restricted by
  specifying bounds wrt. the theory inclusion relation.
›


section ‹Local theory targets \label{sec:target}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "context"} & : & theory → local_theory› \\
    @{command_def (local) "end"} & : & local_theory → theory› \\
    @{keyword_def "private"} \\
    @{keyword_def "qualified"} \\
  \end{matharray}

  A local theory target is a specification context that is managed separately
  within the enclosing theory. Contexts may introduce parameters (fixed
  variables) and assumptions (hypotheses). Definitions and theorems depending
  on the context may be added incrementally later on.

  ‹Named contexts› refer to locales (cf.\ \secref{sec:locale}) or type
  classes (cf.\ \secref{sec:class}); the name ``-›'' signifies the global
  theory context.

  ‹Unnamed contexts› may introduce additional parameters and assumptions, and
  results produced in the context are generalized accordingly. Such auxiliary
  contexts may be nested within other targets, like locale, class,
  instantiation, overloading.

  rail@@{command context} @{syntax name} @{syntax_ref "opening"}? @'begin'
    ;
    @@{command context} @{syntax_ref "includes"}? (@{syntax context_elem} * ) @'begin'
    ;
    @{syntax_def target}: '(' @'in' @{syntax name} ')'

   context c bundles begin opens a named context, by recommencing an existing
  locale or class c›. Note that locale and class definitions allow to include
  the begin keyword as well, in order to continue the local theory
  immediately after the initial specification.  Optionally given
  bundles› only take effect in the surface context within the begin /
  end block.

   context bundles elements begin opens an unnamed context, by extending
  the enclosing global or local theory target by the given declaration bundles
  (\secref{sec:bundle}) and context elements (fixes, assumes etc.). This
  means any results stemming from definitions and proofs in the extended
  context will be exported into the enclosing target by lifting over extra
  parameters and premises.

   @{command (local) "end"} concludes the current local theory, according to
  the nesting of contexts. Note that a global @{command (global) "end"} has a
  different meaning: it concludes the theory itself (\secref{sec:begin-thy}).

   private or qualified may be given as modifiers before any local
  theory command. This restricts name space accesses to the local scope, as
  determined by the enclosing context beginend block. Outside its scope,
  a private name is inaccessible, and a qualified name is only
  accessible with some qualification.

  Neither a global theory nor a locale target provides a local scope by
  itself: an extra unnamed context is required to use private or
  qualified here.

   (›@{keyword_def "in"}~c)› given after any local theory command specifies
  an immediate target, e.g.\ ``definition (in c)'' or
  ``theorem (in c)''. This works both in a local or global theory context;
  the current target context will be suspended for this command only. Note
  that ``(in -)'' will always produce a global result independently of the
  current target context.


  Any specification element that operates on local_theory› according to this
  manual implicitly allows the above target syntax (in c), but individual
  syntax diagrams omit that aspect for clarity.

  
  The exact meaning of results produced within a local theory context depends
  on the underlying target infrastructure (locale, type class etc.). The
  general idea is as follows, considering a context named c› with parameter
  x› and assumption A[x]›.

  Definitions are exported by introducing a global version with additional
  arguments; a syntactic abbreviation links the long form with the abstract
  version of the target context. For example, a ≡ t[x]› becomes c.a ?x ≡
  t[?x]› at the theory level (for arbitrary ?x›), together with a local
  abbreviation a ≡ c.a x› in the target context (for the fixed parameter
  x›).

  Theorems are exported by discharging the assumptions and generalizing the
  parameters of the context. For example, a: B[x]› becomes c.a: A[?x] ⟹
  B[?x]›, again for arbitrary ?x›.
›


section ‹Bundled declarations \label{sec:bundle}›

text ‹
  \begin{matharray}{rcl}
    @{command_def "bundle"} & : & local_theory → local_theory› \\
    @{command "bundle"} & : & theory → local_theory› \\
    @{command_def "print_bundles"}* & : & context →› \\
    @{command_def "include"} & : & proof(state) → proof(state)› \\
    @{command_def "including"} & : & proof(prove) → proof(prove)› \\
    @{keyword_def "includes"} & : & syntax \\
  \end{matharray}

  The outer syntax of fact expressions (\secref{sec:syn-att}) involves
  theorems and attributes, which are evaluated in the context and applied to
  it. Attributes may declare theorems to the context, as in this_rule [intro]
  that_rule [elim]› for example. Configuration options (\secref{sec:config})
  are special declaration attributes that operate on the context without a
  theorem, as in [[show_types = false]]› for example.

  Expressions of this form may be defined as ‹bundled declarations› in the
  context, and included in other situations later on. Including declaration
  bundles augments a local context casually without logical dependencies,
  which is in contrast to locales and locale interpretation
  (\secref{sec:locale}).

  rail@@{command bundle} @{syntax name}
      ( '=' @{syntax thms} @{syntax for_fixes} | @'begin')
    ;
    @@{command print_bundles} ('!'?)
    ;
    (@@{command include} | @@{command including}) (@{syntax name}+)
    ;
    @{syntax_def "includes"}: @'includes' (@{syntax name}+)
    ;
    @{syntax_def "opening"}: @'opening' (@{syntax name}+)
    ;
    @@{command unbundle} (@{syntax name}+)
  ›

   bundle b = decls› defines a bundle of declarations in the current
  context. The RHS is similar to the one of the declare command. Bundles
  defined in local theory targets are subject to transformations via
  morphisms, when moved into different application contexts; this works
  analogously to any other local theory specification.

   bundle b begin body end defines a bundle of declarations from the
  body› of local theory specifications. It may consist of commands that are
  technically equivalent to declare or declaration, which also includes
  notation, for example. Named fact declarations like ``lemmas a [simp] =
  b›'' or ``lemma a [simp]: B \<proof>'' are also admitted, but the name
  bindings are not recorded in the bundle.

   print_bundles prints the named bundles that are available in the
  current context; the ``!›'' option indicates extra verbosity.

   include b1 … bn activates the declarations from the given bundles
  in a proof body (forward mode). This is analogous to note
  (\secref{sec:proof-facts}) with the expanded bundles.

   including b1 … bn is similar to include, but works in proof refinement
  (backward mode). This is analogous to using (\secref{sec:proof-facts})
  with the expanded bundles.

   includes b1 … bn is similar to include, but applies to a
  confined specification context: unnamed contexts and
  long statements of theorem.

   opening b1 … bn is similar to includes, but applies to
  a named specification context: locales, classes and
  named contexts. The effect is confined to the surface context within the
  specification block itself and the corresponding begin / end block.

   unbundle b1 … bn activates the declarations from the given bundles in
  the current local theory context. This is analogous to lemmas
  (\secref{sec:theorems}) with the expanded bundles.


  Here is an artificial example of bundling various configuration options:
›

(*<*)experiment begin(*>*)
bundle trace = [[simp_trace, linarith_trace, metis_trace, smt_trace]]

lemma "x = x"
  including trace by metis
(*<*)end(*>*)


section ‹Term definitions \label{sec:term-definitions}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "definition"} & : & local_theory → local_theory› \\
    @{attribute_def "defn"} & : & attribute› \\
    @{command_def "print_defn_rules"}* & : & context →› \\
    @{command_def "abbreviation"} & : & local_theory → local_theory› \\
    @{command_def "print_abbrevs"}* & : & context →› \\
  \end{matharray}

  Term definitions may either happen within the logic (as equational axioms of
  a certain form (see also \secref{sec:overloading}), or outside of it as
  rewrite system on abstract syntax. The second form is called
  ``abbreviation''.

  rail@@{command definition} decl? definition
    ;
    @@{command abbreviation} @{syntax mode}? decl? abbreviation
    ;
    @@{command print_abbrevs} ('!'?)
    ;
    decl: @{syntax name} ('::' @{syntax type})? @{syntax mixfix}? @'where'
    ;
    definition: @{syntax thmdecl}? @{syntax prop}
      @{syntax spec_prems} @{syntax for_fixes}
    ;
    abbreviation: @{syntax prop} @{syntax for_fixes}

   definition c where eq› produces an internal definition c ≡ t› according
  to the specification given as eq›, which is then turned into a proven fact.
  The given proposition may deviate from internal meta-level equality
  according to the rewrite rules declared as @{attribute defn} by the
  object-logic. This usually covers object-level equality x = y› and
  equivalence A ⟷ B›. End-users normally need not change the @{attribute
  defn} setup.

  Definitions may be presented with explicit arguments on the LHS, as well as
  additional conditions, e.g.\ f x y = t› instead of f ≡ λx y. t› and y ≠ 0
  ⟹ g x y = u› instead of an unrestricted g ≡ λx y. u›.

   print_defn_rules prints the definitional rewrite rules declared via
  @{attribute defn} in the current context.

   abbreviation c where eq› introduces a syntactic constant which is
  associated with a certain term according to the meta-level equality eq›.

  Abbreviations participate in the usual type-inference process, but are
  expanded before the logic ever sees them. Pretty printing of terms involves
  higher-order rewriting with rules stemming from reverted abbreviations. This
  needs some care to avoid overlapping or looping syntactic replacements!

  The optional mode› specification restricts output to a particular print
  mode; using ``input›'' here achieves the effect of one-way abbreviations.
  The mode may also include an ``output'' qualifier that affects the
  concrete syntax declared for abbreviations, cf.\ syntax in
  \secref{sec:syn-trans}.

   print_abbrevs prints all constant abbreviations of the current context;
  the ``!›'' option indicates extra verbosity.
›


section ‹Axiomatizations \label{sec:axiomatizations}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "axiomatization"} & : & theory → theory› & (axiomatic!) \\
  \end{matharray}

  rail@@{command axiomatization} @{syntax vars}? (@'where' axiomatization)?
    ;
    axiomatization: (@{syntax thmdecl} @{syntax prop} + @'and')
      @{syntax spec_prems} @{syntax for_fixes}

   axiomatization c1 … cm where φ1 … φn introduces several constants
  simultaneously and states axiomatic properties for these. The constants are
  marked as being specified once and for all, which prevents additional
  specifications for the same constants later on, but it is always possible to
  emit axiomatizations without referring to particular constants. Note that
  lack of precise dependency tracking of axiomatizations may disrupt the
  well-formedness of an otherwise definitional theory.

  Axiomatization is restricted to a global theory context: support for local
  theory targets \secref{sec:target} would introduce an extra dimension of
  uncertainty what the written specifications really are, and make it
  infeasible to argue why they are correct.

  Axiomatic specifications are required when declaring a new logical system
  within Isabelle/Pure, but in an application environment like Isabelle/HOL
  the user normally stays within definitional mechanisms provided by the logic
  and its libraries.
›


section ‹Generic declarations›

text ‹
  \begin{matharray}{rcl}
    @{command_def "declaration"} & : & local_theory → local_theory› \\
    @{command_def "syntax_declaration"} & : & local_theory → local_theory› \\
    @{command_def "declare"} & : & local_theory → local_theory› \\
  \end{matharray}

  Arbitrary operations on the background context may be wrapped-up as generic
  declaration elements. Since the underlying concept of local theories may be
  subject to later re-interpretation, there is an additional dependency on a
  morphism that tells the difference of the original declaration context wrt.\
  the application context encountered later on. A fact declaration is an
  important special case: it consists of a theorem which is applied to the
  context by means of an attribute.

  rail‹
    (@@{command declaration} | @@{command syntax_declaration})
      ('(' @'pervasive' ')')?  @{syntax text}
    ;
    @@{command declare} (@{syntax thms} + @'and')
  ›

   declaration d› adds the declaration function d› of ML type ML_typeMorphism.declaration, to the current local theory under construction. In later
  application contexts, the function is transformed according to the morphisms
  being involved in the interpretation hierarchy.

  If the (pervasive) option is given, the corresponding declaration is
  applied to all possible contexts involved, including the global background
  theory.

   syntax_declaration is similar to declaration, but is meant to affect
  only ``syntactic'' tools by convention (such as notation and type-checking
  information).

   declare thms› declares theorems to the current local theory context. No
  theorem binding is involved here, unlike lemmas (cf.\
  \secref{sec:theorems}), so declare only has the effect of applying
  attributes as included in the theorem specification.
›


section ‹Locales \label{sec:locale}›

text ‹
  A locale is a functor that maps parameters (including implicit type
  parameters) and a specification to a list of declarations. The syntax of
  locales is modeled after the Isar proof context commands (cf.\
  \secref{sec:proof-context}).

  Locale hierarchies are supported by maintaining a graph of dependencies
  between locale instances in the global theory. Dependencies may be
  introduced through import (where a locale is defined as sublocale of the
  imported instances) or by proving that an existing locale is a sublocale of
  one or several locale instances.

  A locale may be opened with the purpose of appending to its list of
  declarations (cf.\ \secref{sec:target}). When opening a locale declarations
  from all dependencies are collected and are presented as a local theory. In
  this process, which is called ‹roundup›, redundant locale instances are
  omitted. A locale instance is redundant if it is subsumed by an instance
  encountered earlier. A more detailed description of this process is
  available elsewhere citeBallarin2014.
›


subsection ‹Locale expressions \label{sec:locale-expr}›

text ‹
  A ‹locale expression› denotes a context composed of instances of existing
  locales. The context consists of the declaration elements from the locale
  instances. Redundant locale instances are omitted according to roundup.

  rail@{syntax_def locale_expr}: (instance + '+') @{syntax for_fixes}
    ;
    instance: (qualifier ':')? @{syntax name} (pos_insts | named_insts) 
      rewrites?
    ;
    qualifier: @{syntax name} ('?')?
    ;
    pos_insts: ('_' | @{syntax term})*
    ;
    named_insts: @'where' (@{syntax name} '=' @{syntax term} + @'and')
    ;
    rewrites: @'rewrites' (@{syntax thmdecl}? @{syntax prop} + @'and')
  ›

  A locale instance consists of a reference to a locale and either positional
  or named parameter instantiations optionally followed by rewrites clauses.
  Identical instantiations (that is, those
  that instantiate a parameter by itself) may be omitted. The notation ``_›''
  enables to omit the instantiation for a parameter inside a positional
  instantiation.

  Terms in instantiations are from the context the locale expressions is
  declared in. Local names may be added to this context with the optional
  for clause. This is useful for shadowing names bound in outer contexts,
  and for declaring syntax. In addition, syntax declarations from one instance
  are effective when parsing subsequent instances of the same expression.

  Instances have an optional qualifier which applies to names in declarations.
  Names include local definitions and theorem names. If present, the qualifier
  itself is either mandatory (default) or non-mandatory (when followed by
  ``‹?›''). Non-mandatory means that the qualifier may be omitted on input.
  Qualifiers only affect name spaces; they play no role in determining whether
  one locale instance subsumes another.

  Rewrite clauses amend instances with equations that act as rewrite rules.
  This is particularly useful for changing concepts introduced through
  definitions. Rewrite clauses are available only in interpretation commands
  (see \secref{sec:locale-interpretation} below) and must be proved the user.
›


subsection ‹Locale declarations›

text ‹
  \begin{tabular}{rcl}
    @{command_def "locale"} & : & theory → local_theory› \\
    @{command_def "experiment"} & : & theory → local_theory› \\
    @{command_def "print_locale"}* & : & context →› \\
    @{command_def "print_locales"}* & : & context →› \\
    @{command_def "locale_deps"}* & : & context →› \\
  \end{tabular}

  @{index_ref fixes (element)›}
  @{index_ref constrains (element)›}
  @{index_ref assumes (element)›}
  @{index_ref defines (element)›}
  @{index_ref notes (element)›}
  rail@@{command locale} @{syntax name} ('=' @{syntax locale})? @'begin'?
    ;
    @@{command experiment} (@{syntax context_elem}*) @'begin'
    ;
    @@{command print_locale} '!'? @{syntax name}
    ;
    @@{command print_locales} ('!'?)
    ;
    @{syntax_def locale}: @{syntax context_elem}+ |
      @{syntax_ref "opening"} ('+' (@{syntax context_elem}+))? |
      @{syntax locale_expr} @{syntax_ref "opening"}? ('+' (@{syntax context_elem}+))?
    ;
    @{syntax_def context_elem}:
      @'fixes' @{syntax vars} |
      @'constrains' (@{syntax name} '::' @{syntax type} + @'and') |
      @'assumes' (@{syntax props} + @'and') |
      @'defines' (@{syntax thmdecl}? @{syntax prop} @{syntax prop_pat}? + @'and') |
      @'notes' (@{syntax thmdef}? @{syntax thms} + @'and')
  ›

   locale loc = import opening bundles + body› defines a new locale loc›
  as a context consisting of a certain view of existing locales (import›) plus some
  additional elements (body›) with declaration bundles› enriching the context
  of the command itself. All import›, bundles› and body› are optional; the
  degenerate form locale loc› defines an empty locale, which may still be
  useful to collect declarations of facts later on. Type-inference on locale
  expressions automatically takes care of the most general typing that the
  combined context elements may acquire.

  The import› consists of a locale expression; see \secref{sec:locale-expr}
  above. Its for clause defines the parameters of import›. These are
  parameters of the defined locale. Locale parameters whose instantiation is
  omitted automatically extend the (possibly empty) for clause: they are
  inserted at its beginning. This means that these parameters may be referred
  to from within the expression and also in the subsequent context elements
  and provides a notational convenience for the inheritance of parameters in
  locale declarations.

  Declarations from bundles›, see \secref{sec:bundle}, are effective in the
  entire command including a subsequent begin / end block, but they do
  not contribute to the declarations stored in the locale.

  The body› consists of context elements:

     @{element "fixes"}~x :: τ (mx)› declares a local parameter of type τ›
    and mixfix annotation mx› (both are optional). The special syntax
    declaration ``(›@{keyword_ref "structure"})›'' means that x› may be
    referenced implicitly in this context.

     @{element "constrains"}~x :: τ› introduces a type constraint τ› on the
    local parameter x›. This element is deprecated. The type constraint
    should be introduced in the for clause or the relevant @{element
    "fixes"} element.

     @{element "assumes"}~a: φ1 … φn introduces local premises, similar
    to assume within a proof (cf.\ \secref{sec:proof-context}).

     @{element "defines"}~a: x ≡ t› defines a previously declared parameter.
    This is similar to define within a proof (cf.\
    \secref{sec:proof-context}), but @{element "defines"} is restricted to
    Pure equalities and the defined variable needs to be declared beforehand
    via @{element "fixes"}. The left-hand side of the equation may have
    additional arguments, e.g.\ ``@{element "defines"}~f x1 … xn ≡ t›'',
    which need to be free in the context.

     @{element "notes"}~a = b1 … bn reconsiders facts within a local
    context. Most notably, this may include arbitrary declarations in any
    attribute specifications included here, e.g.\ a local @{attribute simp}
    rule.

  Both @{element "assumes"} and @{element "defines"} elements contribute to
  the locale specification. When defining an operation derived from the
  parameters, definition (\secref{sec:term-definitions}) is usually more
  appropriate.

  Note that ``(is p1 … pn)'' patterns given in the syntax of @{element
  "assumes"} and @{element "defines"} above are illegal in locale definitions.
  In the long goal format of \secref{sec:goals}, term bindings may be included
  as expected, though.

  
  Locale specifications are ``closed up'' by turning the given text into a
  predicate definition loc_axioms› and deriving the original assumptions as
  local lemmas (modulo local definitions). The predicate statement covers only
  the newly specified assumptions, omitting the content of included locale
  expressions. The full cumulative view is only provided on export, involving
  another predicate loc› that refers to the complete specification text.

  In any case, the predicate arguments are those locale parameters that
  actually occur in the respective piece of text. Also these predicates
  operate at the meta-level in theory, but the locale packages attempts to
  internalize statements according to the object-logic setup (e.g.\ replacing
  ⋀› by ∀›, and ⟹› by ⟶› in HOL; see also \secref{sec:object-logic}).
  Separate introduction rules loc_axioms.intro› and loc.intro› are provided
  as well.

   experiment body begin opens an anonymous locale context with private
  naming policy. Specifications in its body are inaccessible from outside.
  This is useful to perform experiments, without polluting the name space.

   print_locale "locale" prints the contents of the named locale. The
  command omits @{element "notes"} elements by default. Use print_locale!
  to have them included.

   print_locales prints the names of all locales of the current theory;
  the ``!›'' option indicates extra verbosity.

   locale_deps visualizes all locales and their relations as a Hasse
  diagram. This includes locales defined as type classes (\secref{sec:class}).
›


subsection ‹Locale interpretation \label{sec:locale-interpretation}›

text ‹
  \begin{matharray}{rcl}
    @{command "interpretation"} & : & local_theory → proof(prove)› \\
    @{command_def "interpret"} & : & proof(state) | proof(chain) → proof(prove)› \\
    @{command_def "global_interpretation"} & : & theory | local_theory → proof(prove)› \\
    @{command_def "sublocale"} & : & theory | local_theory → proof(prove)› \\
    @{command_def "print_interps"}* & :  & context →› \\
    @{method_def intro_locales} & : & method› \\
    @{method_def unfold_locales} & : & method› \\
    @{attribute_def trace_locales} & : & \mbox{attribute› \quad default false›} \\
  \end{matharray}

  Locales may be instantiated, and the resulting instantiated declarations
  added to the current context. This requires proof (of the instantiated
  specification) and is called ‹locale interpretation›. Interpretation is
  possible within arbitrary local theories (interpretation), within proof
  bodies (interpret), into global theories (global_interpretation) and
  into locales (sublocale).

  rail@@{command interpretation} @{syntax locale_expr}
    ;
    @@{command interpret} @{syntax locale_expr}
    ;
    @@{command global_interpretation} @{syntax locale_expr} definitions?
    ;
    @@{command sublocale} (@{syntax name} ('<' | '⊆'))? @{syntax locale_expr} 
      definitions?
    ;
    @@{command print_interps} @{syntax name}
    ;

    definitions: @'defines' (@{syntax thmdecl}? @{syntax name} 
      @{syntax mixfix}? '=' @{syntax term} + @'and');

  The core of each interpretation command is a locale expression expr›; the
  command generates proof obligations for the instantiated specifications.
  Once these are discharged by the user, instantiated declarations (in
  particular, facts) are added to the context in a post-processing phase, in a
  manner specific to each command.

  Interpretation commands are aware of interpretations that are already
  active: post-processing is achieved through a variant of roundup that takes
  interpretations of the current global or local theory into account. In order
  to simplify the proof obligations according to existing interpretations use
  methods @{method intro_locales} or @{method unfold_locales}.

  Rewrites clauses rewrites eqns› occur within expressions. They amend the
  morphism through which a locale instance is interpreted with rewrite rules,
  also called rewrite morphisms. This is particularly useful for interpreting
  concepts introduced through definitions. The equations must be proved the
  user. To enable syntax of the instantiated locale within the equation, while
  reading a locale expression, equations of a locale instance are read in a
  temporary context where the instance is already activated. If activation
  fails, typically due to duplicate constant declarations, processing falls
  back to reading the equation first.

  Given definitions defs› produce corresponding definitions in the local
  theory's underlying target ‹and› amend the morphism with rewrite rules
  stemming from the symmetric of those definitions. Hence these need not be
  proved explicitly the user. Such rewrite definitions are a even more useful
  device for interpreting concepts introduced through definitions, but they
  are only supported for interpretation commands operating in a local theory
  whose implementing target actually supports this.  Note that despite
  the suggestive and connective, defs›
  are processed sequentially without mutual recursion.

   interpretation expr› interprets expr› into a local theory
  such that its lifetime is limited to the current context block (e.g. a
  locale or unnamed context). At the closing @{command end} of the block the
  interpretation and its declarations disappear. Hence facts based on
  interpretation can be established without creating permanent links to the
  interpreted locale instances, as would be the case with @{command
  sublocale}.

  When used on the level of a global theory, there is no end of a current
  context block, hence interpretation behaves identically to
  global_interpretation then.

   interpret expr› interprets expr› into a proof context:
  the interpretation and its declarations disappear when closing the current
  proof block. Note that for interpret the eqns› should be explicitly
  universally quantified.

   global_interpretation expr defines defs› interprets expr›
  into a global theory.

  When adding declarations to locales, interpreted versions of these
  declarations are added to the global theory for all interpretations in the
  global theory as well. That is, interpretations into global theories
  dynamically participate in any declarations added to locales.

  Free variables in the interpreted expression are allowed. They are turned
  into schematic variables in the generated declarations. In order to use a
  free variable whose name is already bound in the context --- for example,
  because a constant of that name exists --- add it to the for clause.

  When used in a nested target, resulting declarations are propagated
  through the whole target stack.

   sublocale name  expr defines defs› interprets expr›
  into the locale name›. A proof that the specification of name› implies the
  specification of expr› is required. As in the localized version of the
  theorem command, the proof is in the context of name›. After the proof
  obligation has been discharged, the locale hierarchy is changed as if name›
  imported expr› (hence the name sublocale). When the context of name› is
  subsequently entered, traversing the locale hierarchy will involve the
  locale instances of expr›, and their declarations will be added to the
  context. This makes sublocale dynamic: extensions of a locale that is
  instantiated in expr› may take place after the sublocale declaration and
  still become available in the context. Circular sublocale declarations
  are allowed as long as they do not lead to infinite chains.

  If interpretations of name› exist in the current global theory, the command
  adds interpretations for expr› as well, with the same qualifier, although
  only for fragments of expr› that are not interpreted in the theory already.

  Rewrites clauses in the expression or rewrite definitions defs› can help break
  infinite chains induced by circular sublocale declarations.

  In a named context block the sublocale command may also be used, but the
  locale argument must be omitted. The command then refers to the locale (or
  class) target of the context block.

   print_interps name› lists all interpretations of locale name› in the
  current theory or proof context, including those due to a combination of an
  interpretation or interpret and one or several sublocale
  declarations.

   @{method intro_locales} and @{method unfold_locales} repeatedly expand all
  introduction rules of locale predicates of the theory. While @{method
  intro_locales} only applies the loc.intro› introduction rules and therefore
  does not descend to assumptions, @{method unfold_locales} is more aggressive
  and applies loc_axioms.intro› as well. Both methods are aware of locale
  specifications entailed by the context, both from target statements, and
  from interpretations (see below). New goals that are entailed by the current
  context are discharged automatically.

  While @{method unfold_locales} is part of the default method for proof
  and often invoked ``behind the scenes'', @{method intro_locales} helps
  understand which proof obligations originated from which locale instances.
  The latter method is useful while developing proofs but rare in finished
  developments.

   @{attribute trace_locales}, when set to true›, prints the locale
  instances activated during roundup. Use this when locale commands yield
  obscure errors or for understanding local theories created by complex locale
  hierarchies.

  \begin{warn}
    If a global theory inherits declarations (body elements) for a locale from
    one parent and an interpretation of that locale from another parent, the
    interpretation will not be applied to the declarations.
  \end{warn}

  \begin{warn}
    Since attributes are applied to interpreted theorems, interpretation may
    modify the context of common proof tools, e.g.\ the Simplifier or
    Classical Reasoner. As the behaviour of such tools is ‹not› stable under
    interpretation morphisms, manual declarations might have to be added to
    the target context of the interpretation to revert such declarations.
  \end{warn}

  \begin{warn}
    An interpretation in a local theory or proof context may subsume previous
    interpretations. This happens if the same specification fragment is
    interpreted twice and the instantiation of the second interpretation is
    more general than the interpretation of the first. The locale package does
    not attempt to remove subsumed interpretations.
  \end{warn}

  \begin{warn}
    While interpretation (in c) …› is admissible, it is not useful since
    its result is discarded immediately.
  \end{warn}
›


section ‹Classes \label{sec:class}›

text ‹
  \begin{matharray}{rcl}
    @{command_def "class"} & : & theory → local_theory› \\
    @{command_def "instantiation"} & : & theory → local_theory› \\
    @{command_def "instance"} & : & local_theory → local_theory› \\
    @{command "instance"} & : & theory → proof(prove)› \\
    @{command_def "subclass"} & : & local_theory → local_theory› \\
    @{command_def "print_classes"}* & : & context →› \\
    @{command_def "class_deps"}* & : & context →› \\
    @{method_def intro_classes} & : & method› \\
  \end{matharray}

  A class is a particular locale with ‹exactly one› type variable α›. Beyond
  the underlying locale, a corresponding type class is established which is
  interpreted logically as axiomatic type class cite"Wenzel:1997:TPHOL"
  whose logical content are the assumptions of the locale. Thus, classes
  provide the full generality of locales combined with the commodity of type
  classes (notably type-inference). See cite"isabelle-classes" for a short
  tutorial.

  rail@@{command class} class_spec @'begin'?
    ;
    class_spec: @{syntax name} '='
      ((@{syntax name} @{syntax_ref "opening"}? '+' (@{syntax context_elem}+)) |
        @{syntax name} @{syntax_ref "opening"}? |
        @{syntax_ref "opening"}? '+' (@{syntax context_elem}+))
    ;
    @@{command instantiation} (@{syntax name} + @'and') '::' @{syntax arity} @'begin'
    ;
    @@{command instance} (() | (@{syntax name} + @'and') '::' @{syntax arity} |
      @{syntax name} ('<' | '⊆') @{syntax name} )
    ;
    @@{command subclass} @{syntax name}
    ;
    @@{command class_deps} (class_bounds class_bounds?)?
    ;
    class_bounds: @{syntax sort} | '(' (@{syntax sort} + @'|') ')'

   class c = superclasses bundles + body› defines a new class c›, inheriting from
  superclasses›. This introduces a locale c› with import of all locales
  superclasses›.

  Any @{element "fixes"} in body› are lifted to the global theory level
  (‹class operations› f1, …, fn of class c›), mapping the local type
  parameter α› to a schematic type variable ?α :: c›.

  Likewise, @{element "assumes"} in body› are also lifted, mapping each local
  parameter f :: τ[α]› to its corresponding global constant f :: τ[?α ::
  c]›. The corresponding introduction rule is provided as
  c_class_axioms.intro›. This rule should be rarely needed directly --- the
  @{method intro_classes} method takes care of the details of class membership
  proofs.

  Optionally given bundles› take effect in the surface context within the
  body› and the potentially following begin / end block.

   instantiation t :: (s1,, sn)s begin opens a target (cf.\
  \secref{sec:target}) which allows to specify class operations f1, …, fn
  corresponding to sort s› at the particular type instance 1 :: s1, …,
  αn :: sn) t›. A plain instance command in the target body poses a goal
  stating these type arities. The target is concluded by an @{command_ref
  (local) "end"} command.

  Note that a list of simultaneous type constructors may be given; this
  corresponds nicely to mutually recursive type definitions, e.g.\ in
  Isabelle/HOL.

   instance in an instantiation target body sets up a goal stating the
  type arities claimed at the opening instantiation. The proof would
  usually proceed by @{method intro_classes}, and then establish the
  characteristic theorems of the type classes involved. After finishing the
  proof, the background theory will be augmented by the proven type arities.

  On the theory level, instance t :: (s1,, sn)s› provides a convenient
  way to instantiate a type class with no need to specify operations: one can
  continue with the instantiation proof immediately.

   subclass c› in a class context for class d› sets up a goal stating that
  class c› is logically contained in class d›. After finishing the proof,
  class d› is proven to be subclass c› and the locale c› is interpreted
  into d› simultaneously.

  A weakened form of this is available through a further variant of @{command
  instance}: instance c1  c2 opens a proof that class c2 implies
  c1 without reference to the underlying locales; this is useful if the
  properties to prove the logical connection are not sufficient on the locale
  level but on the theory level.

   print_classes prints all classes in the current theory.

   class_deps visualizes classes and their subclass relations as a
  directed acyclic graph. By default, all classes from the current theory
  context are show. This may be restricted by optional bounds as follows:
  class_deps upper› or class_deps upper lower›. A class is visualized, iff
  it is a subclass of some sort from upper› and a superclass of some sort
  from lower›.

   @{method intro_classes} repeatedly expands all class introduction rules of
  this theory. Note that this method usually needs not be named explicitly, as
  it is already included in the default proof step (e.g.\ of proof). In
  particular, instantiation of trivial (syntactic) classes may be performed by
  a single ``..'' proof step.
›


subsection ‹The class target›

text ‹
  %FIXME check

  A named context may refer to a locale (cf.\ \secref{sec:target}). If this
  locale is also a class c›, apart from the common locale target behaviour
  the following happens.

     Local constant declarations g[α]› referring to the local type parameter
    α› and local parameters f[α]› are accompanied by theory-level constants
    g[?α :: c]› referring to theory-level class operations f[?α :: c]›.

     Local theorem bindings are lifted as are assumptions.

     Local syntax refers to local operations g[α]› and global operations
    g[?α :: c]› uniformly. Type inference resolves ambiguities. In rare
    cases, manual type annotations are needed.
›


subsection ‹Co-regularity of type classes and arities›

text ‹
  The class relation together with the collection of type-constructor arities
  must obey the principle of ‹co-regularity› as defined below.

  
  For the subsequent formulation of co-regularity we assume that the class
  relation is closed by transitivity and reflexivity. Moreover the collection
  of arities t :: (vecs)c› is completed such that t :: (vecs)c› and
  c ⊆ c'› implies t :: (vecs)c'› for all such declarations.

  Treating sorts as finite sets of classes (meaning the intersection), the
  class relation c1 ⊆ c2 is extended to sorts as follows:
  \[
    s1 ⊆ s2 ≡ ∀c2 ∈ s2. ∃c1 ∈ s1. c1 ⊆ c2
  \]

  This relation on sorts is further extended to tuples of sorts (of the same
  length) in the component-wise way.

  
  Co-regularity of the class relation together with the arities relation
  means:
  \[
    t :: (vecs1)c1 ⟹ t :: (vecs2)c2 ⟹ c1 ⊆ c2vecs1vecs2
  \]
  for all such arities. In other words, whenever the result classes of some
  type-constructor arities are related, then the argument sorts need to be
  related in the same way.

  
  Co-regularity is a very fundamental property of the order-sorted algebra of
  types. For example, it entails principal types and most general unifiers,
  e.g.\ see cite"nipkow-prehofer".
›


section ‹Overloaded constant definitions \label{sec:overloading}›

text ‹
  Definitions essentially express abbreviations within the logic. The simplest
  form of a definition is c :: σ ≡ t›, where c› is a new constant and t› is
  a closed term that does not mention c›. Moreover, so-called ‹hidden
  polymorphism› is excluded: all type variables in t› need to occur in its
  type σ›.

  ‹Overloading› means that a constant being declared as c :: α decl› may be
  defined separately on type instances c :: (β1, …, βn)κ decl› for each
  type constructor κ›. At most occasions overloading will be used in a
  Haskell-like fashion together with type classes by means of instantiation
  (see \secref{sec:class}). Sometimes low-level overloading is desirable; this
  is supported by consts and overloading explained below.

  The right-hand side of overloaded definitions may mention overloaded
  constants recursively at type instances corresponding to the immediate
  argument types β1, …, βn. Incomplete specification patterns impose
  global constraints on all occurrences. E.g.\ d :: α × α› on the left-hand
  side means that all corresponding occurrences on some right-hand side need
  to be an instance of this, and general d :: α × β› will be disallowed. Full
  details are given by Kun\v{c}ar cite"Kuncar:2015".

  
  The consts command and the overloading target provide a convenient
  interface for end-users. Regular specification elements such as @{command
  definition}, @{command inductive}, @{command function} may be used in the
  body. It is also possible to use consts c :: σ› with later overloading c
   c :: σ› to keep the declaration and definition of a constant separate.

  \begin{matharray}{rcl}
    @{command_def "consts"} & : & theory → theory› \\
    @{command_def "overloading"} & : & theory → local_theory› \\
  \end{matharray}

  rail@@{command consts} ((@{syntax name} '::' @{syntax type} @{syntax mixfix}?) +)
    ;
    @@{command overloading} ( spec + ) @'begin'
    ;
    spec: @{syntax name} ( '≡' | '==' ) @{syntax term} ( '(' @'unchecked' ')' )?

   consts c :: σ› declares constant c› to have any instance of type scheme
  σ›. The optional mixfix annotations may attach concrete syntax to the
  constants declared.

   overloading x1  c1 :: τ1 … xn  cn :: τn beginend defines
  a theory target (cf.\ \secref{sec:target}) which allows to specify already
  declared constants via definitions in the body. These are identified by an
  explicitly given mapping from variable names xi to constants ci at
  particular type instances. The definitions themselves are established using
  common specification tools, using the names xi as reference to the
  corresponding constants.

  Option (unchecked) disables global dependency checks for the
  corresponding definition, which is occasionally useful for exotic
  overloading; this is a form of axiomatic specification. It is at the
  discretion of the user to avoid malformed theory specifications!
›


subsubsection ‹Example›

consts Length :: "'a  nat"

overloading
  Length0  "Length :: unit  nat"
  Length1  "Length :: 'a × unit  nat"
  Length2  "Length :: 'a × 'b × unit  nat"
  Length3  "Length :: 'a × 'b × 'c × unit  nat"
begin

fun Length0 :: "unit  nat" where "Length0 () = 0"
fun Length1 :: "'a × unit  nat" where "Length1 (a, ()) = 1"
fun Length2 :: "'a × 'b × unit  nat" where "Length2 (a, b, ()) = 2"
fun Length3 :: "'a × 'b × 'c × unit  nat" where "Length3 (a, b, c, ()) = 3"

end

lemma "Length (a, b, c, ()) = 3" by simp
lemma "Length ((a, b), (c, d), ()) = 2" by simp
lemma "Length ((a, b, c, d, e), ()) = 1" by simp


section ‹Incorporating ML code \label{sec:ML}›

text ‹
  \begin{matharray}{rcl}
    @{command_def "SML_file"} & : & local_theory → local_theory› \\
    @{command_def "SML_file_debug"} & : & local_theory → local_theory› \\
    @{command_def "SML_file_no_debug"} & : & local_theory → local_theory› \\
    @{command_def "ML_file"} & : & local_theory → local_theory› \\
    @{command_def "ML_file_debug"} & : & local_theory → local_theory› \\
    @{command_def "ML_file_no_debug"} & : & local_theory → local_theory› \\
    @{command_def "ML"} & : & local_theory → local_theory› \\
    @{command_def "ML_export"} & : & local_theory → local_theory› \\
    @{command_def "ML_prf"} & : & proof → proof› \\
    @{command_def "ML_val"} & : & any →› \\
    @{command_def "ML_command"} & : & any →› \\
    @{command_def "setup"} & : & theory → theory› \\
    @{command_def "local_setup"} & : & local_theory → local_theory› \\
    @{command_def "attribute_setup"} & : & local_theory → local_theory› \\
  \end{matharray}
  \begin{tabular}{rcll}
    @{attribute_def ML_print_depth} & : & attribute› & default 10 \\
    @{attribute_def ML_source_trace} & : & attribute› & default false› \\
    @{attribute_def ML_debugger} & : & attribute› & default false› \\
    @{attribute_def ML_exception_trace} & : & attribute› & default false› \\
    @{attribute_def ML_exception_debugger} & : & attribute› & default false› \\
    @{attribute_def ML_environment} & : & attribute› & default Isabelle› \\
  \end{tabular}

  rail‹
    (@@{command SML_file} |
      @@{command SML_file_debug} |
      @@{command SML_file_no_debug} |
      @@{command ML_file} |
      @@{command ML_file_debug} |
      @@{command ML_file_no_debug}) @{syntax name} ';'?
    ;
    (@@{command ML} | @@{command ML_export} | @@{command ML_prf} |
      @@{command ML_val} | @@{command ML_command} | @@{command setup} |
      @@{command local_setup}) @{syntax text}
    ;
    @@{command attribute_setup} @{syntax name} '=' @{syntax text} @{syntax text}?

   SML_file name› reads and evaluates the given Standard ML file. Top-level
  SML bindings are stored within the (global or local) theory context; the
  initial environment is restricted to the Standard ML implementation of
  Poly/ML, without the many add-ons of Isabelle/ML. Multiple SML_file
  commands may be used to build larger Standard ML projects, independently of
  the regular Isabelle/ML environment.

   ML_file name› reads and evaluates the given ML file. The current theory
  context is passed down to the ML toplevel and may be modified, using MLContext.>> or derived ML commands. Top-level ML bindings are stored
  within the (global or local) theory context.

   SML_file_debug, SML_file_no_debug, ML_file_debug, and
  ML_file_no_debug change the @{attribute ML_debugger} option locally while
  the given file is compiled.

   ML is similar to ML_file, but evaluates directly the given text›.
  Top-level ML bindings are stored within the (global or local) theory
  context.

   ML_export is similar to ML, but the resulting toplevel bindings are
  exported to the global bootstrap environment of the ML process --- it has
  a lasting effect that cannot be retracted. This allows ML evaluation
  without a formal theory context, e.g. for command-line tools via @{tool
  process} cite"isabelle-system".

   ML_prf is analogous to ML but works within a proof context.
  Top-level ML bindings are stored within the proof context in a purely
  sequential fashion, disregarding the nested proof structure. ML bindings
  introduced by ML_prf are discarded at the end of the proof.

   ML_val and ML_command are diagnostic versions of ML, which means
  that the context may not be updated. ML_val echos the bindings produced
  at the ML toplevel, but ML_command is silent.

   setup "text" changes the current theory context by applying text›,
  which refers to an ML expression of type ML_typetheory -> theory. This
  enables to initialize any object-logic specific tools and packages written
  in ML, for example.

   local_setup is similar to setup for a local theory context, and an
  ML expression of type ML_typelocal_theory -> local_theory. This allows
  to invoke local theory specification packages without going through concrete
  outer syntax, for example.

   attribute_setup name = "text" description› defines an attribute in the
  current context. The given text› has to be an ML expression of type
  ML_typeattribute context_parser, cf.\ basic parsers defined in
  structure ML_structureArgs and ML_structureAttrib.

  In principle, attributes can operate both on a given theorem and the
  implicit context, although in practice only one is modified and the other
  serves as parameter. Here are examples for these two cases:
›

(*<*)experiment begin(*>*)
        attribute_setup my_rule =
          Attrib.thms >> (fn ths =>
            Thm.rule_attribute ths
              (fn context: Context.generic => fn th: thm =>
                let val th' = th OF ths
                in th' end))

        attribute_setup my_declaration =
          Attrib.thms >> (fn ths =>
            Thm.declaration_attribute
              (fn th: thm => fn context: Context.generic =>
                let val context' = context
                in context' end))
(*<*)end(*>*)

text  @{attribute ML_print_depth} controls the printing depth of the ML toplevel
  pretty printer. Typically the limit should be less than 10. Bigger values
  such as 100--1000 are occasionally useful for debugging.

   @{attribute ML_source_trace} indicates whether the source text that is
  given to the ML compiler should be output: it shows the raw Standard ML
  after expansion of Isabelle/ML antiquotations.

   @{attribute ML_debugger} controls compilation of sources with or without
  debugging information. The global system option @{system_option_ref
  ML_debugger} does the same when building a session image. It is also
  possible use commands like ML_file_debug etc. The ML debugger is
  explained further in cite"isabelle-jedit".

   @{attribute ML_exception_trace} indicates whether the ML run-time system
  should print a detailed stack trace on exceptions. The result is dependent
  on various ML compiler optimizations. The boundary for the exception trace
  is the current Isar command transactions: it is occasionally better to
  insert the combinator MLRuntime.exn_trace into ML code for debugging
  cite"isabelle-implementation", closer to the point where it actually
  happens.

   @{attribute ML_exception_debugger} controls detailed exception trace via
  the Poly/ML debugger, at the cost of extra compile-time and run-time
  overhead. Relevant ML modules need to be compiled beforehand with debugging
  enabled, see @{attribute ML_debugger} above.

   @{attribute ML_environment} determines the named ML environment for
  toplevel declarations, e.g.\ in command ML or ML_file. The following
  ML environments are predefined in Isabelle/Pure:

     Isabelle› for Isabelle/ML. It contains all modules of Isabelle/Pure and
    further add-ons, e.g. material from Isabelle/HOL.

     SML› for official Standard ML. It contains only the initial basis
    according to 🌐‹http://sml-family.org/Basis/overview.html›.

  The Isabelle/ML function MLML_Env.setup defines a new ML environment.
  This is useful to incorporate big SML projects in an isolated name space,
  possibly with variations on ML syntax; the existing setup of
  MLML_Env.SML_operations follows the official standard.

  It is also possible to move toplevel bindings between ML environments, using
  a notation with ``>›'' as separator. For example:
›

(*<*)experiment begin(*>*)
        declare [[ML_environment = "Isabelle>SML"]]
        ML val println = writeln

        declare [[ML_environment = "SML"]]
        ML println "test"

        declare [[ML_environment = "Isabelle"]]
        ML ML println› (*bad*) handle ERROR msg => warning msg
(*<*)end(*>*)


section ‹Generated files and exported files›

text ‹
  Write access to the physical file-system is incompatible with the stateless
  model of processing Isabelle documents. To avoid bad effects, the following
  concepts for abstract file-management are provided by Isabelle:

    [Generated files] are stored within the theory context in Isabelle/ML.
    This allows to operate on the content in Isabelle/ML, e.g. via the command
    @{command compile_generated_files}.

    [Exported files] are stored within the session database in
    Isabelle/Scala. This allows to deliver artefacts to external tools, see
    also cite"isabelle-system" for session ‹ROOT› declaration
    export_files, and @{tool build} option ‹-e›.

  A notable example is the command @{command_ref export_code}
  (\chref{ch:export-code}): it uses both concepts simultaneously.

  File names are hierarchically structured, using a slash as separator. The
  (long) theory name is used as a prefix: the resulting name needs to be
  globally unique.

  \begin{matharray}{rcll}
    @{command_def "generate_file"} & : & local_theory → local_theory› \\
    @{command_def "export_generated_files"} & : & context →› \\
    @{command_def "compile_generated_files"} & : & context →› \\
    @{command_def "external_file"} & : & any → any› \\
  \end{matharray}

  rail@@{command generate_file} path '=' content
    ;
    path: @{syntax embedded}
    ;
    content: @{syntax embedded}
    ;
    @@{command export_generated_files} (files_in_theory + @'and')
    ;
    files_in_theory: (@'_' | (path+)) (('(' @'in' @{syntax name} ')')?)
    ;
    @@{command compile_generated_files} (files_in_theory + @'and') 
      (@'external_files' (external_files + @'and'))? 
      (@'export_files' (export_files + @'and'))? 
      (@'export_prefix' path)?
    ;
    external_files: (path+) (('(' @'in' path ')')?)
    ;
    export_files: (path+) (executable?)
    ;
    executable: '(' ('exe' | 'executable') ')'
    ;
    @@{command external_file} @{syntax name} ';'?

   generate_file path = content› augments the table of generated files
  within the current theory by a new entry: duplicates are not allowed. The
  name extension determines a pre-existent file-type; the content› is a
  string that is preprocessed according to rules of this file-type.

  For example, Isabelle/Pure supports ‹.hs› as file-type for Haskell:
  embedded cartouches are evaluated as Isabelle/ML expressions of type
  ML_typestring, the result is inlined in Haskell string syntax.

   export_generated_files paths (in thy) retrieves named generated files
  from the given theory (that needs be reachable via imports of the current
  one). By default, the current theory node is used. Using ``‹_›''
  (underscore) instead of explicit path names refers to \emph{all} files of a
  theory node.

  The overall list of files is prefixed with the respective (long) theory name
  and exported to the session database. In Isabelle/jEdit the result can be
  browsed via the virtual file-system with prefix ``‹isabelle-export:›''
  (using the regular file-browser).

   scala_build_generated_files paths (in thy) retrieves named generated
  files as for export_generated_files and writes them into a temporary
  directory, which is taken as starting point for build process of
  Isabelle/Scala/Java modules (see cite"isabelle-system"). The
  corresponding @{path ‹build.props›} file is expected directly in the toplevel
  directory, instead of @{path ‹etc/build.props›} for Isabelle system
  components. These properties need to specify sources, resources, services
  etc. as usual. The resulting JAR module becomes an export artefact of the
  session database, with a name of the form
  ``theory›‹:classpath/›module›‹.jar›''.

   compile_generated_files paths (in thy) where compile_body› retrieves
  named generated files as for export_generated_files and writes them into
  a temporary directory, such that the compile_body› may operate on them as
  an ML function of type ML_typePath.T -> unit. This may create further
  files, e.g.\ executables produced by a compiler that is invoked as external
  process (e.g.\ via MLIsabelle_System.bash), or any other files.

  The option ``external_files paths (in base_dir)'' copies files from the
  physical file-system into the temporary directory, \emph{before} invoking
  compile_body›. The base_dir› prefix is removed from each of the paths›,
  but the remaining sub-directory structure is reconstructed in the target
  directory.

  The option ``export_files paths›'' exports the specified files from the
  temporary directory to the session database, \emph{after} invoking
  compile_body›. Entries may be decorated with ``(exe)'' to say that it is
  a platform-specific executable program: the executable file-attribute will
  be set, and on Windows the ‹.exe› file-extension will be included;
  ``(executable)'' only refers to the file-attribute, without special
  treatment of the ‹.exe› extension.

  The option ``export_prefix path›'' specifies an extra path prefix for all
  exports of export_files above.

   external_file name› declares the formal dependency on the given file
  name, such that the Isabelle build process knows about it (see also cite"isabelle-system"). This is required for any files mentioned in
  compile_generated_files / external_files above, in order to document
  source dependencies properly. It is also possible to use external_file
  alone, e.g.\ when other Isabelle/ML tools use MLFile.read, without
  specific management of content by the Prover IDE.
›


section ‹Primitive specification elements›

subsection ‹Sorts›

text ‹
  \begin{matharray}{rcll}
    @{command_def "default_sort"} & : & local_theory → local_theory›
  \end{matharray}

  rail@@{command default_sort} @{syntax sort}

   default_sort s› makes sort s› the new default sort for any type
  variable that is given explicitly in the text, but lacks a sort constraint
  (wrt.\ the current context). Type variables generated by type inference are
  not affected.

  Usually the default sort is only changed when defining a new object-logic.
  For example, the default sort in Isabelle/HOL is classtype, the class of
  all HOL types.

  When merging theories, the default sorts of the parents are logically
  intersected, i.e.\ the representations as lists of classes are joined.
›


subsection ‹Types \label{sec:types-pure}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "type_synonym"} & : & local_theory → local_theory› \\
    @{command_def "typedecl"} & : & local_theory → local_theory› \\
  \end{matharray}

  rail@@{command type_synonym} (@{syntax typespec} '=' @{syntax type} @{syntax mixfix}?)
    ;
    @@{command typedecl} @{syntax typespec} @{syntax mixfix}?

   type_synonym (α1,, αn) t = τ› introduces a ‹type synonym› 1, …,
  αn) t› for the existing type τ›. Unlike the semantic type definitions in
  Isabelle/HOL, type synonyms are merely syntactic abbreviations without any
  logical significance. Internally, type synonyms are fully expanded.

   typedecl (α1,, αn) t› declares a new type constructor t›. If the
  object-logic defines a base sort s›, then the constructor is declared to
  operate on that, via the axiomatic type-class instance t :: (s, …, s)s›.


  \begin{warn}
    If you introduce a new type axiomatically, i.e.\ via @{command_ref
    typedecl} and @{command_ref axiomatization}
    (\secref{sec:axiomatizations}), the minimum requirement is that it has a
    non-empty model, to avoid immediate collapse of the logical environment.
    Moreover, one needs to demonstrate that the interpretation of such
    free-form axiomatizations can coexist with other axiomatization schemes
    for types, notably @{command_def typedef} in Isabelle/HOL
    (\secref{sec:hol-typedef}), or any other extension that people might have
    introduced elsewhere.
  \end{warn}
›


section ‹Naming existing theorems \label{sec:theorems}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "lemmas"} & : & local_theory → local_theory› \\
    @{command_def "named_theorems"} & : & local_theory → local_theory› \\
  \end{matharray}

  rail@@{command lemmas} (@{syntax thmdef}? @{syntax thms} + @'and')
      @{syntax for_fixes}
    ;
    @@{command named_theorems} (@{syntax name} @{syntax text}? + @'and')
  ›

   lemmas a = b1 … bn~@{keyword_def "for"}~x1 … xm evaluates given
  facts (with attributes) in the current context, which may be augmented by
  local variables. Results are standardized before being stored, i.e.\
  schematic variables are renamed to enforce index 0› uniformly.

   named_theorems name description› declares a dynamic fact within the
  context. The same name› is used to define an attribute with the usual
  add›/del› syntax (e.g.\ see \secref{sec:simp-rules}) to maintain the
  content incrementally, in canonical declaration order of the text structure.
›


section ‹Oracles \label{sec:oracles}›

text ‹
  \begin{matharray}{rcll}
    @{command_def "oracle"} & : & theory → theory› & (axiomatic!) \\
    @{command_def "thm_oracles"}* & : & context →› \\
  \end{matharray}

  Oracles allow Isabelle to take advantage of external reasoners such as
  arithmetic decision procedures, model checkers, fast tautology checkers or
  computer algebra systems. Invoked as an oracle, an external reasoner can
  create arbitrary Isabelle theorems.

  It is the responsibility of the user to ensure that the external reasoner is
  as trustworthy as the application requires. Another typical source of errors
  is the linkup between Isabelle and the external tool, not just its concrete
  implementation, but also the required translation between two different
  logical environments.

  Isabelle merely guarantees well-formedness of the propositions being
  asserted, and records within the internal derivation object how presumed
  theorems depend on unproven suppositions. This also includes implicit
  type-class reasoning via the order-sorted algebra of class relations and
  type arities (see also @{command_ref instantiation} and @{command_ref
  instance}).

  rail@@{command oracle} @{syntax name} '=' @{syntax text}
    ;
    @@{command thm_oracles} @{syntax thms}

   oracle name = "text" turns the given ML expression text› of type
  ML_text‹'a -> cterm› into an ML function of type ML_text‹'a -> thm›,
  which is bound to the global identifier ML_text‹name›. This acts like an
  infinitary specification of axioms! Invoking the oracle only works within
  the scope of the resulting theory.

  See 🗏‹~~/src/HOL/Examples/Iff_Oracle.thy› for a worked example of defining
  a new primitive rule as oracle, and turning it into a proof method.

   thm_oracles thms› displays all oracles used in the internal derivation
  of the given theorems; this covers the full graph of transitive
  dependencies.
›


section ‹Name spaces›

text ‹
  \begin{matharray}{rcl}
    @{command_def "alias"} & : & local_theory → local_theory› \\
    @{command_def "type_alias"} & : & local_theory → local_theory› \\
    @{command_def "hide_class"} & : & theory → theory› \\
    @{command_def "hide_type"} & : & theory → theory› \\
    @{command_def "hide_const"} & : & theory → theory› \\
    @{command_def "hide_fact"} & : & theory → theory› \\
  \end{matharray}

  rail‹
    (@{command alias} | @{command type_alias}) @{syntax name} '=' @{syntax name}
    ;
    (@{command hide_class} | @{command hide_type} |
      @{command hide_const} | @{command hide_fact}) ('(' @'open' ')')? (@{syntax name} + )
  ›

  Isabelle organizes any kind of name declarations (of types, constants,
  theorems etc.) by separate hierarchically structured name spaces. Normally
  the user does not have to control the behaviour of name spaces by hand, yet
  the following commands provide some way to do so.

   alias and type_alias introduce aliases for constants and type
  constructors, respectively. This allows adhoc changes to name-space
  accesses.

   type_alias b = c› introduces an alias for an existing type constructor.

   hide_class names› fully removes class declarations from a given name
  space; with the (open)› option, only the unqualified base name is hidden.

  Note that hiding name space accesses has no impact on logical declarations
  --- they remain valid internally. Entities that are no longer accessible to
  the user are printed with the special qualifier ``??›'' prefixed to the
  full internal name.

   hide_type, hide_const, and hide_fact are similar to
  hide_class, but hide types, constants, and facts, respectively.
›

end