Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Bool_nat_list.thy

  Sprache: Isabelle
 

(*<*)
theory Bool_nat_list
imports Complex_Main
begin
(*>*)

text
 vspace{-4ex}
 section{\texorpdfstring{Types typbool, typnat and list}{Types bool, nat and list}}

  are the most important predefined types. We go through them one by one.
  on examples we learn how to define (possibly recursive) functions and
  theorems about them by induction and simplification.

 subsection{Type \indexed{typbool}{bool}}

  type of boolean values is a predefined datatype
 {datatype[display] bool}
  the two values \indexed{constTrue}{True} and \indexed{constFalse}{False} and
  many predefined functions: ¬, , , , etc. Here is how conjunction could be defined by pattern matching:
 


fun conj :: "bool bool bool" where
"conj True True = True" |
"conj _ _ = False"

textBoth the datatype and function definitions roughly follow the syntax
  functional programming languages.

 subsection{Type \indexed{typnat}{nat}}

  numbers are another predefined datatype:
 {datatype[display] nat}\index{Suc@constSuc}
  values of type typnat are generated by the constructors
 0 and constSuc. Thus the values of type typnat are
 0, termSuc 0, termSuc(Suc 0), etc.
  are many predefined functions: +, *, , etc. Here is how you could define your own addition:
 


fun add :: "nat nat nat" where
"add 0 n = n" |
"add (Suc m) n = Suc(add m n)"

textAnd here is a proof of the fact that propadd m 0 = m:

lemma add_02: "add m 0 = m"
apply(induction m)
apply(auto)
done
(*<*)
lemma "add m 0 = m"
apply(induction m)
(*>*)
txtThe \isacom{lemma} command starts the proof and gives the lemma
  name, add_02. Properties of recursively defined functions
  to be established by induction in most cases.
  \isacom{apply}(induction m) instructs Isabelle to
  a proof by induction on m. In response, it will show the
  proof state\ifsem\footnote{See page \pageref{proof-state} for how to
  the proof state.}\fi:
 {subgoals[display,indent=0]}
  numbered lines are known as \emph{subgoals}.
  first subgoal is the base case, the second one the induction step.
  prefix m. is Isabelle's way of saying ``for an arbitrary but fixed m''. The ==> separates assumptions from the conclusion.
  command \isacom{apply}(auto) instructs Isabelle to try
  prove all subgoals automatically, essentially by simplifying them.
  both subgoals are easy, Isabelle can do it.
  base case propadd 0 0 = 0 holds by definition of constadd,
  the induction step is almost as simple:
 add🚫~(Suc m) 0 = Suc(add m 0) = Suc m
  first the definition of constadd and then the induction hypothesis.
  summary, both subproofs rely on simplification with function definitions and
  induction hypothesis.
  a result of that final \isacom{done}, Isabelle associates the lemma
  proved with its name. You can now inspect the lemma with the command
 


thm add_02

txtwhich displays @{thm[show_question_marks,display] add_02} The free
  m has been replaced by the \concept{unknown}
 ?m. There is no logical difference between the two but there is an
  one: unknowns can be instantiated, which is what you want after
  lemma has been proved.

  that there is also a proof method induct, which behaves almost
  induction; the difference is explained in \autoref{ch:Isar}.

 begin{warn}
 : We use \concept{lemma}, \concept{theorem} and \concept{rule}
  for propositions that have been proved.
 end{warn}
 begin{warn}
 Numerals (0, 1, 2, \dots) and most of the standard
 arithmetic operations (+, -, *, ,
 <\<close>, etc.) are overloaded: they are available
 not just for natural numbers but for other types as well.
 For example, given the goal x + 0 = x, there is nothing to indicate
 that you are talking about natural numbers. Hence Isabelle can only infer
 that termx is of some arbitrary type where 0 and +
 exist. As a consequence, you will be unable to prove the goal.
  To alert you to such pitfalls, Isabelle flags numerals without a
  fixed type in its output: @ {prop"x+0 = x"}.
 In this particular example, you need to include
 an explicit type constraint, for example x+0 = (x::nat). If there
 is enough contextual information this may not be necessary: propSuc x =
 x
automatically implies x::nat because termSuc is not
 overloaded.
 end{warn}

 subsubsection{An Informal Proof}

  we gave some terse informal explanation of the proof of
 propadd m 0 = m. A more detailed informal exposition of the lemma
  look like this:
 bigskip

 noindent
 textbf{Lemma} propadd m 0 = m

 noindent
 textbf{Proof} by induction on m.
 begin{itemize}
 item Case 0 (the base case): propadd 0 0 = 0
 holds by definition of constadd.
 item Case termSuc m (the induction step):
 We assume propadd m 0 = m, the induction hypothesis (IH),
 and we need to show add (Suc m) 0 = Suc m.
 The proof is as follows:\smallskip

 \begin{tabular}{@ {}rcl@ {\quad}l@ {}}
 termadd (Suc m) 0 &=& termSuc(add m 0)
 & by definition of add\\
 &=& termSuc m & by IH
 \end{tabular}
 end{itemize}
  this book, \concept{IH} will stand for ``induction hypothesis''.

  have now seen three proofs of propadd m 0 = 0: the Isabelle one, the
  four lines explaining the base case and the induction step, and just now a
  of a traditional inductive proof. The three proofs differ in the level
  detail given and the intended reader: the Isabelle proof is for the
 , the informal proofs are for humans. Although this book concentrates
  Isabelle proofs, it is important to be able to rephrase those proofs
  informal text comprehensible to a reader familiar with traditional
  proofs. Later on we will introduce an Isabelle proof language
  is closer to traditional informal mathematical language and is often
  readable.

 subsection{Type \indexed{list}{list}}

  lists are already predefined, we define our own copy for
  purposes:
 

(*<*)

apply(auto)
done 
declare [[names_short]]
(*>*)
datatype 'a list = Nil | Cons 'a "'a list"
(*<*)
for map: map
(*>*)

text
 begin{itemize}
 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).
 item Lists have two constructors: constNil, the empty list, and constCons, which puts an element (of type typ'a) in front of a list (of type typ'a list).
  all lists are of the form constNil, or termCons x Nil,
  termCons x (Cons y Nil), etc.
 item \isacom{datatype} requires no quotation marks on the
 -hand side, but on the right-hand side each of the argument
  of a constructor needs to be enclosed in quotation marks, unless
  is just an identifier (e.g., typnat or typ'a).
 end{itemize}
  also define two standard functions, append and reverse:


fun app :: "'a list 'a list 'a list" where
"app Nil ys = ys" |
"app (Cons x xs) ys = Cons x (app xs ys)"

fun rev :: "'a list 'a list" where
"rev Nil = Nil" |
"rev (Cons x xs) = app (rev xs) (Cons x Nil)"

textBy default, variables xs, ys and zs are of
 list type.

  \indexed{\isacom{value}}{value} evaluates a term. For example,


value "rev(Cons True (Cons False Nil))"

textyields the result 🚫rev(Cons True (Cons False Nil)). This works symbolically, too:

value "rev(Cons a (Cons b Nil))"

textyields 🚫rev(Cons a (Cons b Nil)).
 medskip

 ~\ref{fig:MyList} shows the theory created so far.
  list, constNil, constCons, etc.are already predefined,
 Isabelle prints qualified (long) names when executing this theory, for example, MyList.Nil
 instead of constNil.
 To suppress the qualified names you can insert the command
 \texttt{declare [[names\_short]]}.
 This is not recommended in general but is convenient for this unusual example.
  Notice where the
 quotations marks are needed that we mostly sweep under the carpet. In
 particular, notice that \isacom{datatype} requires no quotation marks on the
 left-hand side, but that on the right-hand side each of the argument
 types of a constructor needs to be enclosed in quotation marks.

 begin{figure}[htbp]
 begin{alltt}
 input{MyList.thy}\end{alltt}
 caption{A theory of lists}
 label{fig:MyList}
 index{comment}
 end{figure}

 subsubsection{Structural Induction for Lists}

  as for natural numbers, there is a proof principle of induction for
 . Induction over a list is essentially induction over the length of
  list, although the length remains implicit. To prove that some property
 P holds for all lists xs, i.e., \mbox{propP(xs)},
  need to prove
 begin{enumerate}
 item the base case propP(Nil) and
 item the inductive case propP(Cons x xs) under the assumption propP(xs), for some arbitrary but fixed x and xs.
 end{enumerate}
  is often called \concept{structural induction} for lists.

 subsection{The Proof Process}

  will now demonstrate the typical proof process, which involves
  formulation and proof of auxiliary lemmas.
  goal is to show that reversing a list twice produces the original
 .


theorem rev_rev [simp]: "rev(rev xs) = xs"

txtCommands \isacom{theorem} and \isacom{lemma} are
  and merely indicate the importance we attach to a
 . Via the bracketed attribute simp we also tell Isabelle
  make the eventual theorem a \conceptnoidx{simplification rule}: future proofs
  simplification will replace occurrences of termrev(rev xs) by
 termxs. The proof is by induction:


apply(induction xs)

txt
  explained above, we obtain two subgoals, namely the base case (constNil) and the induction step (constCons):
 {subgoals[display,indent=0,margin=65]}
  us try to solve both goals automatically:
 


apply(auto)

txtSubgoal~1 is proved, and disappears; the simplified version
  subgoal~2 becomes the new subgoal~1:
 {subgoals[display,indent=0,margin=70]}
  order to simplify this subgoal further, a lemma suggests itself.

 subsubsection{A First Lemma}

  insert the following lemma in front of the main theorem:
 

(*<*)
oops
(*>*)
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"

txtThere are two variables that we could induct on: xs and
 ys. Because constapp is defined by recursion on
  first argument, xs is the correct one:
 


apply(induction xs)

txtThis time not even the base case is solved automatically:
apply(auto)
txt
 vspace{-5ex}
 {subgoals[display,goals_limit=1]}
 , we need to abandon this proof attempt and prove another simple lemma
 .

 subsubsection{A Second Lemma}

  again try the canonical proof procedure:
 

(*<*)
oops
(*>*)
lemma app_Nil2 [simp]: "app xs Nil = xs"
apply(induction xs)
apply(auto)
done

text
 , this worked.
  we can continue with our stuck proof attempt of the first lemma:
 


lemma rev_app [simp]: "rev(app xs ys) = app (rev ys) (rev xs)"
apply(induction xs)
apply(auto)

txt
  find that this time auto solves the base case, but the
  step merely simplifies to
 {subgoals[display,indent=0,goals_limit=1]}
  missing lemma is associativity of constapp,
  we insert in front of the failed lemma rev_app.

 subsubsection{Associativity of constapp}

  canonical proof procedure succeeds without further ado:
 

(*<*)oops(*>*)
lemma app_assoc [simp]: "app (app xs ys) zs = app xs (app ys zs)"
apply(induction xs)
apply(auto)
done
(*<*)
lemma rev_app [simp]: "rev(app xs ys) = app (rev ys)(rev xs)"
apply(induction xs)
apply(auto)
done

theorem rev_rev [simp]: "rev(rev xs) = xs"
apply(induction xs)
apply(auto)
done
(*>*)
text
  the proofs of @{thm[source] rev_app} and @{thm[source] rev_rev}
 , too.

 subsubsection{Another Informal Proof}

  is the informal proof of associativity of constapp
  to the Isabelle proof above.
 bigskip

 noindent
 textbf{Lemma} propapp (app xs ys) zs = app xs (app ys zs)

 noindent
 textbf{Proof} by induction on xs.
 begin{itemize}
 item Case Nil: propapp (app Nil ys) zs = app ys zs =
 \mbox{termapp Nil (app ys zs)} holds by definition of app.
 item Case Cons x xs: We assume
 \begin{center} \hfill termapp (app xs ys) zs =
 termapp xs (app ys zs) \hfill (IH) \end{center}
 and we need to show
 \begin{center} propapp (app (Cons x xs) ys) zs = app (Cons x xs) (app ys zs).\end{center}
 The proof is as follows:\smallskip

 \begin{tabular}{@ {}l@ {\quad}l@ {}}
 termapp (app (Cons x xs) ys) zs\\
 = app (Cons x (app xs ys)) zs & by definition of app\\
 = Cons x (app (app xs ys) zs) & by definition of app\\
 = Cons x (app xs (app ys zs)) & by IH\\
 = app (Cons x xs) (app ys zs) & by definition of app
 \end{tabular}
 end{itemize}
 medskip

 noindent Didn't we say earlier that all proofs are by simplification? But
  both cases, going from left to right, the last equality step is not a
  at all! In the base case it is propapp ys zs = app Nil (app
  zs)
. It appears almost mysterious because we suddenly complicate the
  by appending Nil on the left. What is really going on is this:
  proving some equality \mbox{props = t}, both s and t are
  until they ``meet in the middle''. This heuristic for equality proofs
  well for a functional programming context like ours. In the base case
  termapp (app Nil ys) zs and termapp Nil (app
  zs)
are simplified to termapp ys zs, the term in the middle.

 subsection{Predefined Lists}
 label{sec:predeflists}

 's predefined lists are the same as the ones above, but with
  syntactic sugar:
 begin{itemize}
 item [] is \indexed{constNil}{Nil},
 item termx # xs is termCons x xs\index{Cons@constCons},
 item [x1, , xn] is x1 # # xn # [], and
 item termxs @ ys is termapp xs ys.
 end{itemize}
  is also a large library of predefined functions.
  most important ones are the length function
 length :: 'a list nat\index{length@constlength} (with the obvious definition),
  the \indexed{constmap}{map} function that applies a function to all elements of a list:
 begin{isabelle}
 isacom{fun} constmap :: @{typ[source] "('a 'b) 'a list 'b list"} \isacom{where}\\
 "@{thm list.map(1) [of f]}" |\\
 "@{thm list.map(2) [of f x xs]}"
 end{isabelle}

 ifsem
  useful are the \concept{head} of a list, its first element,
  the \concept{tail}, the rest of the list:
 begin{isabelle}\index{hd@consthd}
 isacom{fun} hd :: 'a list 'a\\
 prophd(x#xs) = x
 end{isabelle}
 begin{isabelle}\index{tl@consttl}
 isacom{fun} tl :: 'a list 'a list\\
 proptl [] = [] |\\
 proptl(x#xs) = xs
 end{isabelle}
  that since HOL is a logic of total functions, termhd [] is defined,
  we do not know what the result is. That is, termhd [] is not undefined
  underdefined.
 fi
 

  now on lists are always the predefined lists.

 ifsem\else
 subsection{Types typint and typreal}

  addition to typnat there are also the types typint and typreal, the mathematical integers
  real numbers. As mentioned above, numerals and most of the standard arithmetic operations are overloaded.
  particular they are defined on typint and typreal.

 begin{warn}
  are two infix exponentiation operators:
 term(^) for typnat and typint (with exponent of type typnat in both cases)
  term(powr) for typreal.
 end{warn}
 begin{warn}
  typint is already part of theory 🚫Main, but in order to use typreal as well, you have to import
  🚫Complex_Main instead of 🚫Main.
 end{warn}

  are three coercion functions that are inclusions and do not lose information:
 begin{quote}
 begin{tabular}{rcl}
 constint &::& typnat int\\
 constreal &::& typnat real\\
 constreal_of_int &::& typint real\\
 end{tabular}
 end{quote}

  inserts these inclusions automatically once you import Complex_Main.
  there are multiple type-correct completions, Isabelle chooses an arbitrary one.
  example, the input \noquotes{@{term[source] "(i::int) + (n::nat)"}} has the unique
 -correct completion term(i::int) + int(n::nat). In contrast,
 noquotes{@{term[source] "((n::nat) + n) :: real"}} has two type-correct completions,
 noquotes{@{term[source]"real(n+n)"}} and \noquotes{@{term[source]"real n + real n"}}.

  are also the coercion functions in the other direction:
 begin{quote}
 begin{tabular}{rcl}
 constnat &::& typint nat\\
 constfloor &::& typreal int\\
 constceiling &::& typreal int\\
 end{tabular}
 end{quote}
 fi

 subsection*{Exercises}

 begin{exercise}
  the \isacom{value} command to evaluate the following expressions:
 {term[source] "1 + (2::nat)"}, @{term[source] "1 + (2::int)"},
 {term[source] "1 - (2::nat)"} and @{term[source] "1 - (2::int)"}.
 end{exercise}

 begin{exercise}
  from the definition of constadd given above.
  that constadd is associative and commutative.
  a recursive function double :: typnat nat
  prove propdouble m = add m m.
 end{exercise}

 begin{exercise}
  a function count :: typ'a 'a list nat
  counts the number of occurrences of an element in a list. Prove
 propcount x xs length xs.
 end{exercise}

 begin{exercise}
  a recursive function snoc :: typ'a list 'a 'a list
  appends an element to the end of a list. With the help of snoc
  a recursive function reverse :: typ'a list 'a list
  reverses a list. Prove propreverse(reverse xs) = xs.
 end{exercise}

 begin{exercise}
  a recursive function sum_upto :: typnat nat such that
 mbox{sum_upto n} = 0 + ... + n and prove
 prop sum_upto (n::nat) = n * (n+1) div 2.
 end{exercise}
 

(*<*)
end
(*>*)

Messung V0.5 in Prozent
C=79 H=90 G=84

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002