src/Doc/Prog_Prove/Bool_nat_list.thy
author nipkow
Tue, 09 Feb 2016 11:05:53 +0100
changeset 62222 54a7b9422d3e
parent 59360 b1e5d552e8cc
child 62223 c82c7b78b509
permissions -rw-r--r--
synchronized with book
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     1
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     2
theory Bool_nat_list
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     3
imports Main
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     4
begin
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     5
(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     6
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     7
text{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     8
\vspace{-4ex}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
     9
\section{\texorpdfstring{Types @{typ bool}, @{typ nat} and @{text list}}{Types bool, nat and list}}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    10
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    11
These are the most important predefined types. We go through them one by one.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    12
Based on examples we learn how to define (possibly recursive) functions and
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    13
prove theorems about them by induction and simplification.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    14
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
    15
\subsection{Type \indexed{@{typ bool}}{bool}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    16
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    17
The type of boolean values is a predefined datatype
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    18
@{datatype[display] bool}
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
    19
with the two values \indexed{@{const True}}{True} and \indexed{@{const False}}{False} and
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    20
with many predefined functions:  @{text "\<not>"}, @{text "\<and>"}, @{text "\<or>"}, @{text
56989
nipkow
parents: 56451
diff changeset
    21
"\<longrightarrow>"}, etc. Here is how conjunction could be defined by pattern matching:
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    22
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    23
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    24
fun conj :: "bool \<Rightarrow> bool \<Rightarrow> bool" where
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    25
"conj True True = True" |
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    26
"conj _ _ = False"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    27
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    28
text{* Both the datatype and function definitions roughly follow the syntax
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    29
of functional programming languages.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    30
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
    31
\subsection{Type \indexed{@{typ nat}}{nat}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    32
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    33
Natural numbers are another predefined datatype:
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
    34
@{datatype[display] nat}\index{Suc@@{const Suc}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    35
All values of type @{typ nat} are generated by the constructors
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    36
@{text 0} and @{const Suc}. Thus the values of type @{typ nat} are
56989
nipkow
parents: 56451
diff changeset
    37
@{text 0}, @{term"Suc 0"}, @{term"Suc(Suc 0)"}, etc.
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    38
There are many predefined functions: @{text "+"}, @{text "*"}, @{text
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    39
"\<le>"}, etc. Here is how you could define your own addition:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    40
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    41
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    42
fun add :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    43
"add 0 n = n" |
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    44
"add (Suc m) n = Suc(add m n)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    45
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    46
text{* And here is a proof of the fact that @{prop"add m 0 = m"}: *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    47
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    48
lemma add_02: "add m 0 = m"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    49
apply(induction m)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    50
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    51
done
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    52
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    53
lemma "add m 0 = m"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    54
apply(induction m)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    55
(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    56
txt{* The \isacom{lemma} command starts the proof and gives the lemma
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    57
a name, @{text add_02}. Properties of recursively defined functions
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    58
need to be established by induction in most cases.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    59
Command \isacom{apply}@{text"(induction m)"} instructs Isabelle to
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    60
start a proof by induction on @{text m}. In response, it will show the
62222
54a7b9422d3e synchronized with book
nipkow
parents: 59360
diff changeset
    61
following proof state\ifsem\footnote{See page \pageref{proof-state} for how to
54a7b9422d3e synchronized with book
nipkow
parents: 59360
diff changeset
    62
display the proof state}\fi:
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    63
@{subgoals[display,indent=0]}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    64
The numbered lines are known as \emph{subgoals}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    65
The first subgoal is the base case, the second one the induction step.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    66
The prefix @{text"\<And>m."} is Isabelle's way of saying ``for an arbitrary but fixed @{text m}''. The @{text"\<Longrightarrow>"} separates assumptions from the conclusion.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    67
The command \isacom{apply}@{text"(auto)"} instructs Isabelle to try
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    68
and prove all subgoals automatically, essentially by simplifying them.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    69
Because both subgoals are easy, Isabelle can do it.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    70
The base case @{prop"add 0 0 = 0"} holds by definition of @{const add},
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    71
and the induction step is almost as simple:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    72
@{text"add\<^raw:~>(Suc m) 0 = Suc(add m 0) = Suc m"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    73
using first the definition of @{const add} and then the induction hypothesis.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    74
In summary, both subproofs rely on simplification with function definitions and
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    75
the induction hypothesis.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    76
As a result of that final \isacom{done}, Isabelle associates the lemma
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    77
just proved with its name. You can now inspect the lemma with the command
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    78
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    79
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    80
thm add_02
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    81
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    82
txt{* which displays @{thm[show_question_marks,display] add_02} The free
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    83
variable @{text m} has been replaced by the \concept{unknown}
56989
nipkow
parents: 56451
diff changeset
    84
@{text"?m"}. There is no logical difference between the two but there is an
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    85
operational one: unknowns can be instantiated, which is what you want after
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    86
some lemma has been proved.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    87
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    88
Note that there is also a proof method @{text induct}, which behaves almost
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    89
like @{text induction}; the difference is explained in \autoref{ch:Isar}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    90
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    91
\begin{warn}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    92
Terminology: We use \concept{lemma}, \concept{theorem} and \concept{rule}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    93
interchangeably for propositions that have been proved.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    94
\end{warn}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    95
\begin{warn}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    96
  Numerals (@{text 0}, @{text 1}, @{text 2}, \dots) and most of the standard
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    97
  arithmetic operations (@{text "+"}, @{text "-"}, @{text "*"}, @{text"\<le>"},
58521
nipkow
parents: 58504
diff changeset
    98
  @{text"<"}, etc.) are overloaded: they are available
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
    99
  not just for natural numbers but for other types as well.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   100
  For example, given the goal @{text"x + 0 = x"}, there is nothing to indicate
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   101
  that you are talking about natural numbers. Hence Isabelle can only infer
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   102
  that @{term x} is of some arbitrary type where @{text 0} and @{text"+"}
54508
nipkow
parents: 54467
diff changeset
   103
  exist. As a consequence, you will be unable to prove the goal.
nipkow
parents: 54467
diff changeset
   104
%  To alert you to such pitfalls, Isabelle flags numerals without a
nipkow
parents: 54467
diff changeset
   105
%  fixed type in its output: @ {prop"x+0 = x"}.
nipkow
parents: 54467
diff changeset
   106
  In this particular example, you need to include
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   107
  an explicit type constraint, for example @{text"x+0 = (x::nat)"}. If there
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   108
  is enough contextual information this may not be necessary: @{prop"Suc x =
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   109
  x"} automatically implies @{text"x::nat"} because @{term Suc} is not
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   110
  overloaded.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   111
\end{warn}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   112
52361
7d5ad23b8245 all headings in upper case
nipkow
parents: 48985
diff changeset
   113
\subsubsection{An Informal Proof}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   114
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   115
Above we gave some terse informal explanation of the proof of
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   116
@{prop"add m 0 = m"}. A more detailed informal exposition of the lemma
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   117
might look like this:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   118
\bigskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   119
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   120
\noindent
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   121
\textbf{Lemma} @{prop"add m 0 = m"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   122
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   123
\noindent
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   124
\textbf{Proof} by induction on @{text m}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   125
\begin{itemize}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   126
\item Case @{text 0} (the base case): @{prop"add 0 0 = 0"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   127
  holds by definition of @{const add}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   128
\item Case @{term"Suc m"} (the induction step):
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   129
  We assume @{prop"add m 0 = m"}, the induction hypothesis (IH),
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   130
  and we need to show @{text"add (Suc m) 0 = Suc m"}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   131
  The proof is as follows:\smallskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   132
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   133
  \begin{tabular}{@ {}rcl@ {\quad}l@ {}}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   134
  @{term "add (Suc m) 0"} &@{text"="}& @{term"Suc(add m 0)"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   135
  & by definition of @{text add}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   136
              &@{text"="}& @{term "Suc m"} & by IH
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   137
  \end{tabular}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   138
\end{itemize}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   139
Throughout this book, \concept{IH} will stand for ``induction hypothesis''.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   140
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   141
We have now seen three proofs of @{prop"add m 0 = 0"}: the Isabelle one, the
47711
c1cca2a052e4 doc update
nipkow
parents: 47306
diff changeset
   142
terse four lines explaining the base case and the induction step, and just now a
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   143
model of a traditional inductive proof. The three proofs differ in the level
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   144
of detail given and the intended reader: the Isabelle proof is for the
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   145
machine, the informal proofs are for humans. Although this book concentrates
47711
c1cca2a052e4 doc update
nipkow
parents: 47306
diff changeset
   146
on Isabelle proofs, it is important to be able to rephrase those proofs
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   147
as informal text comprehensible to a reader familiar with traditional
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   148
mathematical proofs. Later on we will introduce an Isabelle proof language
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   149
that is closer to traditional informal mathematical language and is often
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   150
directly readable.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   151
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   152
\subsection{Type \indexed{@{text list}}{list}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   153
58521
nipkow
parents: 58504
diff changeset
   154
Although lists are already predefined, we define our own copy for
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   155
demonstration purposes:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   156
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   157
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   158
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   159
done 
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   160
declare [[names_short]]
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   161
(*>*)
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   162
datatype 'a list = Nil | Cons 'a "'a list"
59204
0cbe0a56d3fa update map definition in Prog_Prove for new datatype package
kleing
parents: 58521
diff changeset
   163
(*<*)
0cbe0a56d3fa update map definition in Prog_Prove for new datatype package
kleing
parents: 58521
diff changeset
   164
for map: map
0cbe0a56d3fa update map definition in Prog_Prove for new datatype package
kleing
parents: 58521
diff changeset
   165
(*>*)
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   166
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   167
text{*
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   168
\begin{itemize}
47711
c1cca2a052e4 doc update
nipkow
parents: 47306
diff changeset
   169
\item Type @{typ "'a list"} is the type of lists over elements of type @{typ 'a}. Because @{typ 'a} is a type variable, lists are in fact \concept{polymorphic}: the elements of a list can be of arbitrary type (but must all be of the same type).
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   170
\item Lists have two constructors: @{const Nil}, the empty list, and @{const Cons}, which puts an element (of type @{typ 'a}) in front of a list (of type @{typ "'a list"}).
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   171
Hence all lists are of the form @{const Nil}, or @{term"Cons x Nil"},
56989
nipkow
parents: 56451
diff changeset
   172
or @{term"Cons x (Cons y Nil)"}, etc.
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   173
\item \isacom{datatype} requires no quotation marks on the
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   174
left-hand side, but on the right-hand side each of the argument
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   175
types of a constructor needs to be enclosed in quotation marks, unless
58504
nipkow
parents: 57805
diff changeset
   176
it is just an identifier (e.g., @{typ nat} or @{typ 'a}).
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   177
\end{itemize}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   178
We also define two standard functions, append and reverse: *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   179
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   180
fun app :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   181
"app Nil ys = ys" |
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   182
"app (Cons x xs) ys = Cons x (app xs ys)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   183
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   184
fun rev :: "'a list \<Rightarrow> 'a list" where
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   185
"rev Nil = Nil" |
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   186
"rev (Cons x xs) = app (rev xs) (Cons x Nil)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   187
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   188
text{* By default, variables @{text xs}, @{text ys} and @{text zs} are of
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   189
@{text list} type.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   190
55320
8a6ee5c1f2e0 tuned latex
nipkow
parents: 55318
diff changeset
   191
Command \indexed{\isacommand{value}}{value} evaluates a term. For example, *}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   192
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   193
value "rev(Cons True (Cons False Nil))"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   194
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   195
text{* yields the result @{value "rev(Cons True (Cons False Nil))"}. This works symbolically, too: *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   196
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   197
value "rev(Cons a (Cons b Nil))"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   198
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   199
text{* yields @{value "rev(Cons a (Cons b Nil))"}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   200
\medskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   201
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   202
Figure~\ref{fig:MyList} shows the theory created so far.
56989
nipkow
parents: 56451
diff changeset
   203
Because @{text list}, @{const Nil}, @{const Cons}, etc.\ are already predefined,
47719
8aac84627b84 the perennial doc problem of how to define lists a second time
nipkow
parents: 47711
diff changeset
   204
 Isabelle prints qualified (long) names when executing this theory, for example, @{text MyList.Nil}
8aac84627b84 the perennial doc problem of how to define lists a second time
nipkow
parents: 47711
diff changeset
   205
 instead of @{const Nil}.
8aac84627b84 the perennial doc problem of how to define lists a second time
nipkow
parents: 47711
diff changeset
   206
 To suppress the qualified names you can insert the command
8aac84627b84 the perennial doc problem of how to define lists a second time
nipkow
parents: 47711
diff changeset
   207
 \texttt{declare [[names\_short]]}.
56989
nipkow
parents: 56451
diff changeset
   208
 This is not recommended in general but is convenient for this unusual example.
47302
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   209
% Notice where the
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   210
%quotations marks are needed that we mostly sweep under the carpet.  In
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   211
%particular, notice that \isacom{datatype} requires no quotation marks on the
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   212
%left-hand side, but that on the right-hand side each of the argument
70239da25ef6 towards showing " in the tutorial
nipkow
parents: 47269
diff changeset
   213
%types of a constructor needs to be enclosed in quotation marks.
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   214
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   215
\begin{figure}[htbp]
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   216
\begin{alltt}
48947
7eee8b2d2099 more standard document preparation within session context;
wenzelm
parents: 47719
diff changeset
   217
\input{MyList.thy}\end{alltt}
58521
nipkow
parents: 58504
diff changeset
   218
\caption{A theory of lists}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   219
\label{fig:MyList}
57805
nipkow
parents: 56989
diff changeset
   220
\index{comment}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   221
\end{figure}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   222
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   223
\subsubsection{Structural Induction for Lists}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   224
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   225
Just as for natural numbers, there is a proof principle of induction for
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   226
lists. Induction over a list is essentially induction over the length of
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   227
the list, although the length remains implicit. To prove that some property
58504
nipkow
parents: 57805
diff changeset
   228
@{text P} holds for all lists @{text xs}, i.e., \mbox{@{prop"P(xs)"}},
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   229
you need to prove
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   230
\begin{enumerate}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   231
\item the base case @{prop"P(Nil)"} and
47711
c1cca2a052e4 doc update
nipkow
parents: 47306
diff changeset
   232
\item the inductive case @{prop"P(Cons x xs)"} under the assumption @{prop"P(xs)"}, for some arbitrary but fixed @{text x} and @{text xs}.
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   233
\end{enumerate}
55318
nipkow
parents: 55317
diff changeset
   234
This is often called \concept{structural induction} for lists.
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   235
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   236
\subsection{The Proof Process}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   237
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   238
We will now demonstrate the typical proof process, which involves
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   239
the formulation and proof of auxiliary lemmas.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   240
Our goal is to show that reversing a list twice produces the original
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   241
list. *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   242
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   243
theorem rev_rev [simp]: "rev(rev xs) = xs"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   244
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   245
txt{* Commands \isacom{theorem} and \isacom{lemma} are
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   246
interchangeable and merely indicate the importance we attach to a
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   247
proposition. Via the bracketed attribute @{text simp} we also tell Isabelle
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   248
to make the eventual theorem a \conceptnoidx{simplification rule}: future proofs
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   249
involving simplification will replace occurrences of @{term"rev(rev xs)"} by
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   250
@{term"xs"}. The proof is by induction: *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   251
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   252
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   253
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   254
txt{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   255
As explained above, we obtain two subgoals, namely the base case (@{const Nil}) and the induction step (@{const Cons}):
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   256
@{subgoals[display,indent=0,margin=65]}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   257
Let us try to solve both goals automatically:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   258
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   259
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   260
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   261
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   262
txt{*Subgoal~1 is proved, and disappears; the simplified version
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   263
of subgoal~2 becomes the new subgoal~1:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   264
@{subgoals[display,indent=0,margin=70]}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   265
In order to simplify this subgoal further, a lemma suggests itself.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   266
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   267
\subsubsection{A First Lemma}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   268
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   269
We insert the following lemma in front of the main theorem:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   270
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   271
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   272
oops
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   273
(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   274
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   275
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   276
txt{* There are two variables that we could induct on: @{text xs} and
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   277
@{text ys}. Because @{const app} is defined by recursion on
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   278
the first argument, @{text xs} is the correct one:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   279
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   280
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   281
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   282
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   283
txt{* This time not even the base case is solved automatically: *}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   284
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   285
txt{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   286
\vspace{-5ex}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   287
@{subgoals[display,goals_limit=1]}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   288
Again, we need to abandon this proof attempt and prove another simple lemma
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   289
first.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   290
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   291
\subsubsection{A Second Lemma}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   292
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   293
We again try the canonical proof procedure:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   294
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   295
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   296
oops
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   297
(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   298
lemma app_Nil2 [simp]: "app xs Nil = xs"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   299
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   300
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   301
done
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   302
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   303
text{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   304
Thankfully, this worked.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   305
Now we can continue with our stuck proof attempt of the first lemma:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   306
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   307
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   308
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   309
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   310
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   311
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   312
txt{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   313
We find that this time @{text"auto"} solves the base case, but the
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   314
induction step merely simplifies to
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   315
@{subgoals[display,indent=0,goals_limit=1]}
47711
c1cca2a052e4 doc update
nipkow
parents: 47306
diff changeset
   316
The missing lemma is associativity of @{const app},
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   317
which we insert in front of the failed lemma @{text rev_app}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   318
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   319
\subsubsection{Associativity of @{const app}}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   320
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   321
The canonical proof procedure succeeds without further ado:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   322
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   323
(*<*)oops(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   324
lemma app_assoc [simp]: "app (app xs ys) zs = app xs (app ys zs)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   325
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   326
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   327
done
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   328
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   329
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys)(rev xs)"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   330
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   331
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   332
done
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   333
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   334
theorem rev_rev [simp]: "rev(rev xs) = xs"
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   335
apply(induction xs)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   336
apply(auto)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   337
done
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   338
(*>*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   339
text{*
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   340
Finally the proofs of @{thm[source] rev_app} and @{thm[source] rev_rev}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   341
succeed, too.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   342
52361
7d5ad23b8245 all headings in upper case
nipkow
parents: 48985
diff changeset
   343
\subsubsection{Another Informal Proof}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   344
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   345
Here is the informal proof of associativity of @{const app}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   346
corresponding to the Isabelle proof above.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   347
\bigskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   348
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   349
\noindent
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   350
\textbf{Lemma} @{prop"app (app xs ys) zs = app xs (app ys zs)"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   351
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   352
\noindent
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   353
\textbf{Proof} by induction on @{text xs}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   354
\begin{itemize}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   355
\item Case @{text Nil}: \ @{prop"app (app Nil ys) zs = app ys zs"} @{text"="}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   356
  \mbox{@{term"app Nil (app ys zs)"}} \ holds by definition of @{text app}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   357
\item Case @{text"Cons x xs"}: We assume
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   358
  \begin{center} \hfill @{term"app (app xs ys) zs"} @{text"="}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   359
  @{term"app xs (app ys zs)"} \hfill (IH) \end{center}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   360
  and we need to show
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   361
  \begin{center} @{prop"app (app (Cons x xs) ys) zs = app (Cons x xs) (app ys zs)"}.\end{center}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   362
  The proof is as follows:\smallskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   363
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   364
  \begin{tabular}{@ {}l@ {\quad}l@ {}}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   365
  @{term"app (app (Cons x xs) ys) zs"}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   366
  @{text"= app (Cons x (app xs ys)) zs"} & by definition of @{text app}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   367
  @{text"= Cons x (app (app xs ys) zs)"} & by definition of @{text app}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   368
  @{text"= Cons x (app xs (app ys zs))"} & by IH\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   369
  @{text"= app (Cons x xs) (app ys zs)"} & by definition of @{text app}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   370
  \end{tabular}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   371
\end{itemize}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   372
\medskip
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   373
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   374
\noindent Didn't we say earlier that all proofs are by simplification? But
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   375
in both cases, going from left to right, the last equality step is not a
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   376
simplification at all! In the base case it is @{prop"app ys zs = app Nil (app
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   377
ys zs)"}. It appears almost mysterious because we suddenly complicate the
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   378
term by appending @{text Nil} on the left. What is really going on is this:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   379
when proving some equality \mbox{@{prop"s = t"}}, both @{text s} and @{text t} are
54467
663a927fdc88 comments by Sean Seefried
nipkow
parents: 54436
diff changeset
   380
simplified until they ``meet in the middle''. This heuristic for equality proofs
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   381
works well for a functional programming context like ours. In the base case
54467
663a927fdc88 comments by Sean Seefried
nipkow
parents: 54436
diff changeset
   382
both @{term"app (app Nil ys) zs"} and @{term"app Nil (app
663a927fdc88 comments by Sean Seefried
nipkow
parents: 54436
diff changeset
   383
ys zs)"} are simplified to @{term"app ys zs"}, the term in the middle.
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   384
52361
7d5ad23b8245 all headings in upper case
nipkow
parents: 48985
diff changeset
   385
\subsection{Predefined Lists}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   386
\label{sec:predeflists}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   387
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   388
Isabelle's predefined lists are the same as the ones above, but with
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   389
more syntactic sugar:
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   390
\begin{itemize}
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   391
\item @{text "[]"} is \indexed{@{const Nil}}{Nil},
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   392
\item @{term"x # xs"} is @{term"Cons x xs"}\index{Cons@@{const Cons}},
53015
a1119cf551e8 standardized symbols via "isabelle update_sub_sup", excluding src/Pure and src/Tools/WWW_Find;
wenzelm
parents: 52842
diff changeset
   393
\item @{text"[x\<^sub>1, \<dots>, x\<^sub>n]"} is @{text"x\<^sub>1 # \<dots> # x\<^sub>n # []"}, and
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   394
\item @{term "xs @ ys"} is @{term"app xs ys"}.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   395
\end{itemize}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   396
There is also a large library of predefined functions.
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   397
The most important ones are the length function
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   398
@{text"length :: 'a list \<Rightarrow> nat"}\index{length@@{const length}} (with the obvious definition),
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   399
and the \indexed{@{const map}}{map} function that applies a function to all elements of a list:
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   400
\begin{isabelle}
59360
nipkow
parents: 59204
diff changeset
   401
\isacom{fun} @{const map} @{text"::"} @{typ[source] "('a \<Rightarrow> 'b) \<Rightarrow> 'a list \<Rightarrow> 'b list"} \isacom{where}\\
59204
0cbe0a56d3fa update map definition in Prog_Prove for new datatype package
kleing
parents: 58521
diff changeset
   402
@{text"\""}@{thm list.map(1) [of f]}@{text"\" |"}\\
0cbe0a56d3fa update map definition in Prog_Prove for new datatype package
kleing
parents: 58521
diff changeset
   403
@{text"\""}@{thm list.map(2) [of f x xs]}@{text"\""}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   404
\end{isabelle}
52782
b11d73dbfb76 tuned intro
nipkow
parents: 52718
diff changeset
   405
b11d73dbfb76 tuned intro
nipkow
parents: 52718
diff changeset
   406
\ifsem
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   407
Also useful are the \concept{head} of a list, its first element,
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   408
and the \concept{tail}, the rest of the list:
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   409
\begin{isabelle}\index{hd@@{const hd}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   410
\isacom{fun} @{text"hd :: 'a list \<Rightarrow> 'a"}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   411
@{prop"hd(x#xs) = x"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   412
\end{isabelle}
55317
834a84553e02 started index
nipkow
parents: 54508
diff changeset
   413
\begin{isabelle}\index{tl@@{const tl}}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   414
\isacom{fun} @{text"tl :: 'a list \<Rightarrow> 'a list"}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   415
@{prop"tl [] = []"} @{text"|"}\\
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   416
@{prop"tl(x#xs) = xs"}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   417
\end{isabelle}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   418
Note that since HOL is a logic of total functions, @{term"hd []"} is defined,
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   419
but we do now know what the result is. That is, @{term"hd []"} is not undefined
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   420
but underdefined.
52782
b11d73dbfb76 tuned intro
nipkow
parents: 52718
diff changeset
   421
\fi
47306
56d72c923281 made sure that " is shown in tutorial text
nipkow
parents: 47302
diff changeset
   422
%
52593
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   423
52842
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   424
From now on lists are always the predefined lists.
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   425
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   426
54436
nipkow
parents: 54121
diff changeset
   427
\subsection*{Exercises}
52593
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   428
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   429
\begin{exercise}
54121
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   430
Use the \isacom{value} command to evaluate the following expressions:
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   431
@{term[source] "1 + (2::nat)"}, @{term[source] "1 + (2::int)"},
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   432
@{term[source] "1 - (2::nat)"} and @{term[source] "1 - (2::int)"}.
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   433
\end{exercise}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   434
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   435
\begin{exercise}
52842
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   436
Start from the definition of @{const add} given above.
54467
663a927fdc88 comments by Sean Seefried
nipkow
parents: 54436
diff changeset
   437
Prove that @{const add} is associative and commutative.
54121
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   438
Define a recursive function @{text double} @{text"::"} @{typ"nat \<Rightarrow> nat"}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   439
and prove @{prop"double m = add m m"}.
52593
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   440
\end{exercise}
52718
0faf89b8d928 tuned exercises
nipkow
parents: 52593
diff changeset
   441
52593
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   442
\begin{exercise}
52842
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   443
Define a function @{text"count ::"} @{typ"'a \<Rightarrow> 'a list \<Rightarrow> nat"}
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   444
that counts the number of occurrences of an element in a list. Prove
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   445
@{prop"count x xs \<le> length xs"}.
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   446
\end{exercise}
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   447
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   448
\begin{exercise}
3682e1b7ce86 tuned exercises
nipkow
parents: 52782
diff changeset
   449
Define a recursive function @{text "snoc ::"} @{typ"'a list \<Rightarrow> 'a \<Rightarrow> 'a list"}
54121
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   450
that appends an element to the end of a list. With the help of @{text snoc}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   451
define a recursive function @{text "reverse ::"} @{typ"'a list \<Rightarrow> 'a list"}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   452
that reverses a list. Prove @{prop"reverse(reverse xs) = xs"}.
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   453
\end{exercise}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   454
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   455
\begin{exercise}
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   456
Define a recursive function @{text "sum ::"} @{typ"nat \<Rightarrow> nat"} such that
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   457
\mbox{@{text"sum n"}} @{text"="} @{text"0 + ... + n"} and prove
4e7d71037bb6 tuned exercises
nipkow
parents: 53015
diff changeset
   458
@{prop" sum(n::nat) = n * (n+1) div 2"}.
52593
aedf7b01c6e4 added exercises
nipkow
parents: 52361
diff changeset
   459
\end{exercise}
47269
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   460
*}
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   461
(*<*)
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   462
end
29aa0c071875 New manual Programming and Proving in Isabelle/HOL
nipkow
parents:
diff changeset
   463
(*>*)