(* text {* The following presentation will use notation of Isabelle's meta logic, hence a few sentences to explain this. The logical primitives are universal quantification (@{text "∧"}), entailment (@{text "==>"}) and equality (@{text "≡"}). Variables (not bound variables) are sometimes preceded by a question mark. The logic is typed. Type variables are denoted by~@{text "'a"},~@{text "'b"} etc., and~@{text "==>"} is the function type. Double brackets~@{text "["} and~@{text "]"} are used to abbreviate nested entailment. *} *)
section‹Introduction›
text‹ Locales are based on contexts. A \emph{context} can be seen as a formula schema \[ ‹∧x🪙1…x🪙n. [ A🪙1; … ;A🪙m ]==>…› \] where the variables~‹x🪙1›,\ldots,~‹x🪙n› are called \emph{parameters} and the premises $‹A🪙1›,\ldots,~‹A🪙m›$ \emph{assumptions}. A formula~‹C› is a \emph{theorem} in the context if it is a conclusion \[ ‹∧x🪙1…x🪙n. [ A🪙1; … ;A🪙m ]==> C›. \] Isabelle/Isar's notion of context goes beyond this logical view. Its contexts record, in a consecutive order, proved conclusions along with \emph{attributes}, which can provide context specific configuration information for proof procedures and concrete syntax. From a logical perspective, locales are just contexts that have been made persistent. To the user, though, they provide powerful means for declaring and combining contexts, and for the reuse of theorems proved in these contexts. ›
section‹Simple Locales›
text‹ In its simplest form, a \emph{locale declaration} consists of a sequence of context elements declaring parameters (keyword \isakeyword{fixes}) and assumptions (keyword \isakeyword{assumes}). The following is the specification of partial orders, as locale ‹partial_order›. ›
locale partial_order = fixes le :: "'a ==> 'a ==> bool" (infixl‹⊑› 50) assumes refl [intro, simp]: "x ⊑ x" and anti_sym [intro]: "[ x ⊑ y; y ⊑ x ]==> x = y" and trans [trans]: "[ x ⊑ y; y ⊑ z ]==> x ⊑ z"
text (in partial_order) ‹The parameter of this locale is~‹le›, which is a binary predicate with infix syntax~‹⊑›. The parameter syntax is available in the subsequent assumptions, which are the familiar partial order axioms. Isabelle recognises unbound names as free variables. In locale assumptions, these are implicitly universally quantified. That is, 🍋‹[ x ⊑ y; y ⊑ z ]==> x ⊑ z›in fact means 🍋‹∧x y z. [ x ⊑ y; y ⊑ z ]==> x ⊑ z›. Two commands are provided to inspect locales: \isakeyword{print\_locales} lists the names of all locales of the current theory; \isakeyword{print\_locale}~$n$ prints the parameters and assumptions of locale $n$; the variation \isakeyword{print\_locale!}~$n$ additionally outputs the conclusions that are stored in the locale. We may inspect the new locale by issuing \isakeyword{print\_locale!} 🍋‹partial_order›. The output is the following list of context elements. \begin{small} \begin{alltt} \isakeyword{fixes} le :: "'a \(\Rightarrow\) 'a \(\Rightarrow\) bool" (\isakeyword{infixl} "\(\sqsubseteq\)" 50) \isakeyword{assumes} "partial_order (\(\sqsubseteq\))" \isakeyword{notes} assumption refl [intro, simp] = `?x \(\sqsubseteq\) ?x` \isakeyword{and} anti_sym [intro] = `\(\isasymlbrakk\)?x \(\sqsubseteq\) ?y; ?y \(\sqsubseteq\) ?x\(\isasymrbrakk\)\(\Longrightarrow\) ?x = ?y` \isakeyword{and} trans [trans] = `\(\isasymlbrakk\)?x \(\sqsubseteq\) ?y; ?y \(\sqsubseteq\)?z\(\isasymrbrakk\)\(\Longrightarrow\) ?x \(\sqsubseteq\) ?z` \end{alltt} \end{small} This differs from the declaration. The assumptions have turned into conclusions, denoted by the keyword \isakeyword{notes}. Also, there is only one assumption, namely 🍋‹partial_order le›. The locale declaration has introduced the predicate 🍋‹partial_order›to the theory. This predicate is the \emph{locale predicate}. Its definition may be inspected by issuing \isakeyword{thm} @{thm [source] partial_order_def}. @{thm [display, indent=2] partial_order_def} In our example, this is a unary predicate over the parameter of the locale. It is equivalent to the original assumptions, which have been turned into conclusions and are available as theorems in the context of the locale. The names and attributes from the locale declaration are associated to these theorems and are effective in the context of the locale. Each conclusion has a \emph{foundational theorem} as counterpart in the theory. Technically, this is simply the theorem composed of context and conclusion. For the transitivity theorem, this is @{thm [source] partial_order.trans}: @{thm [display, indent=2] partial_order.trans} ›
subsection‹Targets: Extending Locales›
text‹ The specification of a locale is fixed, but its list of conclusions may be extended through Isar commands that take a \emph{target} argument. In the following, \isakeyword{definition} and \isakeyword{theorem} are illustrated. Table~\ref{tab:commands-with-target} lists Isar commands that accept a target. Isar provides various ways of specifying the target. A target for a single command may be indicated with keyword \isakeyword{in} in the following way: \begin{table} \hrule \vspace{2ex} \begin{center} \begin{tabular}{ll} \isakeyword{definition} & definition through an equation \\ \isakeyword{inductive} & inductive definition \\ \isakeyword{primrec} & primitive recursion \\ \isakeyword{fun}, \isakeyword{function} & general recursion \\ \isakeyword{abbreviation} & syntactic abbreviation \\ \isakeyword{theorem}, etc.\ & theorem statement with proof \\ \isakeyword{theorems}, etc.\ & redeclaration of theorems \\ \isakeyword{text}, etc.\ & document markup \end{tabular} \end{center} \hrule \caption{Isar commands that accept a target.} \label{tab:commands-with-target} \end{table} ›
definition (in partial_order)
less :: "'a ==> 'a ==> bool" (infixl‹⊏› 50) where"(x ⊏ y) = (x ⊑ y ∧ x ≠ y)"
text (in partial_order) ‹The strict order ‹less›with infix syntax~‹⊏›is defined in terms of the locale parameter~‹le›and the general equality of the object logic we work in. The definition generates a \emph{foundational constant} 🍋‹partial_order.less›with definition @{thm [source] partial_order.less_def}: @{thm [display, indent=2] partial_order.less_def} At the same time, the locale is extended by syntax transformations hiding this construction in the context of the locale. Here, the abbreviation ‹less›is available for ‹partial_order.less le›, and it is printed and parsed as infix~‹⊏›. Finally, the conclusion @{thm [source] less_def} is added to the locale: @{thm [display, indent=2] less_def} ›
text‹The treatment of theorem statements is more straightforward. As an example, here is the derivation of a transitivity law for the strict order relation.›
lemma (in partial_order) less_le_trans [trans]: "[ x ⊏ y; y ⊑ z ]==> x ⊏ z" unfolding %visible less_def by %visible (blast intro: trans)
text‹In the context of the proof, conclusions of the locale may be used like theorems. Attributes are effective: ‹anti_sym›was declared as introduction rule, hence it is in the context's set of rules used by the classical reasoner by default.›
subsection‹Context Blocks›
text‹When working with locales, sequences of commands with the same target are frequent. A block of commands, delimited by \isakeyword{begin} and \isakeyword{end}, makes a theory-like style of working possible. All commands inside the block refer to the same target. A block may immediately follow a locale declaration, which makes that locale the target. Alternatively the target for a block may be given with the \isakeyword{context} command. This style of working is illustrated in the block below, where notions of infimum and supremum for partial orders are introduced, together with theorems about their uniqueness.›
context partial_order begin
definition
is_inf where"is_inf x y i = (i ⊑ x ∧ i ⊑ y ∧ (∀z. z ⊑ x ∧ z ⊑ y ⟶ z ⊑ i))"
definition
is_sup where"is_sup x y s = (x ⊑ s ∧ y ⊑ s ∧ (∀z. x ⊑ z ∧ y ⊑ z ⟶ s ⊑ z))"
lemma %invisible is_infI [intro?]: "i ⊑ x ==> i ⊑ y ==> (∧z. z ⊑ x ==> z ⊑ y ==> z ⊑ i) ==> is_inf x y i" by (unfold is_inf_def) blast
lemma %invisible is_inf_lower [elim?]: "is_inf x y i ==> (i ⊑ x ==> i ⊑ y ==> C) ==> C" by (unfold is_inf_def) blast
lemma %invisible is_inf_greatest [elim?]: "is_inf x y i ==> z ⊑ x ==> z ⊑ y ==> z ⊑ i" by (unfold is_inf_def) blast
theorem is_inf_uniq: "[is_inf x y i; is_inf x y i']==> i = i'" proof - assume inf: "is_inf x y i" assume inf': "is_inf x y i'" show ?thesis proof (rule anti_sym) from inf' show"i ⊑ i'" proof (rule is_inf_greatest) from inf show"i ⊑ x" .. from inf show"i ⊑ y" .. qed from inf show"i' ⊑ i" proof (rule is_inf_greatest) from inf' show"i' ⊑ x" .. from inf' show"i' ⊑ y" .. qed qed qed
theorem %invisible is_inf_related [elim?]: "x ⊑ y ==> is_inf x y x" proof - assume"x ⊑ y" show ?thesis proof show"x ⊑ x" .. show"x ⊑ y"by fact fix z assume"z ⊑ x"and"z ⊑ y"show"z ⊑ x"by fact qed qed
lemma %invisible is_supI [intro?]: "x ⊑ s ==> y ⊑ s ==> (∧z. x ⊑ z ==> y ⊑ z ==> s ⊑ z) ==> is_sup x y s" by (unfold is_sup_def) blast
lemma %invisible is_sup_least [elim?]: "is_sup x y s ==> x ⊑ z ==> y ⊑ z ==> s ⊑ z" by (unfold is_sup_def) blast
lemma %invisible is_sup_upper [elim?]: "is_sup x y s ==> (x ⊑ s ==> y ⊑ s ==> C) ==> C" by (unfold is_sup_def) blast
theorem is_sup_uniq: "[is_sup x y s; is_sup x y s']==> s = s'" proof - assume sup: "is_sup x y s" assume sup': "is_sup x y s'" show ?thesis proof (rule anti_sym) from sup show"s ⊑ s'" proof (rule is_sup_least) from sup' show"x ⊑ s'" .. from sup' show"y ⊑ s'" .. qed from sup' show"s' ⊑ s" proof (rule is_sup_least) from sup show"x ⊑ s" .. from sup show"y ⊑ s" .. qed qed qed
theorem %invisible is_sup_related [elim?]: "x ⊑ y ==> is_sup x y y" proof - assume"x ⊑ y" show ?thesis proof show"x ⊑ y"by fact show"y ⊑ y" .. fix z assume"x ⊑ z"and"y ⊑ z" show"y ⊑ z"by fact qed qed
end
text‹The syntax of the locale commands discussed in this tutorial is shown in Table~\ref{tab:commands}. The grammar is complete with the exception of the context elements \isakeyword{constrains} and \isakeyword{defines}, which are provided for backward compatibility. See the Isabelle/Isar Reference Manual 🍋‹IsarRef›for full documentation.›
section‹Import \label{sec:import}›
text‹ Algebraic structures are commonly defined by adding operations and properties to existing structures. For example, partial orders are extended to lattices and total orders. Lattices are extended to distributive lattices.›
text‹ With locales, this kind of inheritance is achieved through \emph{import} of locales. The import part of a locale declaration, if present, precedes the context elements. Here is an example, where partial orders are extended to lattices. ›
locale lattice = partial_order + assumes ex_inf: "∃inf. is_inf x y inf" and ex_sup: "∃sup. is_sup x y sup" begin
text‹These assumptions refer to the predicates for infimum and supremum defined for ‹partial_order›in the previous section. We now introduce the notions of meet and join, together with an example theorem.›
definition
meet (infixl‹⊓› 70) where"x ⊓ y = (THE inf. is_inf x y inf)" definition
join (infixl‹⊔› 65) where"x ⊔ y = (THE sup. is_sup x y sup)"
lemma %invisible meet_equality [elim?]: "is_inf x y i ==> x ⊓ y = i" proof (unfold meet_def) assume"is_inf x y i" thenshow"(THE i. is_inf x y i) = i" by (rule the_equality) (rule is_inf_uniq [OF _ ‹is_inf x y i›]) qed
lemma %invisible meetI [intro?]: "i ⊑ x ==> i ⊑ y ==> (∧z. z ⊑ x ==> z ⊑ y ==> z ⊑ i) ==> x ⊓ y = i" by (rule meet_equality, rule is_infI) blast+
lemma %invisible is_inf_meet [intro?]: "is_inf x y (x ⊓ y)" proof (unfold meet_def) from ex_inf obtain i where"is_inf x y i" .. thenshow"is_inf x y (THE i. is_inf x y i)" by (rule theI) (rule is_inf_uniq [OF _ ‹is_inf x y i›]) qed
lemma meet_left(*<*)[intro?](*>*): "x \<sqinter> y \<sqsubseteq> x" by (rule is_inf_lower) (rule is_inf_meet)
lemma %invisible meet_right [intro?]: "x ⊓ y ⊑ y" by (rule is_inf_lower) (rule is_inf_meet)
lemma %invisible meet_le [intro?]: "[ z ⊑ x; z ⊑ y ]==> z ⊑ x ⊓ y" by (rule is_inf_greatest) (rule is_inf_meet)
lemma %invisible join_equality [elim?]: "is_sup x y s ==> x ⊔ y = s" proof (unfold join_def) assume"is_sup x y s" thenshow"(THE s. is_sup x y s) = s" by (rule the_equality) (rule is_sup_uniq [OF _ ‹is_sup x y s›]) qed
lemma %invisible joinI [intro?]: "x ⊑ s ==> y ⊑ s ==> (∧z. x ⊑ z ==> y ⊑ z ==> s ⊑ z) ==> x ⊔ y = s" by (rule join_equality, rule is_supI) blast+
lemma %invisible is_sup_join [intro?]: "is_sup x y (x ⊔ y)" proof (unfold join_def) from ex_sup obtain s where"is_sup x y s" .. thenshow"is_sup x y (THE s. is_sup x y s)" by (rule theI) (rule is_sup_uniq [OF _ ‹is_sup x y s›]) qed
lemma %invisible join_left [intro?]: "x ⊑ x ⊔ y" by (rule is_sup_upper) (rule is_sup_join)
lemma %invisible join_right [intro?]: "y ⊑ x ⊔ y" by (rule is_sup_upper) (rule is_sup_join)
lemma %invisible join_le [intro?]: "[ x ⊑ z; y ⊑ z ]==> x ⊔ y ⊑ z" by (rule is_sup_least) (rule is_sup_join)
theorem %invisible meet_assoc: "(x ⊓ y) ⊓ z = x ⊓ (y ⊓ z)" proof (rule meetI) show"x ⊓ (y ⊓ z) ⊑ x ⊓ y" proof show"x ⊓ (y ⊓ z) ⊑ x" .. show"x ⊓ (y ⊓ z) ⊑ y" proof - have"x ⊓ (y ⊓ z) ⊑ y ⊓ z" .. alsohave"…⊑ y" .. finallyshow ?thesis . qed qed show"x ⊓ (y ⊓ z) ⊑ z" proof - have"x ⊓ (y ⊓ z) ⊑ y ⊓ z" .. alsohave"…⊑ z" .. finallyshow ?thesis . qed fix w assume"w ⊑ x ⊓ y"and"w ⊑ z" show"w ⊑ x ⊓ (y ⊓ z)" proof show"w ⊑ x" proof - have"w ⊑ x ⊓ y"by fact alsohave"…⊑ x" .. finallyshow ?thesis . qed show"w ⊑ y ⊓ z" proof show"w ⊑ y" proof - have"w ⊑ x ⊓ y"by fact alsohave"…⊑ y" .. finallyshow ?thesis . qed show"w ⊑ z"by fact qed qed qed
theorem %invisible meet_commute: "x ⊓ y = y ⊓ x" proof (rule meetI) show"y ⊓ x ⊑ x" .. show"y ⊓ x ⊑ y" .. fix z assume"z ⊑ y"and"z ⊑ x" thenshow"z ⊑ y ⊓ x" .. qed
theorem %invisible meet_join_absorb: "x ⊓ (x ⊔ y) = x" proof (rule meetI) show"x ⊑ x" .. show"x ⊑ x ⊔ y" .. fix z assume"z ⊑ x"and"z ⊑ x ⊔ y" show"z ⊑ x"by fact qed
theorem %invisible join_assoc: "(x ⊔ y) ⊔ z = x ⊔ (y ⊔ z)" proof (rule joinI) show"x ⊔ y ⊑ x ⊔ (y ⊔ z)" proof show"x ⊑ x ⊔ (y ⊔ z)" .. show"y ⊑ x ⊔ (y ⊔ z)" proof - have"y ⊑ y ⊔ z" .. alsohave"... ⊑ x ⊔ (y ⊔ z)" .. finallyshow ?thesis . qed qed show"z ⊑ x ⊔ (y ⊔ z)" proof - have"z ⊑ y ⊔ z" .. alsohave"... ⊑ x ⊔ (y ⊔ z)" .. finallyshow ?thesis . qed fix w assume"x ⊔ y ⊑ w"and"z ⊑ w" show"x ⊔ (y ⊔ z) ⊑ w" proof show"x ⊑ w" proof - have"x ⊑ x ⊔ y" .. alsohave"…⊑ w"by fact finallyshow ?thesis . qed show"y ⊔ z ⊑ w" proof show"y ⊑ w" proof - have"y ⊑ x ⊔ y" .. alsohave"... ⊑ w"by fact finallyshow ?thesis . qed show"z ⊑ w"by fact qed qed qed
theorem %invisible join_commute: "x ⊔ y = y ⊔ x" proof (rule joinI) show"x ⊑ y ⊔ x" .. show"y ⊑ y ⊔ x" .. fix z assume"y ⊑ z"and"x ⊑ z" thenshow"y ⊔ x ⊑ z" .. qed
theorem %invisible join_meet_absorb: "x ⊔ (x ⊓ y) = x" proof (rule joinI) show"x ⊑ x" .. show"x ⊓ y ⊑ x" .. fix z assume"x ⊑ z"and"x ⊓ y ⊑ z" show"x ⊑ z"by fact qed
theorem %invisible meet_related [elim?]: "x ⊑ y ==> x ⊓ y = x" proof (rule meetI) assume"x ⊑ y" show"x ⊑ x" .. show"x ⊑ y"by fact fix z assume"z ⊑ x"and"z ⊑ y" show"z ⊑ x"by fact qed
theorem %invisible meet_related2 [elim?]: "y ⊑ x ==> x ⊓ y = y" by (drule meet_related) (simp add: meet_commute)
theorem %invisible join_related [elim?]: "x ⊑ y ==> x ⊔ y = y" proof (rule joinI) assume"x ⊑ y" show"y ⊑ y" .. show"x ⊑ y"by fact fix z assume"x ⊑ z"and"y ⊑ z" show"y ⊑ z"by fact qed
theorem %invisible join_related2 [elim?]: "y ⊑ x ==> x ⊔ y = x" by (drule join_related) (simp add: join_commute)
theorem %invisible meet_connection: "(x ⊑ y) = (x ⊓ y = x)" proof assume"x ⊑ y" thenhave"is_inf x y x" .. thenshow"x ⊓ y = x" .. next have"x ⊓ y ⊑ y" .. alsoassume"x ⊓ y = x" finallyshow"x ⊑ y" . qed
theorem %invisible join_connection: "(x ⊑ y) = (x ⊔ y = y)" proof assume"x ⊑ y" thenhave"is_sup x y y" .. thenshow"x ⊔ y = y" .. next have"x ⊑ x ⊔ y" .. alsoassume"x ⊔ y = y" finallyshow"x ⊑ y" . qed
theorem %invisible meet_connection2: "(x ⊑ y) = (y ⊓ x = x)" using meet_commute meet_connection by simp
theorem %invisible join_connection2: "(x ⊑ y) = (x ⊔ y = y)" using join_commute join_connection by simp
text %invisible ‹Naming according to Jacobson I, p.\ 459.› lemmas %invisible L1 = join_commute meet_commute lemmas %invisible L2 = join_assoc meet_assoc (* lemmas L3 = join_idem meet_idem *) lemmas %invisible L4 = join_meet_absorb meet_join_absorb
end
text‹Locales for total orders and distributive lattices follow to establish a sufficiently rich landscape of locales for further examples in this tutorial.›
locale total_order = partial_order + assumes total: "x ⊑ y ∨ y ⊑ x"
lemma (in total_order) less_total: "x ⊏ y ∨ x = y ∨ y ⊏ x" using total by (unfold less_def) blast
locale distrib_lattice = lattice + assumes meet_distr: "x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z"
text‹ The locale hierarchy obtained through these declarations is shown in Figure~\ref{fig:lattices}(a). \begin{figure} \hrule\vspace{2ex} \begin{center} \subfigure[Declared hierarchy]{ \begin{tikzpicture} \node (po) at (0,0) {‹partial_order›}; \node (lat) at (-1.5,-1) {‹lattice›}; \node (dlat) at (-1.5,-2) {‹distrib_lattice›}; \node (to) at (1.5,-1) {‹total_order›}; \draw (po) -- (lat); \draw (lat) -- (dlat); \draw (po) -- (to);
% \draw[->, dashed] (lat) -- (to); \end{tikzpicture}
} java.lang.NullPointerException \subfigure[Total orders are lattices]{ \begin{tikzpicture} \node (po) at (0,0) {‹partial_order›}; \node (lat) at (0,-1) {‹lattice›}; \node (dlat) at (-1.5,-2) {‹distrib_lattice›}; \node (to) at (1.5,-2) {‹total_order›}; \draw (po) -- (lat); \draw (lat) -- (dlat); \draw (lat) -- (to);
% \draw[->, dashed] (dlat) -- (to); \end{tikzpicture}
} \quad \subfigure[Total orders are distributive lattices]{ \begin{tikzpicture} \node (po) at (0,0) {‹partial_order›}; \node (lat) at (0,-1) {‹lattice›}; \node (dlat) at (0,-2) {‹distrib_lattice›}; \node (to) at (0,-3) {‹total_order›}; \draw (po) -- (lat); \draw (lat) -- (dlat); \draw (dlat) -- (to); \end{tikzpicture}
} \end{center} \hrule \caption{Hierarchy of Lattice Locales.} \label{fig:lattices} \end{figure} ›
section‹Changing the Locale Hierarchy \label{sec:changing-the-hierarchy}›
text‹ Locales enable to prove theorems abstractly, relative to sets of assumptions. These theorems can then be used in other contexts where the assumptions themselves, or instances of the assumptions, are theorems. This form of theorem reuse is called \emph{interpretation}. Locales generalise interpretation from theorems to conclusions, enabling the reuse of definitions and other constructs that are not part of the specifications of the locales. The first form of interpretation we will consider in this tutorial is provided by the \isakeyword{sublocale} command. It enables to modify the import hierarchy to reflect the \emph{logical} relation between locales. Consider the locale hierarchy from Figure~\ref{fig:lattices}(a). Total orders are lattices, although this is not reflected here, and definitions, theorems and other conclusions from 🍋‹lattice› a obtain the situation in Figure~\ref{fig:lattices}(b), it is
sufficient to add the conclusions of the latter localeto the former.
The \isakeyword{sublocale} command does exactly this.
The declaration\isakeyword{sublocale} $l_1 \subseteq l_2$ causes locale $l_2$ to be \emph{interpreted} in the context of $l_1$. This means that all conclusions of $l_2$ are made
available in $l_1$.
Of course, the change of hierarchy must be supported by a theorem
that reflects, in our example, that total orders are indeed
lattices. Therefore the \isakeyword{sublocale} command generates a
goal, which must be discharged by the user. This is illustrated in
the following paragraphs. First the sublocale relation is stated. ›
sublocale %visible total_order ⊆ lattice
txt‹\normalsize This enters the context of locale ‹total_order›,
which the goal @{subgoals [display]} must be shown.
Now the locale predicate needs to be unfolded --- for example, using its definition or by introduction rules
provided by the locale package. For automation, the locale package
provides the methods ‹intro_locales›and‹unfold_locales›. They are aware of the
current contextand dependencies between locales and automatically
discharge goals implied by these. While ‹unfold_locales›
always unfolds locale predicates to assumptions, ‹intro_locales› only unfolds definitions along the locale
hierarchy, leaving a goal consisting of predicates defined by the locale package. Occasionally the latter is of advantage since the goal is smaller.
For the current goal, we would like to get hold of
the assumptions of ‹lattice›, which need to be shown, hence ‹unfold_locales›is appropriate.›
proof unfold_locales
txt‹\normalsize Since the fact that both lattices and total orders are partial orders is already reflected in the locale hierarchy, the assumptions of ‹partial_order› a
assumptions introduced in‹lattice› remain as subgoals
@{subgoals [display]}
The prooffor the first subgoal is obtained by constructing an
infimum, whose existence is implied by totality.›
fix x y from total have"is_inf x y (if x ⊑ y then x else y)" by (auto simp: is_inf_def) thenshow"∃inf. is_inf x y inf" .. txt‹\normalsize The proof for the second subgoal is analogous and not reproduced here.› next %invisible fix x y from total have"is_sup x y (if x ⊑ y then y else x)" by (auto simp: is_sup_def) thenshow"∃sup. is_sup x y sup" .. qed %visible
text‹Similarly, we may establish that total orders are distributive lattices with a second \isakeyword{sublocale} statement.›
sublocale total_order ⊆ distrib_lattice proof unfold_locales fix %"proof" x y z show"x ⊓ (y ⊔ z) = x ⊓ y ⊔ x ⊓ z" (is"?l = ?r") txt‹Jacobson I, p.\ 462› proof -
{ assume c: "y ⊑ x""z ⊑ x" from c have"?l = y ⊔ z" by (metis c join_connection2 join_related2 meet_related2 total) alsofrom c have"... = ?r"by (metis meet_related2) finallyhave"?l = ?r" . } moreover
{ assume c: "x ⊑ y ∨ x ⊑ z" from c have"?l = x" by (metis join_connection2 join_related2 meet_connection total trans) alsofrom c have"... = ?r" by (metis join_commute join_related2 meet_connection meet_related2 total) finallyhave"?l = ?r" . } moreovernote total ultimatelyshow ?thesis by blast qed qed
text‹The locale hierarchy is now as shown in Figure~\ref{fig:lattices}(c).›
text‹ Locale interpretation is \emph{dynamic}. The statement \isakeyword{sublocale} $l_1 \subseteq l_2$ will not just add the current conclusions of $l_2$ to $l_1$. Rather the dependency is stored, and conclusions that will be added to $l_2$ in future are automatically propagated to $l_1$. The sublocale relation is transitive --- that is, propagation takes effect along chains of sublocales. Even cycles in the sublocale relation are supported, as long as these cycles do not lead to infinite chains. Details are discussed in the technical report 🍋‹Ballarin2006a›.
See alsoSection~\ref{sec:infinite-chains} of this tutorial.›
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet am 2026-05-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.