Adapted text to new theory header syntax.
3 \def\isabellecontext{ToyList}%
4 \isacommand{theory}\ ToyList\isanewline
5 \isakeyword{import}\ PreList\isanewline
6 \isakeyword{begin}\isamarkupfalse%
10 HOL already has a predefined theory of lists called \isa{List} ---
11 \isa{ToyList} is merely a small fragment of it chosen as an example. In
12 contrast to what is recommended in \S\ref{sec:Basic:Theories},
13 \isa{ToyList} is not based on \isa{Main} but on \isa{PreList}, a
14 theory that contains pretty much everything but lists, thus avoiding
15 ambiguities caused by defining lists twice.%
18 \isacommand{datatype}\ {\isacharprime}a\ list\ {\isacharequal}\ Nil\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharparenleft}{\isachardoublequote}{\isacharbrackleft}{\isacharbrackright}{\isachardoublequote}{\isacharparenright}\isanewline
19 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ {\isacharbar}\ Cons\ {\isacharprime}a\ {\isachardoublequote}{\isacharprime}a\ list{\isachardoublequote}\ \ \ \ \ \ \ \ \ \ \ \ {\isacharparenleft}\isakeyword{infixr}\ {\isachardoublequote}{\isacharhash}{\isachardoublequote}\ {\isadigit{6}}{\isadigit{5}}{\isacharparenright}\isamarkupfalse%
21 \begin{isamarkuptext}%
23 The datatype\index{datatype@\isacommand {datatype} (command)}
24 \tydx{list} introduces two
25 constructors \cdx{Nil} and \cdx{Cons}, the
26 empty~list and the operator that adds an element to the front of a list. For
27 example, the term \isa{Cons True (Cons False Nil)} is a value of
28 type \isa{bool\ list}, namely the list with the elements \isa{True} and
29 \isa{False}. Because this notation quickly becomes unwieldy, the
30 datatype declaration is annotated with an alternative syntax: instead of
31 \isa{Nil} and \isa{Cons x xs} we can write
32 \isa{{\isacharbrackleft}{\isacharbrackright}}\index{$HOL2list@\texttt{[]}|bold} and
33 \isa{x\ {\isacharhash}\ xs}\index{$HOL2list@\texttt{\#}|bold}. In fact, this
34 alternative syntax is the familiar one. Thus the list \isa{Cons True
35 (Cons False Nil)} becomes \isa{True\ {\isacharhash}\ False\ {\isacharhash}\ {\isacharbrackleft}{\isacharbrackright}}. The annotation
36 \isacommand{infixr}\index{infixr@\isacommand{infixr} (annotation)}
37 means that \isa{{\isacharhash}} associates to
38 the right: the term \isa{x\ {\isacharhash}\ y\ {\isacharhash}\ z} is read as \isa{x\ {\isacharhash}\ {\isacharparenleft}y\ {\isacharhash}\ z{\isacharparenright}}
39 and not as \isa{{\isacharparenleft}x\ {\isacharhash}\ y{\isacharparenright}\ {\isacharhash}\ z}.
40 The \isa{{\isadigit{6}}{\isadigit{5}}} is the priority of the infix \isa{{\isacharhash}}.
43 Syntax annotations can be powerful, but they are difficult to master and
44 are never necessary. You
45 could drop them from theory \isa{ToyList} and go back to the identifiers
46 \isa{Nil} and \isa{Cons}.
47 Novices should avoid using
48 syntax annotations in their own theories.
50 Next, two functions \isa{app} and \cdx{rev} are declared:%
53 \isacommand{consts}\ app\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequote}\ \ \ {\isacharparenleft}\isakeyword{infixr}\ {\isachardoublequote}{\isacharat}{\isachardoublequote}\ {\isadigit{6}}{\isadigit{5}}{\isacharparenright}\isanewline
54 \ \ \ \ \ \ \ rev\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a\ list{\isachardoublequote}\isamarkupfalse%
56 \begin{isamarkuptext}%
58 In contrast to many functional programming languages,
59 Isabelle insists on explicit declarations of all functions
60 (keyword \commdx{consts}). Apart from the declaration-before-use
61 restriction, the order of items in a theory file is unconstrained. Function
62 \isa{app} is annotated with concrete syntax too. Instead of the
63 prefix syntax \isa{app\ xs\ ys} the infix
64 \isa{xs\ {\isacharat}\ ys}\index{$HOL2list@\texttt{\at}|bold} becomes the preferred
65 form. Both functions are defined recursively:%
68 \isacommand{primrec}\isanewline
69 {\isachardoublequote}{\isacharbrackleft}{\isacharbrackright}\ {\isacharat}\ ys\ \ \ \ \ \ \ {\isacharequal}\ ys{\isachardoublequote}\isanewline
70 {\isachardoublequote}{\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ {\isacharat}\ ys\ {\isacharequal}\ x\ {\isacharhash}\ {\isacharparenleft}xs\ {\isacharat}\ ys{\isacharparenright}{\isachardoublequote}\isanewline
73 \isacommand{primrec}\isanewline
74 {\isachardoublequote}rev\ {\isacharbrackleft}{\isacharbrackright}\ \ \ \ \ \ \ \ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}{\isachardoublequote}\isanewline
75 {\isachardoublequote}rev\ {\isacharparenleft}x\ {\isacharhash}\ xs{\isacharparenright}\ \ {\isacharequal}\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharat}\ {\isacharparenleft}x\ {\isacharhash}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
77 \begin{isamarkuptext}%
78 \noindent\index{*rev (constant)|(}\index{append function|(}
79 The equations for \isa{app} and \isa{rev} hardly need comments:
80 \isa{app} appends two lists and \isa{rev} reverses a list. The
81 keyword \commdx{primrec} indicates that the recursion is
82 of a particularly primitive kind where each recursive call peels off a datatype
83 constructor from one of the arguments. Thus the
84 recursion always terminates, i.e.\ the function is \textbf{total}.
85 \index{functions!total}
87 The termination requirement is absolutely essential in HOL, a logic of total
88 functions. If we were to drop it, inconsistencies would quickly arise: the
89 ``definition'' $f(n) = f(n)+1$ immediately leads to $0 = 1$ by subtracting
91 % However, this is a subtle issue that we cannot discuss here further.
94 As we have indicated, the requirement for total functions is an essential characteristic of HOL\@. It is only
95 because of totality that reasoning in HOL is comparatively easy. More
96 generally, the philosophy in HOL is to refrain from asserting arbitrary axioms (such as
97 function definitions whose totality has not been proved) because they
98 quickly lead to inconsistencies. Instead, fixed constructs for introducing
99 types and functions are offered (such as \isacommand{datatype} and
100 \isacommand{primrec}) which are guaranteed to preserve consistency.
104 A remark about syntax. The textual definition of a theory follows a fixed
105 syntax with keywords like \isacommand{datatype} and \isacommand{end}.
106 % (see Fig.~\ref{fig:keywords} in Appendix~\ref{sec:Appendix} for a full list).
107 Embedded in this syntax are the types and formulae of HOL, whose syntax is
108 extensible (see \S\ref{sec:concrete-syntax}), e.g.\ by new user-defined infix operators.
109 To distinguish the two levels, everything
110 HOL-specific (terms and types) should be enclosed in
111 \texttt{"}\dots\texttt{"}.
112 To lessen this burden, quotation marks around a single identifier can be
113 dropped, unless the identifier happens to be a keyword, as in%
116 \isacommand{consts}\ {\isachardoublequote}end{\isachardoublequote}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequote}\isamarkupfalse%
118 \begin{isamarkuptext}%
120 When Isabelle prints a syntax error message, it refers to the HOL syntax as
121 the \textbf{inner syntax} and the enclosing theory language as the \textbf{outer syntax}.
124 \section{An Introductory Proof}
125 \label{sec:intro-proof}
127 Assuming you have input the declarations and definitions of \texttt{ToyList}
128 presented so far, we are ready to prove a few simple theorems. This will
129 illustrate not just the basic proof commands but also the typical proof
132 \subsubsection*{Main Goal.}
134 Our goal is to show that reversing a list twice produces the original
138 \isacommand{theorem}\ rev{\isacharunderscore}rev\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs{\isachardoublequote}\isamarkupfalse%
140 \begin{isamarkuptxt}%
141 \index{theorem@\isacommand {theorem} (command)|bold}%
143 This \isacommand{theorem} command does several things:
146 It establishes a new theorem to be proved, namely \isa{rev\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs}.
148 It gives that theorem the name \isa{rev{\isacharunderscore}rev}, for later reference.
150 It tells Isabelle (via the bracketed attribute \attrdx{simp}) to take the eventual theorem as a simplification rule: future proofs involving
151 simplification will replace occurrences of \isa{rev\ {\isacharparenleft}rev\ xs{\isacharparenright}} by
154 The name and the simplification attribute are optional.
155 Isabelle's response is to print the initial proof state consisting
156 of some header information (like how many subgoals there are) followed by
158 \ {\isadigit{1}}{\isachardot}\ rev\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs%
160 For compactness reasons we omit the header in this tutorial.
161 Until we have finished a proof, the \rmindex{proof state} proper
162 always looks like this:
164 ~1.~$G\sb{1}$\isanewline
165 ~~\vdots~~\isanewline
168 The numbered lines contain the subgoals $G\sb{1}$, \dots, $G\sb{n}$
169 that we need to prove to establish the main goal.\index{subgoals}
170 Initially there is only one subgoal, which is identical with the
171 main goal. (If you always want to see the main goal as well,
172 set the flag \isa{Proof.show_main_goal}\index{*show_main_goal (flag)}
173 --- this flag used to be set by default.)
175 Let us now get back to \isa{rev\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs}. Properties of recursively
176 defined functions are best established by induction. In this case there is
177 nothing obvious except induction on \isa{xs}:%
180 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isamarkupfalse%
182 \begin{isamarkuptxt}%
183 \noindent\index{*induct_tac (method)}%
184 This tells Isabelle to perform induction on variable \isa{xs}. The suffix
185 \isa{tac} stands for \textbf{tactic},\index{tactics}
186 a synonym for ``theorem proving function''.
187 By default, induction acts on the first subgoal. The new proof state contains
188 two subgoals, namely the base case (\isa{Nil}) and the induction step
191 \ {\isadigit{1}}{\isachardot}\ rev\ {\isacharparenleft}rev\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}\isanewline
192 \ {\isadigit{2}}{\isachardot}\ {\isasymAnd}a\ list{\isachardot}\isanewline
193 \isaindent{\ {\isadigit{2}}{\isachardot}\ \ \ \ }rev\ {\isacharparenleft}rev\ list{\isacharparenright}\ {\isacharequal}\ list\ {\isasymLongrightarrow}\ rev\ {\isacharparenleft}rev\ {\isacharparenleft}a\ {\isacharhash}\ list{\isacharparenright}{\isacharparenright}\ {\isacharequal}\ a\ {\isacharhash}\ list%
196 The induction step is an example of the general format of a subgoal:\index{subgoals}
198 ~$i$.~{\isasymAnd}$x\sb{1}$~\dots$x\sb{n}$.~{\it assumptions}~{\isasymLongrightarrow}~{\it conclusion}
199 \end{isabelle}\index{$IsaAnd@\isasymAnd|bold}
200 The prefix of bound variables \isasymAnd$x\sb{1}$~\dots~$x\sb{n}$ can be
201 ignored most of the time, or simply treated as a list of variables local to
202 this subgoal. Their deeper significance is explained in Chapter~\ref{chap:rules}.
203 The {\it assumptions}\index{assumptions!of subgoal}
204 are the local assumptions for this subgoal and {\it
205 conclusion}\index{conclusion!of subgoal} is the actual proposition to be proved.
207 that add new assumptions are induction and case distinction. In our example
208 the only assumption is the induction hypothesis \isa{rev\ {\isacharparenleft}rev\ list{\isacharparenright}\ {\isacharequal}\ list}, where \isa{list} is a variable name chosen by Isabelle. If there
209 are multiple assumptions, they are enclosed in the bracket pair
210 \indexboldpos{\isasymlbrakk}{$Isabrl} and
211 \indexboldpos{\isasymrbrakk}{$Isabrr} and separated by semicolons.
213 Let us try to solve both goals automatically:%
216 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
218 \begin{isamarkuptxt}%
220 This command tells Isabelle to apply a proof strategy called
221 \isa{auto} to all subgoals. Essentially, \isa{auto} tries to
222 simplify the subgoals. In our case, subgoal~1 is solved completely (thanks
223 to the equation \isa{rev\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ {\isacharbrackleft}{\isacharbrackright}}) and disappears; the simplified version
224 of subgoal~2 becomes the new subgoal~1:
226 \ {\isadigit{1}}{\isachardot}\ {\isasymAnd}a\ list{\isachardot}\isanewline
227 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }rev\ {\isacharparenleft}rev\ list{\isacharparenright}\ {\isacharequal}\ list\ {\isasymLongrightarrow}\ rev\ {\isacharparenleft}rev\ list\ {\isacharat}\ a\ {\isacharhash}\ {\isacharbrackleft}{\isacharbrackright}{\isacharparenright}\ {\isacharequal}\ a\ {\isacharhash}\ list%
229 In order to simplify this subgoal further, a lemma suggests itself.%
234 \isamarkupsubsubsection{First Lemma%
238 \begin{isamarkuptext}%
239 \indexbold{abandoning a proof}\indexbold{proofs!abandoning}
240 After abandoning the above proof attempt (at the shell level type
241 \commdx{oops}) we start a new proof:%
244 \isacommand{lemma}\ rev{\isacharunderscore}app\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}xs\ {\isacharat}\ ys{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}rev\ ys{\isacharparenright}\ {\isacharat}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isachardoublequote}\isamarkupfalse%
246 \begin{isamarkuptxt}%
247 \noindent The keywords \commdx{theorem} and
248 \commdx{lemma} are interchangeable and merely indicate
249 the importance we attach to a proposition. Therefore we use the words
250 \emph{theorem} and \emph{lemma} pretty much interchangeably, too.
252 There are two variables that we could induct on: \isa{xs} and
253 \isa{ys}. Because \isa{{\isacharat}} is defined by recursion on
254 the first argument, \isa{xs} is the correct one:%
257 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isamarkupfalse%
259 \begin{isamarkuptxt}%
261 This time not even the base case is solved automatically:%
264 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
266 \begin{isamarkuptxt}%
268 \ {\isadigit{1}}{\isachardot}\ rev\ ys\ {\isacharequal}\ rev\ ys\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}%
270 Again, we need to abandon this proof attempt and prove another simple lemma
271 first. In the future the step of abandoning an incomplete proof before
272 embarking on the proof of a lemma usually remains implicit.%
277 \isamarkupsubsubsection{Second Lemma%
281 \begin{isamarkuptext}%
282 We again try the canonical proof procedure:%
285 \isacommand{lemma}\ app{\isacharunderscore}Nil{\isadigit{2}}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}xs\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequote}\isanewline
287 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
289 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
291 \begin{isamarkuptxt}%
293 It works, yielding the desired message \isa{No\ subgoals{\isacharbang}}:
295 xs\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs\isanewline
296 No\ subgoals{\isacharbang}%
298 We still need to confirm that the proof is now finished:%
301 \isacommand{done}\isamarkupfalse%
303 \begin{isamarkuptext}%
305 As a result of that final \commdx{done}, Isabelle associates the lemma just proved
306 with its name. In this tutorial, we sometimes omit to show that final \isacommand{done}
307 if it is obvious from the context that the proof is finished.
309 % Instead of \isacommand{apply} followed by a dot, you can simply write
310 % \isacommand{by}\indexbold{by}, which we do most of the time.
311 Notice that in lemma \isa{app{\isacharunderscore}Nil{\isadigit{2}}},
312 as printed out after the final \isacommand{done}, the free variable \isa{xs} has been
313 replaced by the unknown \isa{{\isacharquery}xs}, just as explained in
314 \S\ref{sec:variables}.
316 Going back to the proof of the first lemma%
319 \isacommand{lemma}\ rev{\isacharunderscore}app\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}xs\ {\isacharat}\ ys{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}rev\ ys{\isacharparenright}\ {\isacharat}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isachardoublequote}\isanewline
321 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
323 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
325 \begin{isamarkuptxt}%
327 we find that this time \isa{auto} solves the base case, but the
328 induction step merely simplifies to
330 \ {\isadigit{1}}{\isachardot}\ {\isasymAnd}a\ list{\isachardot}\isanewline
331 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }rev\ {\isacharparenleft}list\ {\isacharat}\ ys{\isacharparenright}\ {\isacharequal}\ rev\ ys\ {\isacharat}\ rev\ list\ {\isasymLongrightarrow}\isanewline
332 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }{\isacharparenleft}rev\ ys\ {\isacharat}\ rev\ list{\isacharparenright}\ {\isacharat}\ a\ {\isacharhash}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ rev\ ys\ {\isacharat}\ rev\ list\ {\isacharat}\ a\ {\isacharhash}\ {\isacharbrackleft}{\isacharbrackright}%
334 Now we need to remember that \isa{{\isacharat}} associates to the right, and that
335 \isa{{\isacharhash}} and \isa{{\isacharat}} have the same priority (namely the \isa{{\isadigit{6}}{\isadigit{5}}}
336 in their \isacommand{infixr} annotation). Thus the conclusion really is
338 ~~~~~(rev~ys~@~rev~list)~@~(a~\#~[])~=~rev~ys~@~(rev~list~@~(a~\#~[]))
340 and the missing lemma is associativity of \isa{{\isacharat}}.%
345 \isamarkupsubsubsection{Third Lemma%
349 \begin{isamarkuptext}%
350 Abandoning the previous attempt, the canonical proof procedure
351 succeeds without further ado.%
354 \isacommand{lemma}\ app{\isacharunderscore}assoc\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}{\isacharparenleft}xs\ {\isacharat}\ ys{\isacharparenright}\ {\isacharat}\ zs\ {\isacharequal}\ xs\ {\isacharat}\ {\isacharparenleft}ys\ {\isacharat}\ zs{\isacharparenright}{\isachardoublequote}\isanewline
356 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
358 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
360 \isacommand{done}\isamarkupfalse%
362 \begin{isamarkuptext}%
364 Now we can prove the first lemma:%
367 \isacommand{lemma}\ rev{\isacharunderscore}app\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}xs\ {\isacharat}\ ys{\isacharparenright}\ {\isacharequal}\ {\isacharparenleft}rev\ ys{\isacharparenright}\ {\isacharat}\ {\isacharparenleft}rev\ xs{\isacharparenright}{\isachardoublequote}\isanewline
369 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
371 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
373 \isacommand{done}\isamarkupfalse%
375 \begin{isamarkuptext}%
377 Finally, we prove our main theorem:%
380 \isacommand{theorem}\ rev{\isacharunderscore}rev\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs{\isachardoublequote}\isanewline
382 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
384 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
386 \isacommand{done}\isamarkupfalse%
388 \begin{isamarkuptext}%
390 The final \commdx{end} tells Isabelle to close the current theory because
391 we are finished with its development:%
392 \index{*rev (constant)|)}\index{append function|)}%
395 \isacommand{end}\isanewline
400 %%% TeX-master: "root"