doc-src/Locales/Locales/Examples.thy
author Walther Neuper <neuper@ist.tugraz.at>
Thu, 12 Aug 2010 15:03:34 +0200
branchisac-from-Isabelle2009-2
changeset 37913 20e3616b2d9c
parent 37190 7f2a6f3143ad
child 47727 f72a2bedd7a9
permissions -rw-r--r--
prepare reactivation of isac-update-Isa09-2
ballarin@27063
     1
theory Examples
ballarin@32981
     2
imports Main
ballarin@27063
     3
begin
ballarin@27063
     4
wenzelm@27081
     5
pretty_setmargin %invisible 65
ballarin@27063
     6
ballarin@27063
     7
(*
ballarin@27063
     8
text {* The following presentation will use notation of
ballarin@27063
     9
  Isabelle's meta logic, hence a few sentences to explain this.
ballarin@27063
    10
  The logical
ballarin@27063
    11
  primitives are universal quantification (@{text "\<And>"}), entailment
ballarin@27063
    12
  (@{text "\<Longrightarrow>"}) and equality (@{text "\<equiv>"}).  Variables (not bound
ballarin@27063
    13
  variables) are sometimes preceded by a question mark.  The logic is
ballarin@32983
    14
  typed.  Type variables are denoted by~@{text "'a"},~@{text "'b"}
ballarin@32983
    15
  etc., and~@{text "\<Rightarrow>"} is the function type.  Double brackets~@{text
ballarin@32983
    16
  "\<lbrakk>"} and~@{text "\<rbrakk>"} are used to abbreviate nested entailment.
ballarin@27063
    17
*}
ballarin@27063
    18
*)
ballarin@27063
    19
ballarin@27063
    20
section {* Introduction *}
ballarin@27063
    21
ballarin@27063
    22
text {*
ballarin@27063
    23
  Locales are based on contexts.  A \emph{context} can be seen as a
ballarin@27063
    24
  formula schema
ballarin@27063
    25
\[
ballarin@27063
    26
  @{text "\<And>x\<^sub>1\<dots>x\<^sub>n. \<lbrakk> A\<^sub>1; \<dots> ;A\<^sub>m \<rbrakk> \<Longrightarrow> \<dots>"}
ballarin@27063
    27
\]
ballarin@33838
    28
  where the variables~@{text "x\<^sub>1"}, \ldots,~@{text "x\<^sub>n"} are called
ballarin@32983
    29
  \emph{parameters} and the premises $@{text "A\<^sub>1"}, \ldots,~@{text
ballarin@32983
    30
  "A\<^sub>m"}$ \emph{assumptions}.  A formula~@{text "C"}
ballarin@27063
    31
  is a \emph{theorem} in the context if it is a conclusion
ballarin@27063
    32
\[
ballarin@27063
    33
  @{text "\<And>x\<^sub>1\<dots>x\<^sub>n. \<lbrakk> A\<^sub>1; \<dots> ;A\<^sub>m \<rbrakk> \<Longrightarrow> C"}.
ballarin@27063
    34
\]
ballarin@27063
    35
  Isabelle/Isar's notion of context goes beyond this logical view.
ballarin@27063
    36
  Its contexts record, in a consecutive order, proved
ballarin@32983
    37
  conclusions along with \emph{attributes}, which can provide context
ballarin@32983
    38
  specific configuration information for proof procedures and concrete
ballarin@32983
    39
  syntax.  From a logical perspective, locales are just contexts that
ballarin@32983
    40
  have been made persistent.  To the user, though, they provide
ballarin@32983
    41
  powerful means for declaring and combining contexts, and for the
ballarin@32983
    42
  reuse of theorems proved in these contexts.
ballarin@27063
    43
  *}
ballarin@27063
    44
ballarin@27063
    45
section {* Simple Locales *}
ballarin@27063
    46
ballarin@27063
    47
text {*
ballarin@32983
    48
  In its simplest form, a
ballarin@27063
    49
  \emph{locale declaration} consists of a sequence of context elements
ballarin@27063
    50
  declaring parameters (keyword \isakeyword{fixes}) and assumptions
ballarin@27063
    51
  (keyword \isakeyword{assumes}).  The following is the specification of
ballarin@27063
    52
  partial orders, as locale @{text partial_order}.
ballarin@27063
    53
  *}
ballarin@27063
    54
ballarin@27063
    55
  locale partial_order =
ballarin@27063
    56
    fixes le :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubseteq>" 50)
ballarin@27063
    57
    assumes refl [intro, simp]: "x \<sqsubseteq> x"
ballarin@27063
    58
      and anti_sym [intro]: "\<lbrakk> x \<sqsubseteq> y; y \<sqsubseteq> x \<rbrakk> \<Longrightarrow> x = y"
ballarin@27063
    59
      and trans [trans]: "\<lbrakk> x \<sqsubseteq> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"
ballarin@27063
    60
ballarin@32983
    61
text (in partial_order) {* The parameter of this locale is~@{text le},
ballarin@32983
    62
  which is a binary predicate with infix syntax~@{text \<sqsubseteq>}.  The
ballarin@32983
    63
  parameter syntax is available in the subsequent
ballarin@32983
    64
  assumptions, which are the familiar partial order axioms.
ballarin@27063
    65
ballarin@32983
    66
  Isabelle recognises unbound names as free variables.  In locale
ballarin@32981
    67
  assumptions, these are implicitly universally quantified.  That is,
ballarin@32983
    68
  @{term "\<lbrakk> x \<sqsubseteq> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"} in fact means
ballarin@32983
    69
  @{term "\<And>x y z. \<lbrakk> x \<sqsubseteq> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubseteq> z"}.
ballarin@32981
    70
ballarin@32981
    71
  Two commands are provided to inspect locales:
ballarin@32981
    72
  \isakeyword{print\_locales} lists the names of all locales of the
ballarin@32981
    73
  current theory; \isakeyword{print\_locale}~$n$ prints the parameters
ballarin@32983
    74
  and assumptions of locale $n$; the variation \isakeyword{print\_locale!}~$n$
ballarin@32983
    75
  additionally outputs the conclusions that are stored in the locale.
ballarin@32983
    76
  We may inspect the new locale
ballarin@32981
    77
  by issuing \isakeyword{print\_locale!} @{term partial_order}.  The output
ballarin@32981
    78
  is the following list of context elements.
ballarin@32983
    79
\begin{small}
ballarin@32981
    80
\begin{alltt}
ballarin@32981
    81
  \isakeyword{fixes} le :: "'a \(\Rightarrow\) 'a \(\Rightarrow\)  bool" (\isakeyword{infixl} "\(\sqsubseteq\)" 50)
ballarin@32981
    82
  \isakeyword{assumes} "partial_order op \(\sqsubseteq\)"
ballarin@32981
    83
  \isakeyword{notes} assumption
ballarin@32981
    84
    refl [intro, simp] = `?x \(\sqsubseteq\) ?x`
ballarin@32981
    85
    \isakeyword{and}
ballarin@32981
    86
    anti_sym [intro] = `\(\isasymlbrakk\)?x \(\sqsubseteq\) ?y; ?y \(\sqsubseteq\) ?x\(\isasymrbrakk\) \(\Longrightarrow\) ?x = ?y`
ballarin@32981
    87
    \isakeyword{and}
ballarin@32981
    88
    trans [trans] = `\(\isasymlbrakk\)?x \(\sqsubseteq\) ?y; ?y \(\sqsubseteq\) ?z\(\isasymrbrakk\) \(\Longrightarrow\) ?x \(\sqsubseteq\) ?z`
ballarin@32981
    89
\end{alltt}
ballarin@32983
    90
\end{small}
ballarin@32981
    91
  The keyword \isakeyword{notes} denotes a conclusion element.  There
ballarin@32983
    92
  is one conclusion, which was added automatically.  Instead, there is
ballarin@32983
    93
  only one assumption, namely @{term "partial_order le"}.  The locale
ballarin@32983
    94
  declaration has introduced the predicate @{term
ballarin@32983
    95
  partial_order} to the theory.  This predicate is the
ballarin@32983
    96
  \emph{locale predicate}.  Its definition may be inspected by
ballarin@32983
    97
  issuing \isakeyword{thm} @{thm [source] partial_order_def}.
ballarin@27063
    98
  @{thm [display, indent=2] partial_order_def}
ballarin@32983
    99
  In our example, this is a unary predicate over the parameter of the
ballarin@32983
   100
  locale.  It is equivalent to the original assumptions, which have
ballarin@32983
   101
  been turned into conclusions and are
ballarin@32981
   102
  available as theorems in the context of the locale.  The names and
ballarin@32981
   103
  attributes from the locale declaration are associated to these
ballarin@32981
   104
  theorems and are effective in the context of the locale.
ballarin@27063
   105
ballarin@32983
   106
  Each conclusion has a \emph{foundational theorem} as counterpart
ballarin@32983
   107
  in the theory.  Technically, this is simply the theorem composed
ballarin@32983
   108
  of context and conclusion.  For the transitivity theorem, this is
ballarin@32983
   109
  @{thm [source] partial_order.trans}:
ballarin@37190
   110
  @{thm [display, indent=2] partial_order.trans}
ballarin@32981
   111
*}
ballarin@32981
   112
ballarin@32983
   113
subsection {* Targets: Extending Locales *}
ballarin@32981
   114
ballarin@32981
   115
text {*
ballarin@27063
   116
  The specification of a locale is fixed, but its list of conclusions
ballarin@27063
   117
  may be extended through Isar commands that take a \emph{target} argument.
ballarin@27063
   118
  In the following, \isakeyword{definition} and 
ballarin@27063
   119
  \isakeyword{theorem} are illustrated.
ballarin@27063
   120
  Table~\ref{tab:commands-with-target} lists Isar commands that accept
ballarin@32983
   121
  a target.  Isar provides various ways of specifying the target.  A
ballarin@27063
   122
  target for a single command may be indicated with keyword
ballarin@27063
   123
  \isakeyword{in} in the following way:
ballarin@27063
   124
ballarin@27063
   125
\begin{table}
ballarin@27063
   126
\hrule
ballarin@27063
   127
\vspace{2ex}
ballarin@27063
   128
\begin{center}
ballarin@27063
   129
\begin{tabular}{ll}
ballarin@27063
   130
  \isakeyword{definition} & definition through an equation \\
ballarin@27063
   131
  \isakeyword{inductive} & inductive definition \\
ballarin@30822
   132
  \isakeyword{primrec} & primitive recursion \\
ballarin@30822
   133
  \isakeyword{fun}, \isakeyword{function} & general recursion \\
ballarin@27063
   134
  \isakeyword{abbreviation} & syntactic abbreviation \\
ballarin@27063
   135
  \isakeyword{theorem}, etc.\ & theorem statement with proof \\
ballarin@30822
   136
  \isakeyword{theorems}, etc.\ & redeclaration of theorems \\
ballarin@30822
   137
  \isakeyword{text}, etc.\ & document markup
ballarin@27063
   138
\end{tabular}
ballarin@27063
   139
\end{center}
ballarin@27063
   140
\hrule
ballarin@27063
   141
\caption{Isar commands that accept a target.}
ballarin@27063
   142
\label{tab:commands-with-target}
ballarin@27063
   143
\end{table}
ballarin@27063
   144
  *}
ballarin@27063
   145
ballarin@27063
   146
  definition (in partial_order)
ballarin@27063
   147
    less :: "'a \<Rightarrow> 'a \<Rightarrow> bool" (infixl "\<sqsubset>" 50)
ballarin@27063
   148
    where "(x \<sqsubset> y) = (x \<sqsubseteq> y \<and> x \<noteq> y)"
ballarin@27063
   149
ballarin@32981
   150
text (in partial_order) {* The strict order @{text less} with infix
ballarin@32983
   151
  syntax~@{text \<sqsubset>} is
ballarin@32983
   152
  defined in terms of the locale parameter~@{text le} and the general
ballarin@32983
   153
  equality of the object logic we work in.  The definition generates a
ballarin@32983
   154
  \emph{foundational constant}
ballarin@32981
   155
  @{term partial_order.less} with definition @{thm [source]
ballarin@32981
   156
  partial_order.less_def}:
ballarin@27063
   157
  @{thm [display, indent=2] partial_order.less_def}
ballarin@30822
   158
  At the same time, the locale is extended by syntax transformations
ballarin@32983
   159
  hiding this construction in the context of the locale.  Here, the
ballarin@32983
   160
  abbreviation @{text less} is available for
ballarin@32981
   161
  @{text "partial_order.less le"}, and it is printed
ballarin@32983
   162
  and parsed as infix~@{text \<sqsubset>}.  Finally, the conclusion @{thm [source]
ballarin@32981
   163
  less_def} is added to the locale:
ballarin@32981
   164
  @{thm [display, indent=2] less_def}
ballarin@32981
   165
*}
wenzelm@30393
   166
ballarin@32981
   167
text {* The treatment of theorem statements is more straightforward.
ballarin@32981
   168
  As an example, here is the derivation of a transitivity law for the
ballarin@32981
   169
  strict order relation. *}
ballarin@27063
   170
ballarin@27063
   171
  lemma (in partial_order) less_le_trans [trans]:
ballarin@27063
   172
    "\<lbrakk> x \<sqsubset> y; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<sqsubset> z"
ballarin@27063
   173
    unfolding %visible less_def by %visible (blast intro: trans)
ballarin@27063
   174
ballarin@32983
   175
text {* In the context of the proof, conclusions of the
ballarin@32983
   176
  locale may be used like theorems.  Attributes are effective: @{text
ballarin@32983
   177
  anti_sym} was
ballarin@27063
   178
  declared as introduction rule, hence it is in the context's set of
ballarin@27063
   179
  rules used by the classical reasoner by default.  *}
ballarin@27063
   180
ballarin@32981
   181
subsection {* Context Blocks *}
ballarin@32981
   182
ballarin@27063
   183
text {* When working with locales, sequences of commands with the same
ballarin@27063
   184
  target are frequent.  A block of commands, delimited by
ballarin@27063
   185
  \isakeyword{begin} and \isakeyword{end}, makes a theory-like style
ballarin@27063
   186
  of working possible.  All commands inside the block refer to the
ballarin@27063
   187
  same target.  A block may immediately follow a locale
ballarin@27063
   188
  declaration, which makes that locale the target.  Alternatively the
ballarin@27063
   189
  target for a block may be given with the \isakeyword{context}
ballarin@27063
   190
  command.
ballarin@27063
   191
ballarin@30573
   192
  This style of working is illustrated in the block below, where
ballarin@30573
   193
  notions of infimum and supremum for partial orders are introduced,
ballarin@32981
   194
  together with theorems about their uniqueness.  *}
ballarin@27063
   195
ballarin@27063
   196
  context partial_order begin
ballarin@27063
   197
ballarin@27063
   198
  definition
ballarin@27063
   199
    is_inf where "is_inf x y i =
ballarin@27063
   200
      (i \<sqsubseteq> x \<and> i \<sqsubseteq> y \<and> (\<forall>z. z \<sqsubseteq> x \<and> z \<sqsubseteq> y \<longrightarrow> z \<sqsubseteq> i))"
ballarin@27063
   201
ballarin@27063
   202
  definition
ballarin@27063
   203
    is_sup where "is_sup x y s =
ballarin@27063
   204
      (x \<sqsubseteq> s \<and> y \<sqsubseteq> s \<and> (\<forall>z. x \<sqsubseteq> z \<and> y \<sqsubseteq> z \<longrightarrow> s \<sqsubseteq> z))"
ballarin@27063
   205
ballarin@27063
   206
  lemma %invisible is_infI [intro?]: "i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow>
ballarin@27063
   207
      (\<And>z. z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i) \<Longrightarrow> is_inf x y i"
ballarin@27063
   208
    by (unfold is_inf_def) blast
ballarin@27063
   209
ballarin@27063
   210
  lemma %invisible is_inf_lower [elim?]:
ballarin@27063
   211
    "is_inf x y i \<Longrightarrow> (i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow> C) \<Longrightarrow> C"
ballarin@27063
   212
    by (unfold is_inf_def) blast
ballarin@27063
   213
ballarin@27063
   214
  lemma %invisible is_inf_greatest [elim?]:
ballarin@27063
   215
      "is_inf x y i \<Longrightarrow> z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i"
ballarin@27063
   216
    by (unfold is_inf_def) blast
ballarin@27063
   217
ballarin@27063
   218
  theorem is_inf_uniq: "\<lbrakk>is_inf x y i; is_inf x y i'\<rbrakk> \<Longrightarrow> i = i'"
ballarin@32983
   219
    proof -
ballarin@27063
   220
    assume inf: "is_inf x y i"
ballarin@27063
   221
    assume inf': "is_inf x y i'"
ballarin@27063
   222
    show ?thesis
ballarin@27063
   223
    proof (rule anti_sym)
ballarin@27063
   224
      from inf' show "i \<sqsubseteq> i'"
ballarin@27063
   225
      proof (rule is_inf_greatest)
wenzelm@32962
   226
        from inf show "i \<sqsubseteq> x" ..
wenzelm@32962
   227
        from inf show "i \<sqsubseteq> y" ..
ballarin@27063
   228
      qed
ballarin@27063
   229
      from inf show "i' \<sqsubseteq> i"
ballarin@27063
   230
      proof (rule is_inf_greatest)
wenzelm@32962
   231
        from inf' show "i' \<sqsubseteq> x" ..
wenzelm@32962
   232
        from inf' show "i' \<sqsubseteq> y" ..
ballarin@27063
   233
      qed
ballarin@27063
   234
    qed
ballarin@27063
   235
  qed
ballarin@27063
   236
ballarin@27063
   237
  theorem %invisible is_inf_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> is_inf x y x"
ballarin@27063
   238
  proof -
ballarin@27063
   239
    assume "x \<sqsubseteq> y"
ballarin@27063
   240
    show ?thesis
ballarin@27063
   241
    proof
ballarin@27063
   242
      show "x \<sqsubseteq> x" ..
ballarin@27063
   243
      show "x \<sqsubseteq> y" by fact
ballarin@27063
   244
      fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y" show "z \<sqsubseteq> x" by fact
ballarin@27063
   245
    qed
ballarin@27063
   246
  qed
ballarin@27063
   247
ballarin@27063
   248
  lemma %invisible is_supI [intro?]: "x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow>
ballarin@27063
   249
      (\<And>z. x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z) \<Longrightarrow> is_sup x y s"
ballarin@27063
   250
    by (unfold is_sup_def) blast
ballarin@27063
   251
ballarin@27063
   252
  lemma %invisible is_sup_least [elim?]:
ballarin@27063
   253
      "is_sup x y s \<Longrightarrow> x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z"
ballarin@27063
   254
    by (unfold is_sup_def) blast
ballarin@27063
   255
ballarin@27063
   256
  lemma %invisible is_sup_upper [elim?]:
ballarin@27063
   257
      "is_sup x y s \<Longrightarrow> (x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow> C) \<Longrightarrow> C"
ballarin@27063
   258
    by (unfold is_sup_def) blast
ballarin@27063
   259
ballarin@27063
   260
  theorem is_sup_uniq: "\<lbrakk>is_sup x y s; is_sup x y s'\<rbrakk> \<Longrightarrow> s = s'"
ballarin@32983
   261
    proof -
ballarin@27063
   262
    assume sup: "is_sup x y s"
ballarin@27063
   263
    assume sup': "is_sup x y s'"
ballarin@27063
   264
    show ?thesis
ballarin@27063
   265
    proof (rule anti_sym)
ballarin@27063
   266
      from sup show "s \<sqsubseteq> s'"
ballarin@27063
   267
      proof (rule is_sup_least)
wenzelm@32962
   268
        from sup' show "x \<sqsubseteq> s'" ..
wenzelm@32962
   269
        from sup' show "y \<sqsubseteq> s'" ..
ballarin@27063
   270
      qed
ballarin@27063
   271
      from sup' show "s' \<sqsubseteq> s"
ballarin@27063
   272
      proof (rule is_sup_least)
wenzelm@32962
   273
        from sup show "x \<sqsubseteq> s" ..
wenzelm@32962
   274
        from sup show "y \<sqsubseteq> s" ..
ballarin@27063
   275
      qed
ballarin@27063
   276
    qed
ballarin@27063
   277
  qed
ballarin@27063
   278
ballarin@27063
   279
  theorem %invisible is_sup_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> is_sup x y y"
ballarin@27063
   280
  proof -
ballarin@27063
   281
    assume "x \<sqsubseteq> y"
ballarin@27063
   282
    show ?thesis
ballarin@27063
   283
    proof
ballarin@27063
   284
      show "x \<sqsubseteq> y" by fact
ballarin@27063
   285
      show "y \<sqsubseteq> y" ..
ballarin@27063
   286
      fix z assume "x \<sqsubseteq> z" and "y \<sqsubseteq> z"
ballarin@27063
   287
      show "y \<sqsubseteq> z" by fact
ballarin@27063
   288
    qed
ballarin@27063
   289
  qed
ballarin@27063
   290
ballarin@27063
   291
  end
ballarin@27063
   292
ballarin@32981
   293
text {* The syntax of the locale commands discussed in this tutorial is
ballarin@32983
   294
  shown in Table~\ref{tab:commands}.  The grammar is complete with the
ballarin@32983
   295
  exception of the context elements \isakeyword{constrains} and
ballarin@32983
   296
  \isakeyword{defines}, which are provided for backward
ballarin@32983
   297
  compatibility.  See the Isabelle/Isar Reference
ballarin@32983
   298
  Manual~\cite{IsarRef} for full documentation.  *}
ballarin@27063
   299
ballarin@27063
   300
ballarin@30573
   301
section {* Import \label{sec:import} *}
ballarin@27063
   302
ballarin@27063
   303
text {* 
ballarin@27063
   304
  Algebraic structures are commonly defined by adding operations and
ballarin@27063
   305
  properties to existing structures.  For example, partial orders
ballarin@27063
   306
  are extended to lattices and total orders.  Lattices are extended to
ballarin@32981
   307
  distributive lattices. *}
ballarin@27063
   308
ballarin@32981
   309
text {*
ballarin@32981
   310
  With locales, this kind of inheritance is achieved through
ballarin@32981
   311
  \emph{import} of locales.  The import part of a locale declaration,
ballarin@32981
   312
  if present, precedes the context elements.  Here is an example,
ballarin@32981
   313
  where partial orders are extended to lattices.
ballarin@27063
   314
  *}
ballarin@27063
   315
ballarin@27063
   316
  locale lattice = partial_order +
ballarin@30573
   317
    assumes ex_inf: "\<exists>inf. is_inf x y inf"
ballarin@30573
   318
      and ex_sup: "\<exists>sup. is_sup x y sup"
ballarin@27063
   319
  begin
ballarin@27063
   320
ballarin@30573
   321
text {* These assumptions refer to the predicates for infimum
ballarin@32981
   322
  and supremum defined for @{text partial_order} in the previous
ballarin@32981
   323
  section.  We now introduce the notions of meet and join.  *}
ballarin@27063
   324
ballarin@27063
   325
  definition
ballarin@27063
   326
    meet (infixl "\<sqinter>" 70) where "x \<sqinter> y = (THE inf. is_inf x y inf)"
ballarin@27063
   327
  definition
ballarin@27063
   328
    join (infixl "\<squnion>" 65) where "x \<squnion> y = (THE sup. is_sup x y sup)"
ballarin@27063
   329
ballarin@27063
   330
  lemma %invisible meet_equality [elim?]: "is_inf x y i \<Longrightarrow> x \<sqinter> y = i"
ballarin@27063
   331
  proof (unfold meet_def)
ballarin@27063
   332
    assume "is_inf x y i"
ballarin@27063
   333
    then show "(THE i. is_inf x y i) = i"
ballarin@27063
   334
      by (rule the_equality) (rule is_inf_uniq [OF _ `is_inf x y i`])
ballarin@27063
   335
  qed
ballarin@27063
   336
ballarin@27063
   337
  lemma %invisible meetI [intro?]:
ballarin@27063
   338
      "i \<sqsubseteq> x \<Longrightarrow> i \<sqsubseteq> y \<Longrightarrow> (\<And>z. z \<sqsubseteq> x \<Longrightarrow> z \<sqsubseteq> y \<Longrightarrow> z \<sqsubseteq> i) \<Longrightarrow> x \<sqinter> y = i"
ballarin@27063
   339
    by (rule meet_equality, rule is_infI) blast+
ballarin@27063
   340
ballarin@27063
   341
  lemma %invisible is_inf_meet [intro?]: "is_inf x y (x \<sqinter> y)"
ballarin@27063
   342
  proof (unfold meet_def)
ballarin@27063
   343
    from ex_inf obtain i where "is_inf x y i" ..
ballarin@27063
   344
    then show "is_inf x y (THE i. is_inf x y i)"
ballarin@27063
   345
      by (rule theI) (rule is_inf_uniq [OF _ `is_inf x y i`])
ballarin@27063
   346
  qed
ballarin@27063
   347
ballarin@27063
   348
  lemma %invisible meet_left [intro?]:
ballarin@27063
   349
    "x \<sqinter> y \<sqsubseteq> x"
ballarin@27063
   350
    by (rule is_inf_lower) (rule is_inf_meet)
ballarin@27063
   351
ballarin@27063
   352
  lemma %invisible meet_right [intro?]:
ballarin@27063
   353
    "x \<sqinter> y \<sqsubseteq> y"
ballarin@27063
   354
    by (rule is_inf_lower) (rule is_inf_meet)
ballarin@27063
   355
ballarin@27063
   356
  lemma %invisible meet_le [intro?]:
ballarin@27063
   357
    "\<lbrakk> z \<sqsubseteq> x; z \<sqsubseteq> y \<rbrakk> \<Longrightarrow> z \<sqsubseteq> x \<sqinter> y"
ballarin@27063
   358
    by (rule is_inf_greatest) (rule is_inf_meet)
ballarin@27063
   359
ballarin@27063
   360
  lemma %invisible join_equality [elim?]: "is_sup x y s \<Longrightarrow> x \<squnion> y = s"
ballarin@27063
   361
  proof (unfold join_def)
ballarin@27063
   362
    assume "is_sup x y s"
ballarin@27063
   363
    then show "(THE s. is_sup x y s) = s"
ballarin@27063
   364
      by (rule the_equality) (rule is_sup_uniq [OF _ `is_sup x y s`])
ballarin@27063
   365
  qed
ballarin@27063
   366
ballarin@27063
   367
  lemma %invisible joinI [intro?]: "x \<sqsubseteq> s \<Longrightarrow> y \<sqsubseteq> s \<Longrightarrow>
ballarin@27063
   368
      (\<And>z. x \<sqsubseteq> z \<Longrightarrow> y \<sqsubseteq> z \<Longrightarrow> s \<sqsubseteq> z) \<Longrightarrow> x \<squnion> y = s"
ballarin@27063
   369
    by (rule join_equality, rule is_supI) blast+
ballarin@27063
   370
ballarin@27063
   371
  lemma %invisible is_sup_join [intro?]: "is_sup x y (x \<squnion> y)"
ballarin@27063
   372
  proof (unfold join_def)
ballarin@27063
   373
    from ex_sup obtain s where "is_sup x y s" ..
ballarin@27063
   374
    then show "is_sup x y (THE s. is_sup x y s)"
ballarin@27063
   375
      by (rule theI) (rule is_sup_uniq [OF _ `is_sup x y s`])
ballarin@27063
   376
  qed
ballarin@27063
   377
ballarin@27063
   378
  lemma %invisible join_left [intro?]:
ballarin@27063
   379
    "x \<sqsubseteq> x \<squnion> y"
ballarin@27063
   380
    by (rule is_sup_upper) (rule is_sup_join)
ballarin@27063
   381
ballarin@27063
   382
  lemma %invisible join_right [intro?]:
ballarin@27063
   383
    "y \<sqsubseteq> x \<squnion> y"
ballarin@27063
   384
    by (rule is_sup_upper) (rule is_sup_join)
ballarin@27063
   385
ballarin@27063
   386
  lemma %invisible join_le [intro?]:
ballarin@27063
   387
    "\<lbrakk> x \<sqsubseteq> z; y \<sqsubseteq> z \<rbrakk> \<Longrightarrow> x \<squnion> y \<sqsubseteq> z"
ballarin@27063
   388
    by (rule is_sup_least) (rule is_sup_join)
ballarin@27063
   389
ballarin@27063
   390
  theorem %invisible meet_assoc: "(x \<sqinter> y) \<sqinter> z = x \<sqinter> (y \<sqinter> z)"
ballarin@27063
   391
  proof (rule meetI)
ballarin@27063
   392
    show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x \<sqinter> y"
ballarin@27063
   393
    proof
ballarin@27063
   394
      show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> x" ..
ballarin@27063
   395
      show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y"
ballarin@27063
   396
      proof -
wenzelm@32962
   397
        have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
wenzelm@32962
   398
        also have "\<dots> \<sqsubseteq> y" ..
wenzelm@32962
   399
        finally show ?thesis .
ballarin@27063
   400
      qed
ballarin@27063
   401
    qed
ballarin@27063
   402
    show "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> z"
ballarin@27063
   403
    proof -
ballarin@27063
   404
      have "x \<sqinter> (y \<sqinter> z) \<sqsubseteq> y \<sqinter> z" ..
ballarin@27063
   405
      also have "\<dots> \<sqsubseteq> z" ..
ballarin@27063
   406
      finally show ?thesis .
ballarin@27063
   407
    qed
ballarin@27063
   408
    fix w assume "w \<sqsubseteq> x \<sqinter> y" and "w \<sqsubseteq> z"
ballarin@27063
   409
    show "w \<sqsubseteq> x \<sqinter> (y \<sqinter> z)"
ballarin@27063
   410
    proof
ballarin@27063
   411
      show "w \<sqsubseteq> x"
ballarin@27063
   412
      proof -
wenzelm@32962
   413
        have "w \<sqsubseteq> x \<sqinter> y" by fact
wenzelm@32962
   414
        also have "\<dots> \<sqsubseteq> x" ..
wenzelm@32962
   415
        finally show ?thesis .
ballarin@27063
   416
      qed
ballarin@27063
   417
      show "w \<sqsubseteq> y \<sqinter> z"
ballarin@27063
   418
      proof
wenzelm@32962
   419
        show "w \<sqsubseteq> y"
wenzelm@32962
   420
        proof -
wenzelm@32962
   421
          have "w \<sqsubseteq> x \<sqinter> y" by fact
wenzelm@32962
   422
          also have "\<dots> \<sqsubseteq> y" ..
wenzelm@32962
   423
          finally show ?thesis .
wenzelm@32962
   424
        qed
wenzelm@32962
   425
        show "w \<sqsubseteq> z" by fact
ballarin@27063
   426
      qed
ballarin@27063
   427
    qed
ballarin@27063
   428
  qed
ballarin@27063
   429
ballarin@27063
   430
  theorem %invisible meet_commute: "x \<sqinter> y = y \<sqinter> x"
ballarin@27063
   431
  proof (rule meetI)
ballarin@27063
   432
    show "y \<sqinter> x \<sqsubseteq> x" ..
ballarin@27063
   433
    show "y \<sqinter> x \<sqsubseteq> y" ..
ballarin@27063
   434
    fix z assume "z \<sqsubseteq> y" and "z \<sqsubseteq> x"
ballarin@27063
   435
    then show "z \<sqsubseteq> y \<sqinter> x" ..
ballarin@27063
   436
  qed
ballarin@27063
   437
ballarin@27063
   438
  theorem %invisible meet_join_absorb: "x \<sqinter> (x \<squnion> y) = x"
ballarin@27063
   439
  proof (rule meetI)
ballarin@27063
   440
    show "x \<sqsubseteq> x" ..
ballarin@27063
   441
    show "x \<sqsubseteq> x \<squnion> y" ..
ballarin@27063
   442
    fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> x \<squnion> y"
ballarin@27063
   443
    show "z \<sqsubseteq> x" by fact
ballarin@27063
   444
  qed
ballarin@27063
   445
ballarin@27063
   446
  theorem %invisible join_assoc: "(x \<squnion> y) \<squnion> z = x \<squnion> (y \<squnion> z)"
ballarin@27063
   447
  proof (rule joinI)
ballarin@27063
   448
    show "x \<squnion> y \<sqsubseteq> x \<squnion> (y \<squnion> z)"
ballarin@27063
   449
    proof
ballarin@27063
   450
      show "x \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
ballarin@27063
   451
      show "y \<sqsubseteq> x \<squnion> (y \<squnion> z)"
ballarin@27063
   452
      proof -
wenzelm@32962
   453
        have "y \<sqsubseteq> y \<squnion> z" ..
wenzelm@32962
   454
        also have "... \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
wenzelm@32962
   455
        finally show ?thesis .
ballarin@27063
   456
      qed
ballarin@27063
   457
    qed
ballarin@27063
   458
    show "z \<sqsubseteq> x \<squnion> (y \<squnion> z)"
ballarin@27063
   459
    proof -
ballarin@27063
   460
      have "z \<sqsubseteq> y \<squnion> z"  ..
ballarin@27063
   461
      also have "... \<sqsubseteq> x \<squnion> (y \<squnion> z)" ..
ballarin@27063
   462
      finally show ?thesis .
ballarin@27063
   463
    qed
ballarin@27063
   464
    fix w assume "x \<squnion> y \<sqsubseteq> w" and "z \<sqsubseteq> w"
ballarin@27063
   465
    show "x \<squnion> (y \<squnion> z) \<sqsubseteq> w"
ballarin@27063
   466
    proof
ballarin@27063
   467
      show "x \<sqsubseteq> w"
ballarin@27063
   468
      proof -
wenzelm@32962
   469
        have "x \<sqsubseteq> x \<squnion> y" ..
wenzelm@32962
   470
        also have "\<dots> \<sqsubseteq> w" by fact
wenzelm@32962
   471
        finally show ?thesis .
ballarin@27063
   472
      qed
ballarin@27063
   473
      show "y \<squnion> z \<sqsubseteq> w"
ballarin@27063
   474
      proof
wenzelm@32962
   475
        show "y \<sqsubseteq> w"
wenzelm@32962
   476
        proof -
wenzelm@32962
   477
          have "y \<sqsubseteq> x \<squnion> y" ..
wenzelm@32962
   478
          also have "... \<sqsubseteq> w" by fact
wenzelm@32962
   479
          finally show ?thesis .
wenzelm@32962
   480
        qed
wenzelm@32962
   481
        show "z \<sqsubseteq> w" by fact
ballarin@27063
   482
      qed
ballarin@27063
   483
    qed
ballarin@27063
   484
  qed
ballarin@27063
   485
ballarin@27063
   486
  theorem %invisible join_commute: "x \<squnion> y = y \<squnion> x"
ballarin@27063
   487
  proof (rule joinI)
ballarin@27063
   488
    show "x \<sqsubseteq> y \<squnion> x" ..
ballarin@27063
   489
    show "y \<sqsubseteq> y \<squnion> x" ..
ballarin@27063
   490
    fix z assume "y \<sqsubseteq> z" and "x \<sqsubseteq> z"
ballarin@27063
   491
    then show "y \<squnion> x \<sqsubseteq> z" ..
ballarin@27063
   492
  qed
ballarin@27063
   493
ballarin@27063
   494
  theorem %invisible join_meet_absorb: "x \<squnion> (x \<sqinter> y) = x"
ballarin@27063
   495
  proof (rule joinI)
ballarin@27063
   496
    show "x \<sqsubseteq> x" ..
ballarin@27063
   497
    show "x \<sqinter> y \<sqsubseteq> x" ..
ballarin@27063
   498
    fix z assume "x \<sqsubseteq> z" and "x \<sqinter> y \<sqsubseteq> z"
ballarin@27063
   499
    show "x \<sqsubseteq> z" by fact
ballarin@27063
   500
  qed
ballarin@27063
   501
ballarin@27063
   502
  theorem %invisible meet_idem: "x \<sqinter> x = x"
ballarin@27063
   503
  proof -
ballarin@27063
   504
    have "x \<sqinter> (x \<squnion> (x \<sqinter> x)) = x" by (rule meet_join_absorb)
ballarin@27063
   505
    also have "x \<squnion> (x \<sqinter> x) = x" by (rule join_meet_absorb)
ballarin@27063
   506
    finally show ?thesis .
ballarin@27063
   507
  qed
ballarin@27063
   508
ballarin@27063
   509
  theorem %invisible meet_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<sqinter> y = x"
ballarin@27063
   510
  proof (rule meetI)
ballarin@27063
   511
    assume "x \<sqsubseteq> y"
ballarin@27063
   512
    show "x \<sqsubseteq> x" ..
ballarin@27063
   513
    show "x \<sqsubseteq> y" by fact
ballarin@27063
   514
    fix z assume "z \<sqsubseteq> x" and "z \<sqsubseteq> y"
ballarin@27063
   515
    show "z \<sqsubseteq> x" by fact
ballarin@27063
   516
  qed
ballarin@27063
   517
ballarin@27063
   518
  theorem %invisible meet_related2 [elim?]: "y \<sqsubseteq> x \<Longrightarrow> x \<sqinter> y = y"
ballarin@27063
   519
    by (drule meet_related) (simp add: meet_commute)
ballarin@27063
   520
ballarin@27063
   521
  theorem %invisible join_related [elim?]: "x \<sqsubseteq> y \<Longrightarrow> x \<squnion> y = y"
ballarin@27063
   522
  proof (rule joinI)
ballarin@27063
   523
    assume "x \<sqsubseteq> y"
ballarin@27063
   524
    show "y \<sqsubseteq> y" ..
ballarin@27063
   525
    show "x \<sqsubseteq> y" by fact
ballarin@27063
   526
    fix z assume "x \<sqsubseteq> z" and "y \<sqsubseteq> z"
ballarin@27063
   527
    show "y \<sqsubseteq> z" by fact
ballarin@27063
   528
  qed
ballarin@27063
   529
ballarin@27063
   530
  theorem %invisible join_related2 [elim?]: "y \<sqsubseteq> x \<Longrightarrow> x \<squnion> y = x"
ballarin@27063
   531
    by (drule join_related) (simp add: join_commute)
ballarin@27063
   532
ballarin@27063
   533
  theorem %invisible meet_connection: "(x \<sqsubseteq> y) = (x \<sqinter> y = x)"
ballarin@27063
   534
  proof
ballarin@27063
   535
    assume "x \<sqsubseteq> y"
ballarin@27063
   536
    then have "is_inf x y x" ..
ballarin@27063
   537
    then show "x \<sqinter> y = x" ..
ballarin@27063
   538
  next
ballarin@27063
   539
    have "x \<sqinter> y \<sqsubseteq> y" ..
ballarin@27063
   540
    also assume "x \<sqinter> y = x"
ballarin@27063
   541
    finally show "x \<sqsubseteq> y" .
ballarin@27063
   542
  qed
ballarin@27063
   543
ballarin@27063
   544
  theorem %invisible join_connection: "(x \<sqsubseteq> y) = (x \<squnion> y = y)"
ballarin@27063
   545
  proof
ballarin@27063
   546
    assume "x \<sqsubseteq> y"
ballarin@27063
   547
    then have "is_sup x y y" ..
ballarin@27063
   548
    then show "x \<squnion> y = y" ..
ballarin@27063
   549
  next
ballarin@27063
   550
    have "x \<sqsubseteq> x \<squnion> y" ..
ballarin@27063
   551
    also assume "x \<squnion> y = y"
ballarin@27063
   552
    finally show "x \<sqsubseteq> y" .
ballarin@27063
   553
  qed
ballarin@27063
   554
ballarin@27063
   555
  theorem %invisible meet_connection2: "(x \<sqsubseteq> y) = (y \<sqinter> x = x)"
ballarin@27063
   556
    using meet_commute meet_connection by simp
ballarin@27063
   557
ballarin@27063
   558
  theorem %invisible join_connection2: "(x \<sqsubseteq> y) = (x \<squnion> y = y)"
ballarin@27063
   559
    using join_commute join_connection by simp
ballarin@27063
   560
ballarin@27063
   561
  text %invisible {* Naming according to Jacobson I, p.\ 459. *}
ballarin@27063
   562
  lemmas %invisible L1 = join_commute meet_commute
ballarin@27063
   563
  lemmas %invisible L2 = join_assoc meet_assoc
ballarin@27063
   564
  (* lemmas L3 = join_idem meet_idem *)
ballarin@27063
   565
  lemmas %invisible L4 = join_meet_absorb meet_join_absorb
ballarin@27063
   566
ballarin@27063
   567
  end
ballarin@27063
   568
ballarin@32983
   569
text {* Locales for total orders and distributive lattices follow to
ballarin@32983
   570
  establish a sufficiently rich landscape of locales for
ballarin@32981
   571
  further examples in this tutorial.  Each comes with an example
ballarin@32981
   572
  theorem. *}
ballarin@27063
   573
ballarin@27063
   574
  locale total_order = partial_order +
ballarin@27063
   575
    assumes total: "x \<sqsubseteq> y \<or> y \<sqsubseteq> x"
ballarin@27063
   576
ballarin@27063
   577
  lemma (in total_order) less_total: "x \<sqsubset> y \<or> x = y \<or> y \<sqsubset> x"
ballarin@27063
   578
    using total
ballarin@27063
   579
    by (unfold less_def) blast
ballarin@27063
   580
ballarin@27063
   581
  locale distrib_lattice = lattice +
ballarin@30573
   582
    assumes meet_distr: "x \<sqinter> (y \<squnion> z) = x \<sqinter> y \<squnion> x \<sqinter> z"
ballarin@27063
   583
ballarin@27063
   584
  lemma (in distrib_lattice) join_distr:
ballarin@27063
   585
    "x \<squnion> (y \<sqinter> z) = (x \<squnion> y) \<sqinter> (x \<squnion> z)"  (* txt {* Jacobson I, p.\ 462 *} *)
ballarin@27063
   586
    proof -
ballarin@27063
   587
    have "x \<squnion> (y \<sqinter> z) = (x \<squnion> (x \<sqinter> z)) \<squnion> (y \<sqinter> z)" by (simp add: L4)
ballarin@27063
   588
    also have "... = x \<squnion> ((x \<sqinter> z) \<squnion> (y \<sqinter> z))" by (simp add: L2)
ballarin@27063
   589
    also have "... = x \<squnion> ((x \<squnion> y) \<sqinter> z)" by (simp add: L1 meet_distr)
ballarin@27063
   590
    also have "... = ((x \<squnion> y) \<sqinter> x) \<squnion> ((x \<squnion> y) \<sqinter> z)" by (simp add: L1 L4)
ballarin@27063
   591
    also have "... = (x \<squnion> y) \<sqinter> (x \<squnion> z)" by (simp add: meet_distr)
ballarin@27063
   592
    finally show ?thesis .
ballarin@27063
   593
  qed
ballarin@27063
   594
ballarin@27063
   595
text {*
ballarin@32983
   596
  The locale hierarchy obtained through these declarations is shown in
ballarin@32981
   597
  Figure~\ref{fig:lattices}(a).
ballarin@27063
   598
ballarin@27063
   599
\begin{figure}
ballarin@27063
   600
\hrule \vspace{2ex}
ballarin@27063
   601
\begin{center}
ballarin@32983
   602
\subfigure[Declared hierarchy]{
ballarin@27063
   603
\begin{tikzpicture}
ballarin@27063
   604
  \node (po) at (0,0) {@{text partial_order}};
ballarin@27063
   605
  \node (lat) at (-1.5,-1) {@{text lattice}};
ballarin@27063
   606
  \node (dlat) at (-1.5,-2) {@{text distrib_lattice}};
ballarin@27063
   607
  \node (to) at (1.5,-1) {@{text total_order}};
ballarin@27063
   608
  \draw (po) -- (lat);
ballarin@27063
   609
  \draw (lat) -- (dlat);
ballarin@27063
   610
  \draw (po) -- (to);
ballarin@27063
   611
%  \draw[->, dashed] (lat) -- (to);
ballarin@27063
   612
\end{tikzpicture}
ballarin@27063
   613
} \\
ballarin@27063
   614
\subfigure[Total orders are lattices]{
ballarin@27063
   615
\begin{tikzpicture}
ballarin@27063
   616
  \node (po) at (0,0) {@{text partial_order}};
ballarin@27063
   617
  \node (lat) at (0,-1) {@{text lattice}};
ballarin@27063
   618
  \node (dlat) at (-1.5,-2) {@{text distrib_lattice}};
ballarin@27063
   619
  \node (to) at (1.5,-2) {@{text total_order}};
ballarin@27063
   620
  \draw (po) -- (lat);
ballarin@27063
   621
  \draw (lat) -- (dlat);
ballarin@27063
   622
  \draw (lat) -- (to);
ballarin@27063
   623
%  \draw[->, dashed] (dlat) -- (to);
ballarin@27063
   624
\end{tikzpicture}
ballarin@27063
   625
} \quad
ballarin@27063
   626
\subfigure[Total orders are distributive lattices]{
ballarin@27063
   627
\begin{tikzpicture}
ballarin@27063
   628
  \node (po) at (0,0) {@{text partial_order}};
ballarin@27063
   629
  \node (lat) at (0,-1) {@{text lattice}};
ballarin@27063
   630
  \node (dlat) at (0,-2) {@{text distrib_lattice}};
ballarin@27063
   631
  \node (to) at (0,-3) {@{text total_order}};
ballarin@27063
   632
  \draw (po) -- (lat);
ballarin@27063
   633
  \draw (lat) -- (dlat);
ballarin@27063
   634
  \draw (dlat) -- (to);
ballarin@27063
   635
\end{tikzpicture}
ballarin@27063
   636
}
ballarin@27063
   637
\end{center}
ballarin@27063
   638
\hrule
ballarin@27063
   639
\caption{Hierarchy of Lattice Locales.}
ballarin@27063
   640
\label{fig:lattices}
ballarin@27063
   641
\end{figure}
ballarin@27063
   642
  *}
ballarin@27063
   643
ballarin@30573
   644
section {* Changing the Locale Hierarchy
ballarin@30573
   645
  \label{sec:changing-the-hierarchy} *}
ballarin@27063
   646
ballarin@27063
   647
text {*
ballarin@32981
   648
  Locales enable to prove theorems abstractly, relative to
ballarin@32981
   649
  sets of assumptions.  These theorems can then be used in other
ballarin@32981
   650
  contexts where the assumptions themselves, or
ballarin@32981
   651
  instances of the assumptions, are theorems.  This form of theorem
ballarin@32981
   652
  reuse is called \emph{interpretation}.  Locales generalise
ballarin@32981
   653
  interpretation from theorems to conclusions, enabling the reuse of
ballarin@32981
   654
  definitions and other constructs that are not part of the
ballarin@32981
   655
  specifications of the locales.
ballarin@32981
   656
webertj@37078
   657
  The first form of interpretation we will consider in this tutorial
ballarin@32983
   658
  is provided by the \isakeyword{sublocale} command.  It enables to
ballarin@32981
   659
  modify the import hierarchy to reflect the \emph{logical} relation
ballarin@32981
   660
  between locales.
ballarin@32981
   661
ballarin@32981
   662
  Consider the locale hierarchy from Figure~\ref{fig:lattices}(a).
ballarin@32983
   663
  Total orders are lattices, although this is not reflected here, and
ballarin@32983
   664
  definitions, theorems and other conclusions
ballarin@32981
   665
  from @{term lattice} are not available in @{term total_order}.  To
ballarin@32981
   666
  obtain the situation in Figure~\ref{fig:lattices}(b), it is
ballarin@32981
   667
  sufficient to add the conclusions of the latter locale to the former.
ballarin@32981
   668
  The \isakeyword{sublocale} command does exactly this.
ballarin@32981
   669
  The declaration \isakeyword{sublocale} $l_1
ballarin@32981
   670
  \subseteq l_2$ causes locale $l_2$ to be \emph{interpreted} in the
ballarin@32983
   671
  context of $l_1$.  This means that all conclusions of $l_2$ are made
ballarin@32981
   672
  available in $l_1$.
ballarin@32981
   673
ballarin@32981
   674
  Of course, the change of hierarchy must be supported by a theorem
ballarin@32981
   675
  that reflects, in our example, that total orders are indeed
ballarin@32981
   676
  lattices.  Therefore the \isakeyword{sublocale} command generates a
ballarin@32981
   677
  goal, which must be discharged by the user.  This is illustrated in
ballarin@32981
   678
  the following paragraphs.  First the sublocale relation is stated.
ballarin@32981
   679
*}
ballarin@27063
   680
ballarin@29566
   681
  sublocale %visible total_order \<subseteq> lattice
ballarin@27063
   682
ballarin@32981
   683
txt {* \normalsize
ballarin@32981
   684
  This enters the context of locale @{text total_order}, in
ballarin@32981
   685
  which the goal @{subgoals [display]} must be shown.
ballarin@32981
   686
  Now the
ballarin@32981
   687
  locale predicate needs to be unfolded --- for example, using its
ballarin@27063
   688
  definition or by introduction rules
ballarin@32983
   689
  provided by the locale package.  For automation, the locale package
ballarin@32983
   690
  provides the methods @{text intro_locales} and @{text
ballarin@32983
   691
  unfold_locales}.  They are aware of the
ballarin@27063
   692
  current context and dependencies between locales and automatically
ballarin@27063
   693
  discharge goals implied by these.  While @{text unfold_locales}
ballarin@27063
   694
  always unfolds locale predicates to assumptions, @{text
ballarin@27063
   695
  intro_locales} only unfolds definitions along the locale
ballarin@27063
   696
  hierarchy, leaving a goal consisting of predicates defined by the
ballarin@27063
   697
  locale package.  Occasionally the latter is of advantage since the goal
ballarin@27063
   698
  is smaller.
ballarin@27063
   699
ballarin@27063
   700
  For the current goal, we would like to get hold of
ballarin@32981
   701
  the assumptions of @{text lattice}, which need to be shown, hence
ballarin@32981
   702
  @{text unfold_locales} is appropriate. *}
ballarin@27063
   703
ballarin@27063
   704
  proof unfold_locales
ballarin@27063
   705
ballarin@32981
   706
txt {* \normalsize
ballarin@32981
   707
  Since the fact that both lattices and total orders are partial
ballarin@32981
   708
  orders is already reflected in the locale hierarchy, the assumptions
ballarin@32981
   709
  of @{text partial_order} are discharged automatically, and only the
ballarin@32981
   710
  assumptions introduced in @{text lattice} remain as subgoals
ballarin@32981
   711
  @{subgoals [display]}
ballarin@32981
   712
  The proof for the first subgoal is obtained by constructing an
ballarin@32981
   713
  infimum, whose existence is implied by totality. *}
ballarin@27063
   714
ballarin@27063
   715
    fix x y
ballarin@27063
   716
    from total have "is_inf x y (if x \<sqsubseteq> y then x else y)"
ballarin@27063
   717
      by (auto simp: is_inf_def)
ballarin@27063
   718
    then show "\<exists>inf. is_inf x y inf" ..
ballarin@32981
   719
txt {* \normalsize
ballarin@32981
   720
   The proof for the second subgoal is analogous and not
ballarin@27063
   721
  reproduced here. *}
ballarin@27063
   722
  next %invisible
ballarin@27063
   723
    fix x y
ballarin@27063
   724
    from total have "is_sup x y (if x \<sqsubseteq> y then y else x)"
ballarin@27063
   725
      by (auto simp: is_sup_def)
ballarin@27063
   726
    then show "\<exists>sup. is_sup x y sup" .. qed %visible
ballarin@27063
   727
ballarin@32983
   728
text {* Similarly, we may establish that total orders are distributive
ballarin@32981
   729
  lattices with a second \isakeyword{sublocale} statement. *}
ballarin@27063
   730
ballarin@29566
   731
  sublocale total_order \<subseteq> distrib_lattice
ballarin@32983
   732
    proof unfold_locales
ballarin@27063
   733
    fix %"proof" x y z
ballarin@27063
   734
    show "x \<sqinter> (y \<squnion> z) = x \<sqinter> y \<squnion> x \<sqinter> z" (is "?l = ?r")
ballarin@27063
   735
      txt {* Jacobson I, p.\ 462 *}
ballarin@27063
   736
    proof -
ballarin@27063
   737
      { assume c: "y \<sqsubseteq> x" "z \<sqsubseteq> x"
wenzelm@32962
   738
        from c have "?l = y \<squnion> z"
wenzelm@32962
   739
          by (metis c join_connection2 join_related2 meet_related2 total)
wenzelm@32962
   740
        also from c have "... = ?r" by (metis meet_related2)
wenzelm@32962
   741
        finally have "?l = ?r" . }
ballarin@27063
   742
      moreover
ballarin@27063
   743
      { assume c: "x \<sqsubseteq> y \<or> x \<sqsubseteq> z"
wenzelm@32962
   744
        from c have "?l = x"
wenzelm@32962
   745
          by (metis join_connection2 join_related2 meet_connection total trans)
wenzelm@32962
   746
        also from c have "... = ?r"
wenzelm@32962
   747
          by (metis join_commute join_related2 meet_connection meet_related2 total)
wenzelm@32962
   748
        finally have "?l = ?r" . }
ballarin@27063
   749
      moreover note total
ballarin@27063
   750
      ultimately show ?thesis by blast
ballarin@27063
   751
    qed
ballarin@27063
   752
  qed
ballarin@27063
   753
ballarin@32981
   754
text {* The locale hierarchy is now as shown in
ballarin@32981
   755
  Figure~\ref{fig:lattices}(c). *}
ballarin@32981
   756
ballarin@32981
   757
text {*
ballarin@32981
   758
  Locale interpretation is \emph{dynamic}.  The statement
ballarin@32981
   759
  \isakeyword{sublocale} $l_1 \subseteq l_2$ will not just add the
ballarin@32981
   760
  current conclusions of $l_2$ to $l_1$.  Rather the dependency is
ballarin@32981
   761
  stored, and conclusions that will be
ballarin@32981
   762
  added to $l_2$ in future are automatically propagated to $l_1$.
ballarin@32981
   763
  The sublocale relation is transitive --- that is, propagation takes
ballarin@32981
   764
  effect along chains of sublocales.  Even cycles in the sublocale relation are
ballarin@32981
   765
  supported, as long as these cycles do not lead to infinite chains.
ballarin@32983
   766
  Details are discussed in the technical report \cite{Ballarin2006a}.
ballarin@32983
   767
  See also Section~\ref{sec:infinite-chains} of this tutorial.  *}
ballarin@27063
   768
ballarin@27063
   769
end