doc-src/TutorialI/ToyList/document/ToyList.tex
author nipkow
Mon, 16 Aug 2004 19:47:01 +0200
changeset 15136 1275417e3930
parent 13978 a241cdd9c1c9
child 15141 a95c2ff210ba
permissions -rw-r--r--
Adapted text to new theory header syntax.
     1 %
     2 \begin{isabellebody}%
     3 \def\isabellecontext{ToyList}%
     4 \isacommand{theory}\ ToyList\isanewline
     5 \isakeyword{import}\ PreList\isanewline
     6 \isakeyword{begin}\isamarkupfalse%
     7 %
     8 \begin{isamarkuptext}%
     9 \noindent
    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.%
    16 \end{isamarkuptext}%
    17 \isamarkuptrue%
    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%
    20 %
    21 \begin{isamarkuptext}%
    22 \noindent
    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}}.
    41 
    42 \begin{warn}
    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.
    49 \end{warn}
    50 Next, two functions \isa{app} and \cdx{rev} are declared:%
    51 \end{isamarkuptext}%
    52 \isamarkuptrue%
    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%
    55 %
    56 \begin{isamarkuptext}%
    57 \noindent
    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:%
    66 \end{isamarkuptext}%
    67 \isamarkuptrue%
    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
    71 \isanewline
    72 \isamarkupfalse%
    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%
    76 %
    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}
    86 
    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
    90 $f(n)$ on both sides.
    91 % However, this is a subtle issue that we cannot discuss here further.
    92 
    93 \begin{warn}
    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.
   101 \end{warn}
   102 
   103 \index{syntax}%
   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%
   114 \end{isamarkuptext}%
   115 \isamarkuptrue%
   116 \isacommand{consts}\ {\isachardoublequote}end{\isachardoublequote}\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequote}{\isacharprime}a\ list\ {\isasymRightarrow}\ {\isacharprime}a{\isachardoublequote}\isamarkupfalse%
   117 %
   118 \begin{isamarkuptext}%
   119 \noindent
   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}.
   122 
   123 
   124 \section{An Introductory Proof}
   125 \label{sec:intro-proof}
   126 
   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
   130 process.
   131 
   132 \subsubsection*{Main Goal.}
   133 
   134 Our goal is to show that reversing a list twice produces the original
   135 list.%
   136 \end{isamarkuptext}%
   137 \isamarkuptrue%
   138 \isacommand{theorem}\ rev{\isacharunderscore}rev\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs{\isachardoublequote}\isamarkupfalse%
   139 %
   140 \begin{isamarkuptxt}%
   141 \index{theorem@\isacommand {theorem} (command)|bold}%
   142 \noindent
   143 This \isacommand{theorem} command does several things:
   144 \begin{itemize}
   145 \item
   146 It establishes a new theorem to be proved, namely \isa{rev\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs}.
   147 \item
   148 It gives that theorem the name \isa{rev{\isacharunderscore}rev}, for later reference.
   149 \item
   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
   152 \isa{xs}.
   153 \end{itemize}
   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
   157 \begin{isabelle}%
   158 \ {\isadigit{1}}{\isachardot}\ rev\ {\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs%
   159 \end{isabelle}
   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:
   163 \begin{isabelle}
   164 ~1.~$G\sb{1}$\isanewline
   165 ~~\vdots~~\isanewline
   166 ~$n$.~$G\sb{n}$
   167 \end{isabelle}
   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.)
   174 
   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}:%
   178 \end{isamarkuptxt}%
   179 \isamarkuptrue%
   180 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isamarkupfalse%
   181 %
   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
   189 (\isa{Cons}):
   190 \begin{isabelle}%
   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%
   194 \end{isabelle}
   195 
   196 The induction step is an example of the general format of a subgoal:\index{subgoals}
   197 \begin{isabelle}
   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. 
   206 Typical proof steps
   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.
   212 
   213 Let us try to solve both goals automatically:%
   214 \end{isamarkuptxt}%
   215 \isamarkuptrue%
   216 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
   217 %
   218 \begin{isamarkuptxt}%
   219 \noindent
   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:
   225 \begin{isabelle}%
   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%
   228 \end{isabelle}
   229 In order to simplify this subgoal further, a lemma suggests itself.%
   230 \end{isamarkuptxt}%
   231 \isamarkuptrue%
   232 \isamarkupfalse%
   233 %
   234 \isamarkupsubsubsection{First Lemma%
   235 }
   236 \isamarkuptrue%
   237 %
   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:%
   242 \end{isamarkuptext}%
   243 \isamarkuptrue%
   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%
   245 %
   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.
   251 
   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:%
   255 \end{isamarkuptxt}%
   256 \isamarkuptrue%
   257 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isamarkupfalse%
   258 %
   259 \begin{isamarkuptxt}%
   260 \noindent
   261 This time not even the base case is solved automatically:%
   262 \end{isamarkuptxt}%
   263 \isamarkuptrue%
   264 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
   265 %
   266 \begin{isamarkuptxt}%
   267 \begin{isabelle}%
   268 \ {\isadigit{1}}{\isachardot}\ rev\ ys\ {\isacharequal}\ rev\ ys\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}%
   269 \end{isabelle}
   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.%
   273 \end{isamarkuptxt}%
   274 \isamarkuptrue%
   275 \isamarkupfalse%
   276 %
   277 \isamarkupsubsubsection{Second Lemma%
   278 }
   279 \isamarkuptrue%
   280 %
   281 \begin{isamarkuptext}%
   282 We again try the canonical proof procedure:%
   283 \end{isamarkuptext}%
   284 \isamarkuptrue%
   285 \isacommand{lemma}\ app{\isacharunderscore}Nil{\isadigit{2}}\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}xs\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs{\isachardoublequote}\isanewline
   286 \isamarkupfalse%
   287 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
   288 \isamarkupfalse%
   289 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
   290 %
   291 \begin{isamarkuptxt}%
   292 \noindent
   293 It works, yielding the desired message \isa{No\ subgoals{\isacharbang}}:
   294 \begin{isabelle}%
   295 xs\ {\isacharat}\ {\isacharbrackleft}{\isacharbrackright}\ {\isacharequal}\ xs\isanewline
   296 No\ subgoals{\isacharbang}%
   297 \end{isabelle}
   298 We still need to confirm that the proof is now finished:%
   299 \end{isamarkuptxt}%
   300 \isamarkuptrue%
   301 \isacommand{done}\isamarkupfalse%
   302 %
   303 \begin{isamarkuptext}%
   304 \noindent
   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.
   308 
   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}.
   315 
   316 Going back to the proof of the first lemma%
   317 \end{isamarkuptext}%
   318 \isamarkuptrue%
   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
   320 \isamarkupfalse%
   321 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
   322 \isamarkupfalse%
   323 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isamarkupfalse%
   324 %
   325 \begin{isamarkuptxt}%
   326 \noindent
   327 we find that this time \isa{auto} solves the base case, but the
   328 induction step merely simplifies to
   329 \begin{isabelle}%
   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}%
   333 \end{isabelle}
   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
   337 \begin{isabelle}
   338 ~~~~~(rev~ys~@~rev~list)~@~(a~\#~[])~=~rev~ys~@~(rev~list~@~(a~\#~[]))
   339 \end{isabelle}
   340 and the missing lemma is associativity of \isa{{\isacharat}}.%
   341 \end{isamarkuptxt}%
   342 \isamarkuptrue%
   343 \isamarkupfalse%
   344 %
   345 \isamarkupsubsubsection{Third Lemma%
   346 }
   347 \isamarkuptrue%
   348 %
   349 \begin{isamarkuptext}%
   350 Abandoning the previous attempt, the canonical proof procedure
   351 succeeds without further ado.%
   352 \end{isamarkuptext}%
   353 \isamarkuptrue%
   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
   355 \isamarkupfalse%
   356 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
   357 \isamarkupfalse%
   358 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
   359 \isamarkupfalse%
   360 \isacommand{done}\isamarkupfalse%
   361 %
   362 \begin{isamarkuptext}%
   363 \noindent
   364 Now we can prove the first lemma:%
   365 \end{isamarkuptext}%
   366 \isamarkuptrue%
   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
   368 \isamarkupfalse%
   369 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
   370 \isamarkupfalse%
   371 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
   372 \isamarkupfalse%
   373 \isacommand{done}\isamarkupfalse%
   374 %
   375 \begin{isamarkuptext}%
   376 \noindent
   377 Finally, we prove our main theorem:%
   378 \end{isamarkuptext}%
   379 \isamarkuptrue%
   380 \isacommand{theorem}\ rev{\isacharunderscore}rev\ {\isacharbrackleft}simp{\isacharbrackright}{\isacharcolon}\ {\isachardoublequote}rev{\isacharparenleft}rev\ xs{\isacharparenright}\ {\isacharequal}\ xs{\isachardoublequote}\isanewline
   381 \isamarkupfalse%
   382 \isacommand{apply}{\isacharparenleft}induct{\isacharunderscore}tac\ xs{\isacharparenright}\isanewline
   383 \isamarkupfalse%
   384 \isacommand{apply}{\isacharparenleft}auto{\isacharparenright}\isanewline
   385 \isamarkupfalse%
   386 \isacommand{done}\isamarkupfalse%
   387 %
   388 \begin{isamarkuptext}%
   389 \noindent
   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|)}%
   393 \end{isamarkuptext}%
   394 \isamarkuptrue%
   395 \isacommand{end}\isanewline
   396 \isamarkupfalse%
   397 \end{isabellebody}%
   398 %%% Local Variables:
   399 %%% mode: latex
   400 %%% TeX-master: "root"
   401 %%% End: