src/Doc/Prog_Prove/Bool_nat_list.thy
changeset 67406 23307fd33906
parent 65514 d10f0bbc7ea1
child 68919 027219002f32
equal deleted inserted replaced
67405:e9ab4ad7bd15 67406:23307fd33906
     2 theory Bool_nat_list
     2 theory Bool_nat_list
     3 imports Main
     3 imports Main
     4 begin
     4 begin
     5 (*>*)
     5 (*>*)
     6 
     6 
     7 text{*
     7 text\<open>
     8 \vspace{-4ex}
     8 \vspace{-4ex}
     9 \section{\texorpdfstring{Types @{typ bool}, @{typ nat} and @{text list}}{Types bool, nat and list}}
     9 \section{\texorpdfstring{Types @{typ bool}, @{typ nat} and @{text list}}{Types bool, nat and list}}
    10 
    10 
    11 These are the most important predefined types. We go through them one by one.
    11 These are the most important predefined types. We go through them one by one.
    12 Based on examples we learn how to define (possibly recursive) functions and
    12 Based on examples we learn how to define (possibly recursive) functions and
    17 The type of boolean values is a predefined datatype
    17 The type of boolean values is a predefined datatype
    18 @{datatype[display] bool}
    18 @{datatype[display] bool}
    19 with the two values \indexed{@{const True}}{True} and \indexed{@{const False}}{False} and
    19 with the two values \indexed{@{const True}}{True} and \indexed{@{const False}}{False} and
    20 with many predefined functions:  @{text "\<not>"}, @{text "\<and>"}, @{text "\<or>"}, @{text
    20 with many predefined functions:  @{text "\<not>"}, @{text "\<and>"}, @{text "\<or>"}, @{text
    21 "\<longrightarrow>"}, etc. Here is how conjunction could be defined by pattern matching:
    21 "\<longrightarrow>"}, etc. Here is how conjunction could be defined by pattern matching:
    22 *}
    22 \<close>
    23 
    23 
    24 fun conj :: "bool \<Rightarrow> bool \<Rightarrow> bool" where
    24 fun conj :: "bool \<Rightarrow> bool \<Rightarrow> bool" where
    25 "conj True True = True" |
    25 "conj True True = True" |
    26 "conj _ _ = False"
    26 "conj _ _ = False"
    27 
    27 
    28 text{* Both the datatype and function definitions roughly follow the syntax
    28 text\<open>Both the datatype and function definitions roughly follow the syntax
    29 of functional programming languages.
    29 of functional programming languages.
    30 
    30 
    31 \subsection{Type \indexed{@{typ nat}}{nat}}
    31 \subsection{Type \indexed{@{typ nat}}{nat}}
    32 
    32 
    33 Natural numbers are another predefined datatype:
    33 Natural numbers are another predefined datatype:
    35 All values of type @{typ nat} are generated by the constructors
    35 All values of type @{typ nat} are generated by the constructors
    36 @{text 0} and @{const Suc}. Thus the values of type @{typ nat} are
    36 @{text 0} and @{const Suc}. Thus the values of type @{typ nat} are
    37 @{text 0}, @{term"Suc 0"}, @{term"Suc(Suc 0)"}, etc.
    37 @{text 0}, @{term"Suc 0"}, @{term"Suc(Suc 0)"}, etc.
    38 There are many predefined functions: @{text "+"}, @{text "*"}, @{text
    38 There are many predefined functions: @{text "+"}, @{text "*"}, @{text
    39 "\<le>"}, etc. Here is how you could define your own addition:
    39 "\<le>"}, etc. Here is how you could define your own addition:
    40 *}
    40 \<close>
    41 
    41 
    42 fun add :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
    42 fun add :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
    43 "add 0 n = n" |
    43 "add 0 n = n" |
    44 "add (Suc m) n = Suc(add m n)"
    44 "add (Suc m) n = Suc(add m n)"
    45 
    45 
    46 text{* And here is a proof of the fact that @{prop"add m 0 = m"}: *}
    46 text\<open>And here is a proof of the fact that @{prop"add m 0 = m"}:\<close>
    47 
    47 
    48 lemma add_02: "add m 0 = m"
    48 lemma add_02: "add m 0 = m"
    49 apply(induction m)
    49 apply(induction m)
    50 apply(auto)
    50 apply(auto)
    51 done
    51 done
    52 (*<*)
    52 (*<*)
    53 lemma "add m 0 = m"
    53 lemma "add m 0 = m"
    54 apply(induction m)
    54 apply(induction m)
    55 (*>*)
    55 (*>*)
    56 txt{* The \isacom{lemma} command starts the proof and gives the lemma
    56 txt\<open>The \isacom{lemma} command starts the proof and gives the lemma
    57 a name, @{text add_02}. Properties of recursively defined functions
    57 a name, @{text add_02}. Properties of recursively defined functions
    58 need to be established by induction in most cases.
    58 need to be established by induction in most cases.
    59 Command \isacom{apply}@{text"(induction m)"} instructs Isabelle to
    59 Command \isacom{apply}@{text"(induction m)"} instructs Isabelle to
    60 start a proof by induction on @{text m}. In response, it will show the
    60 start a proof by induction on @{text m}. In response, it will show the
    61 following proof state\ifsem\footnote{See page \pageref{proof-state} for how to
    61 following proof state\ifsem\footnote{See page \pageref{proof-state} for how to
    73 using first the definition of @{const add} and then the induction hypothesis.
    73 using first the definition of @{const add} and then the induction hypothesis.
    74 In summary, both subproofs rely on simplification with function definitions and
    74 In summary, both subproofs rely on simplification with function definitions and
    75 the induction hypothesis.
    75 the induction hypothesis.
    76 As a result of that final \isacom{done}, Isabelle associates the lemma
    76 As a result of that final \isacom{done}, Isabelle associates the lemma
    77 just proved with its name. You can now inspect the lemma with the command
    77 just proved with its name. You can now inspect the lemma with the command
    78 *}
    78 \<close>
    79 
    79 
    80 thm add_02
    80 thm add_02
    81 
    81 
    82 txt{* which displays @{thm[show_question_marks,display] add_02} The free
    82 txt\<open>which displays @{thm[show_question_marks,display] add_02} The free
    83 variable @{text m} has been replaced by the \concept{unknown}
    83 variable @{text m} has been replaced by the \concept{unknown}
    84 @{text"?m"}. There is no logical difference between the two but there is an
    84 @{text"?m"}. There is no logical difference between the two but there is an
    85 operational one: unknowns can be instantiated, which is what you want after
    85 operational one: unknowns can be instantiated, which is what you want after
    86 some lemma has been proved.
    86 some lemma has been proved.
    87 
    87 
   151 
   151 
   152 \subsection{Type \indexed{@{text list}}{list}}
   152 \subsection{Type \indexed{@{text list}}{list}}
   153 
   153 
   154 Although lists are already predefined, we define our own copy for
   154 Although lists are already predefined, we define our own copy for
   155 demonstration purposes:
   155 demonstration purposes:
   156 *}
   156 \<close>
   157 (*<*)
   157 (*<*)
   158 apply(auto)
   158 apply(auto)
   159 done 
   159 done 
   160 declare [[names_short]]
   160 declare [[names_short]]
   161 (*>*)
   161 (*>*)
   162 datatype 'a list = Nil | Cons 'a "'a list"
   162 datatype 'a list = Nil | Cons 'a "'a list"
   163 (*<*)
   163 (*<*)
   164 for map: map
   164 for map: map
   165 (*>*)
   165 (*>*)
   166 
   166 
   167 text{*
   167 text\<open>
   168 \begin{itemize}
   168 \begin{itemize}
   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).
   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).
   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"}).
   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"}).
   171 Hence all lists are of the form @{const Nil}, or @{term"Cons x Nil"},
   171 Hence all lists are of the form @{const Nil}, or @{term"Cons x Nil"},
   172 or @{term"Cons x (Cons y Nil)"}, etc.
   172 or @{term"Cons x (Cons y Nil)"}, etc.
   173 \item \isacom{datatype} requires no quotation marks on the
   173 \item \isacom{datatype} requires no quotation marks on the
   174 left-hand side, but on the right-hand side each of the argument
   174 left-hand side, but on the right-hand side each of the argument
   175 types of a constructor needs to be enclosed in quotation marks, unless
   175 types of a constructor needs to be enclosed in quotation marks, unless
   176 it is just an identifier (e.g., @{typ nat} or @{typ 'a}).
   176 it is just an identifier (e.g., @{typ nat} or @{typ 'a}).
   177 \end{itemize}
   177 \end{itemize}
   178 We also define two standard functions, append and reverse: *}
   178 We also define two standard functions, append and reverse:\<close>
   179 
   179 
   180 fun app :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   180 fun app :: "'a list \<Rightarrow> 'a list \<Rightarrow> 'a list" where
   181 "app Nil ys = ys" |
   181 "app Nil ys = ys" |
   182 "app (Cons x xs) ys = Cons x (app xs ys)"
   182 "app (Cons x xs) ys = Cons x (app xs ys)"
   183 
   183 
   184 fun rev :: "'a list \<Rightarrow> 'a list" where
   184 fun rev :: "'a list \<Rightarrow> 'a list" where
   185 "rev Nil = Nil" |
   185 "rev Nil = Nil" |
   186 "rev (Cons x xs) = app (rev xs) (Cons x Nil)"
   186 "rev (Cons x xs) = app (rev xs) (Cons x Nil)"
   187 
   187 
   188 text{* By default, variables @{text xs}, @{text ys} and @{text zs} are of
   188 text\<open>By default, variables @{text xs}, @{text ys} and @{text zs} are of
   189 @{text list} type.
   189 @{text list} type.
   190 
   190 
   191 Command \indexed{\isacommand{value}}{value} evaluates a term. For example, *}
   191 Command \indexed{\isacommand{value}}{value} evaluates a term. For example,\<close>
   192 
   192 
   193 value "rev(Cons True (Cons False Nil))"
   193 value "rev(Cons True (Cons False Nil))"
   194 
   194 
   195 text{* yields the result @{value "rev(Cons True (Cons False Nil))"}. This works symbolically, too: *}
   195 text\<open>yields the result @{value "rev(Cons True (Cons False Nil))"}. This works symbolically, too:\<close>
   196 
   196 
   197 value "rev(Cons a (Cons b Nil))"
   197 value "rev(Cons a (Cons b Nil))"
   198 
   198 
   199 text{* yields @{value "rev(Cons a (Cons b Nil))"}.
   199 text\<open>yields @{value "rev(Cons a (Cons b Nil))"}.
   200 \medskip
   200 \medskip
   201 
   201 
   202 Figure~\ref{fig:MyList} shows the theory created so far.
   202 Figure~\ref{fig:MyList} shows the theory created so far.
   203 Because @{text list}, @{const Nil}, @{const Cons}, etc.\ are already predefined,
   203 Because @{text list}, @{const Nil}, @{const Cons}, etc.\ are already predefined,
   204  Isabelle prints qualified (long) names when executing this theory, for example, @{text MyList.Nil}
   204  Isabelle prints qualified (long) names when executing this theory, for example, @{text MyList.Nil}
   236 \subsection{The Proof Process}
   236 \subsection{The Proof Process}
   237 
   237 
   238 We will now demonstrate the typical proof process, which involves
   238 We will now demonstrate the typical proof process, which involves
   239 the formulation and proof of auxiliary lemmas.
   239 the formulation and proof of auxiliary lemmas.
   240 Our goal is to show that reversing a list twice produces the original
   240 Our goal is to show that reversing a list twice produces the original
   241 list. *}
   241 list.\<close>
   242 
   242 
   243 theorem rev_rev [simp]: "rev(rev xs) = xs"
   243 theorem rev_rev [simp]: "rev(rev xs) = xs"
   244 
   244 
   245 txt{* Commands \isacom{theorem} and \isacom{lemma} are
   245 txt\<open>Commands \isacom{theorem} and \isacom{lemma} are
   246 interchangeable and merely indicate the importance we attach to a
   246 interchangeable and merely indicate the importance we attach to a
   247 proposition. Via the bracketed attribute @{text simp} we also tell Isabelle
   247 proposition. Via the bracketed attribute @{text simp} we also tell Isabelle
   248 to make the eventual theorem a \conceptnoidx{simplification rule}: future proofs
   248 to make the eventual theorem a \conceptnoidx{simplification rule}: future proofs
   249 involving simplification will replace occurrences of @{term"rev(rev xs)"} by
   249 involving simplification will replace occurrences of @{term"rev(rev xs)"} by
   250 @{term"xs"}. The proof is by induction: *}
   250 @{term"xs"}. The proof is by induction:\<close>
   251 
   251 
   252 apply(induction xs)
   252 apply(induction xs)
   253 
   253 
   254 txt{*
   254 txt\<open>
   255 As explained above, we obtain two subgoals, namely the base case (@{const Nil}) and the induction step (@{const Cons}):
   255 As explained above, we obtain two subgoals, namely the base case (@{const Nil}) and the induction step (@{const Cons}):
   256 @{subgoals[display,indent=0,margin=65]}
   256 @{subgoals[display,indent=0,margin=65]}
   257 Let us try to solve both goals automatically:
   257 Let us try to solve both goals automatically:
   258 *}
   258 \<close>
   259 
   259 
   260 apply(auto)
   260 apply(auto)
   261 
   261 
   262 txt{*Subgoal~1 is proved, and disappears; the simplified version
   262 txt\<open>Subgoal~1 is proved, and disappears; the simplified version
   263 of subgoal~2 becomes the new subgoal~1:
   263 of subgoal~2 becomes the new subgoal~1:
   264 @{subgoals[display,indent=0,margin=70]}
   264 @{subgoals[display,indent=0,margin=70]}
   265 In order to simplify this subgoal further, a lemma suggests itself.
   265 In order to simplify this subgoal further, a lemma suggests itself.
   266 
   266 
   267 \subsubsection{A First Lemma}
   267 \subsubsection{A First Lemma}
   268 
   268 
   269 We insert the following lemma in front of the main theorem:
   269 We insert the following lemma in front of the main theorem:
   270 *}
   270 \<close>
   271 (*<*)
   271 (*<*)
   272 oops
   272 oops
   273 (*>*)
   273 (*>*)
   274 lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
   274 lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
   275 
   275 
   276 txt{* There are two variables that we could induct on: @{text xs} and
   276 txt\<open>There are two variables that we could induct on: @{text xs} and
   277 @{text ys}. Because @{const app} is defined by recursion on
   277 @{text ys}. Because @{const app} is defined by recursion on
   278 the first argument, @{text xs} is the correct one:
   278 the first argument, @{text xs} is the correct one:
   279 *}
   279 \<close>
   280 
   280 
   281 apply(induction xs)
   281 apply(induction xs)
   282 
   282 
   283 txt{* This time not even the base case is solved automatically: *}
   283 txt\<open>This time not even the base case is solved automatically:\<close>
   284 apply(auto)
   284 apply(auto)
   285 txt{*
   285 txt\<open>
   286 \vspace{-5ex}
   286 \vspace{-5ex}
   287 @{subgoals[display,goals_limit=1]}
   287 @{subgoals[display,goals_limit=1]}
   288 Again, we need to abandon this proof attempt and prove another simple lemma
   288 Again, we need to abandon this proof attempt and prove another simple lemma
   289 first.
   289 first.
   290 
   290 
   291 \subsubsection{A Second Lemma}
   291 \subsubsection{A Second Lemma}
   292 
   292 
   293 We again try the canonical proof procedure:
   293 We again try the canonical proof procedure:
   294 *}
   294 \<close>
   295 (*<*)
   295 (*<*)
   296 oops
   296 oops
   297 (*>*)
   297 (*>*)
   298 lemma app_Nil2 [simp]: "app xs Nil = xs"
   298 lemma app_Nil2 [simp]: "app xs Nil = xs"
   299 apply(induction xs)
   299 apply(induction xs)
   300 apply(auto)
   300 apply(auto)
   301 done
   301 done
   302 
   302 
   303 text{*
   303 text\<open>
   304 Thankfully, this worked.
   304 Thankfully, this worked.
   305 Now we can continue with our stuck proof attempt of the first lemma:
   305 Now we can continue with our stuck proof attempt of the first lemma:
   306 *}
   306 \<close>
   307 
   307 
   308 lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
   308 lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
   309 apply(induction xs)
   309 apply(induction xs)
   310 apply(auto)
   310 apply(auto)
   311 
   311 
   312 txt{*
   312 txt\<open>
   313 We find that this time @{text"auto"} solves the base case, but the
   313 We find that this time @{text"auto"} solves the base case, but the
   314 induction step merely simplifies to
   314 induction step merely simplifies to
   315 @{subgoals[display,indent=0,goals_limit=1]}
   315 @{subgoals[display,indent=0,goals_limit=1]}
   316 The missing lemma is associativity of @{const app},
   316 The missing lemma is associativity of @{const app},
   317 which we insert in front of the failed lemma @{text rev_app}.
   317 which we insert in front of the failed lemma @{text rev_app}.
   318 
   318 
   319 \subsubsection{Associativity of @{const app}}
   319 \subsubsection{Associativity of @{const app}}
   320 
   320 
   321 The canonical proof procedure succeeds without further ado:
   321 The canonical proof procedure succeeds without further ado:
   322 *}
   322 \<close>
   323 (*<*)oops(*>*)
   323 (*<*)oops(*>*)
   324 lemma app_assoc [simp]: "app (app xs ys) zs = app xs (app ys zs)"
   324 lemma app_assoc [simp]: "app (app xs ys) zs = app xs (app ys zs)"
   325 apply(induction xs)
   325 apply(induction xs)
   326 apply(auto)
   326 apply(auto)
   327 done
   327 done
   334 theorem rev_rev [simp]: "rev(rev xs) = xs"
   334 theorem rev_rev [simp]: "rev(rev xs) = xs"
   335 apply(induction xs)
   335 apply(induction xs)
   336 apply(auto)
   336 apply(auto)
   337 done
   337 done
   338 (*>*)
   338 (*>*)
   339 text{*
   339 text\<open>
   340 Finally the proofs of @{thm[source] rev_app} and @{thm[source] rev_rev}
   340 Finally the proofs of @{thm[source] rev_app} and @{thm[source] rev_rev}
   341 succeed, too.
   341 succeed, too.
   342 
   342 
   343 \subsubsection{Another Informal Proof}
   343 \subsubsection{Another Informal Proof}
   344 
   344 
   455 \begin{exercise}
   455 \begin{exercise}
   456 Define a recursive function @{text "sum_upto ::"} @{typ"nat \<Rightarrow> nat"} such that
   456 Define a recursive function @{text "sum_upto ::"} @{typ"nat \<Rightarrow> nat"} such that
   457 \mbox{@{text"sum_upto n"}} @{text"="} @{text"0 + ... + n"} and prove
   457 \mbox{@{text"sum_upto n"}} @{text"="} @{text"0 + ... + n"} and prove
   458 @{prop" sum_upto (n::nat) = n * (n+1) div 2"}.
   458 @{prop" sum_upto (n::nat) = n * (n+1) div 2"}.
   459 \end{exercise}
   459 \end{exercise}
   460 *}
   460 \<close>
   461 (*<*)
   461 (*<*)
   462 end
   462 end
   463 (*>*)
   463 (*>*)