CookBook/FirstSteps.thy
changeset 50 3d4b49921cdb
parent 49 a0edabf14457
child 52 a04bdee4fb1e
equal deleted inserted replaced
49:a0edabf14457 50:3d4b49921cdb
     5 
     5 
     6 chapter {* First Steps *}
     6 chapter {* First Steps *}
     7 
     7 
     8 text {*
     8 text {*
     9 
     9 
    10   Isabelle programming is done in Standard ML.
    10   Isabelle programming is done in SML.  Just like lemmas and proofs, SML-code
    11   Just like lemmas and proofs, SML-code in Isabelle is part of a 
    11   in Isabelle is part of a theory. If you want to follow the code written in
    12   theory. If you want to follow the code written in this chapter, we 
    12   this chapter, we assume you are working inside the theory defined by
    13   assume you are working inside the theory defined by
       
    14 
    13 
    15   \begin{center}
    14   \begin{center}
    16   \begin{tabular}{@ {}l}
    15   \begin{tabular}{@ {}l}
    17   \isacommand{theory} FirstSteps\\
    16   \isacommand{theory} FirstSteps\\
    18   \isacommand{imports} Main\\
    17   \isacommand{imports} Main\\
    62 
    61 
    63 section {* Debugging and Printing *}
    62 section {* Debugging and Printing *}
    64 
    63 
    65 text {*
    64 text {*
    66 
    65 
    67   During developments you might find it necessary to quickly inspect some data
    66   During development you might find it necessary to inspect some data
    68   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    67   in your code. This can be done in a ``quick-and-dirty'' fashion using 
    69   the function @{ML "warning"}. For example 
    68   the function @{ML "warning"}. For example 
    70 
    69 
    71   @{ML [display] "warning \"any string\""}
    70   @{ML [display] "warning \"any string\""}
    72 
    71 
    73   will print out @{ML_text [quotes] "any string"} inside the response buffer of Isabelle.
    72   will print out @{ML_text [quotes] "any string"} inside the response buffer
    74   If you develop under PolyML, then there is a convenient, though again 
    73   of Isabelle.  This function expects a string. If you develop under PolyML,
    75   ``quick-and-dirty'', method for converting values into strings, 
    74   then there is a convenient, though again ``quick-and-dirty'', method for
    76   for example: 
    75   converting values into strings, for example:
    77 
    76 
    78   @{ML [display] "warning (makestring 1)"} 
    77   @{ML [display] "warning (makestring 1)"} 
    79 
    78 
    80   However this only works if the type of what is converted is monomorphic and is not 
    79   However this only works if the type of what is converted is monomorphic and is not 
    81   a function.
    80   a function.
    82 
    81 
    83   The funtion @{ML "warning"} should only be used for testing purposes, because any
    82   The funtion @{ML "warning"} should only be used for testing purposes, because any
    84   output this funtion generates will be overwritten as soon as an error is
    83   output this funtion generates will be overwritten as soon as an error is
    85   raised. Therefore for printing anything more serious and elaborate, the
    84   raised. For printing anything more serious and elaborate, the
    86   function @{ML tracing} should be used. This function writes all output into
    85   function @{ML tracing} should be used. This function writes all output into
    87   a separate tracing buffer. For example
    86   a separate tracing buffer. For example
    88 
    87 
    89   @{ML [display] "tracing \"foo\""}
    88   @{ML [display] "tracing \"foo\""}
    90 
    89 
    91   It is also possible to redirect the channel where the @{ML_text "foo"} is 
    90   It is also possible to redirect the ``channel'' where the @{ML_text "foo"} is 
    92   printed to a separate file, e.g. to prevent Proof General from choking on massive 
    91   printed to a separate file, e.g. to prevent Proof General from choking on massive 
    93   amounts of trace output. This rediretion can be achieved using the code
    92   amounts of trace output. This rediretion can be achieved using the code
    94 *}
    93 *}
    95 
    94 
    96 ML{* 
    95 ML{* 
   154   In a similar way you can use antiquotations to refer to theorems or simpsets:
   153   In a similar way you can use antiquotations to refer to theorems or simpsets:
   155 
   154 
   156   @{ML [display] "@{thm allI}"}
   155   @{ML [display] "@{thm allI}"}
   157   @{ML [display] "@{simpset}"}
   156   @{ML [display] "@{simpset}"}
   158 
   157 
   159   While antiquotations nowadays have many applications, they were originally introduced to 
   158   While antiquotations have many applications, they were originally introduced to 
   160   avoid explicit bindings for theorems such as
   159   avoid explicit bindings for theorems such as
   161 *}
   160 *}
   162 
   161 
   163 ML {*
   162 ML {*
   164 val allI = thm "allI"
   163 val allI = thm "allI"
   166 
   165 
   167 text {*
   166 text {*
   168   These bindings were difficult to maintain and also could be accidentally
   167   These bindings were difficult to maintain and also could be accidentally
   169   overwritten by the user. This usually broke definitional
   168   overwritten by the user. This usually broke definitional
   170   packages. Antiquotations solve this problem, since they are ``linked''
   169   packages. Antiquotations solve this problem, since they are ``linked''
   171   statically at compile-time. However, that also sometimes limits there
   170   statically at compile-time. However, that also sometimes limits their
   172   applicability. In the course of this introduction, we will learn more about
   171   applicability. In the course of this introduction, we will learn more about
   173   these antiquotations: they greatly simplify Isabelle programming since one
   172   these antiquotations: they greatly simplify Isabelle programming since one
   174   can directly access all kinds of logical elements from ML.
   173   can directly access all kinds of logical elements from ML.
   175 
   174 
   176 *}
   175 *}
   182   \mbox{@{text "@{term \<dots>}"}}. For example
   181   \mbox{@{text "@{term \<dots>}"}}. For example
   183 
   182 
   184   @{ML_response [display] "@{term \"(a::nat) + b = c\"}" 
   183   @{ML_response [display] "@{term \"(a::nat) + b = c\"}" 
   185                           "Const (\"op =\", \<dots>)  $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   184                           "Const (\"op =\", \<dots>)  $ (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   186 
   185 
   187   This will show the term @{term "(a::nat) + b = c"}, but printed out using the internal
   186   This will show the term @{term "(a::nat) + b = c"}, but printed using the internal
   188   representation of this term. This internal representation corresponds to the 
   187   representation of this term. This internal representation corresponds to the 
   189   datatype @{ML_type "term"}.
   188   datatype @{ML_type "term"}.
   190   
   189   
   191   The internal representation of terms uses the usual de Bruijn index mechanism where bound 
   190   The internal representation of terms uses the usual de Bruijn index mechanism where bound 
   192   variables are represented by the constructor @{ML Bound}. The index in @{ML Bound} refers to
   191   variables are represented by the constructor @{ML Bound}. The index in @{ML Bound} refers to
   220   \end{exercise}
   219   \end{exercise}
   221 
   220 
   222   @{ML [display] "print_depth 50"}
   221   @{ML [display] "print_depth 50"}
   223 
   222 
   224   The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type, 
   223   The antiquotation @{text "@{prop \<dots>}"} constructs terms of propositional type, 
   225   inserting the invisible @{text "Trueprop"} coercions whenever necessary. 
   224   inserting the invisible @{text "Trueprop"}-coercions whenever necessary. 
   226   Consider for example
   225   Consider for example
   227 
   226 
   228   @{ML_response [display] "@{term \"P x\"}" "Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)"}
   227   @{ML_response [display] "@{term \"P x\"}" "Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)"}
   229   @{ML_response [display] "@{prop \"P x\"}" 
   228   @{ML_response [display] "@{prop \"P x\"}" 
   230                           "Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>))"}
   229                           "Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>))"}
   232   which inserts the coercion in the latter case and 
   231   which inserts the coercion in the latter case and 
   233 
   232 
   234   @{ML_response [display] "@{term \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   233   @{ML_response [display] "@{term \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   235   @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   234   @{ML_response [display] "@{prop \"P x \<Longrightarrow> Q x\"}" "Const (\"==>\", \<dots>) $ \<dots> $ \<dots>"}
   236 
   235 
   237   which does not. 
   236   which does not (since it is already constructed using the meta-implication). 
   238 
   237 
   239   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   238   Types can be constructed using the antiquotation @{text "@{typ \<dots>}"}. For example
   240 
   239 
   241   @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   240   @{ML_response_fake [display] "@{typ \"bool \<Rightarrow> nat\"}" "bool \<Rightarrow> nat"}
   242 
   241 
   281 text {*
   280 text {*
   282   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   281   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   283   to both functions. 
   282   to both functions. 
   284 
   283 
   285   One tricky point in constructing terms by hand is to obtain the 
   284   One tricky point in constructing terms by hand is to obtain the 
   286   fully qualified name for constants. For example the names for @{text "zero"} or 
   285   fully qualified name for constants. For example the names for @{text "zero"} and
   287   @{text "+"} are more complex than one first expects, namely 
   286   @{text "+"} are more complex than one first expects, namely 
   288 
   287 
   289   \begin{center}
   288   \begin{center}
   290   @{ML_text "HOL.zero_class.zero"} and @{ML_text "HOL.plus_class.plus"}. 
   289   @{ML_text "HOL.zero_class.zero"} and @{ML_text "HOL.plus_class.plus"}. 
   291   \end{center}
   290   \end{center}
   298 
   297 
   299   @{ML_response_fake [display] "@{const_name \"Nil\"}" "List.list.Nil"}
   298   @{ML_response_fake [display] "@{const_name \"Nil\"}" "List.list.Nil"}
   300 
   299 
   301   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   300   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   302 
   301 
   303   Similarly, types can be constructed for example as follows:
   302   Similarly, types can be constructed manually, for example as follows:
   304 
   303 
   305 *} 
   304 *} 
   306 
   305 
   307 ML {*
   306 ML {*
   308 fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2])
   307 fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2])
   350 text {* 
   349 text {* 
   351   
   350   
   352   We can freely construct and manipulate terms, since they are just
   351   We can freely construct and manipulate terms, since they are just
   353   arbitrary unchecked trees. However, we eventually want to see if a
   352   arbitrary unchecked trees. However, we eventually want to see if a
   354   term is well-formed, or type checks, relative to a theory.
   353   term is well-formed, or type checks, relative to a theory.
   355   Type-checking is done via the function @{ML cterm_of}, which turns 
   354   Type-checking is done via the function @{ML cterm_of}, which converts 
   356   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   355   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   357   Unlike @{ML_type term}s, which are just trees, @{ML_type
   356   Unlike @{ML_type term}s, which are just trees, @{ML_type
   358   "cterm"}s are abstract objects that are guaranteed to be
   357   "cterm"}s are abstract objects that are guaranteed to be
   359   type-correct, and that can only be constructed via the official
   358   type-correct, and that can only be constructed via the ``official
   360   interfaces.
   359   interfaces''.
   361 
   360 
   362   Type checking is always relative to a theory context. For now we can use
   361   Type checking is always relative to a theory context. For now we use
   363   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   362   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   364   For example we can write
   363   For example we can write
   365 
   364 
   366   @{ML_response_fake [display] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   365   @{ML_response_fake [display] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   367 
   366 
   381   $ zero $ zero)
   380   $ zero $ zero)
   382 end" "0 + 0"}
   381 end" "0 + 0"}
   383 
   382 
   384   \begin{exercise}
   383   \begin{exercise}
   385   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   384   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   386   result that type checks.
   385   result that type-checks.
   387   \end{exercise}
   386   \end{exercise}
   388 
   387 
   389 *}
   388 *}
   390 
   389 
   391 section {* Theorems *}
   390 section {* Theorems *}
   392 
   391 
   393 text {*
   392 text {*
   394   Just like @{ML_type cterm}s, theorems (of type @{ML_type thm}) are
   393   Just like @{ML_type cterm}s, theorems are abstract objects of type @{ML_type thm} 
   395   abstract objects that can only be built by going through the kernel
   394   that can only be built by going through interfaces, which means that all your proofs 
   396   interfaces, which means that all your proofs will be checked. 
   395   will be checked. 
   397 
   396 
   398   To see theorems in ``action'', let us give a proof for the following statement
   397   To see theorems in ``action'', let us give a proof for the following statement
   399 *}
   398 *}
   400 
   399 
   401   lemma 
   400   lemma 
   442     }
   441     }
   443   \]
   442   \]
   444 
   443 
   445 
   444 
   446   \begin{readmore}
   445   \begin{readmore}
   447   For how the functions @{text "assume"}, @{text "forall_elim"} etc work
   446   For the functions @{text "assume"}, @{text "forall_elim"} etc 
   448   see \isccite{sec:thms}. The basic functions for theorems are defined in
   447   see \isccite{sec:thms}. The basic functions for theorems are defined in
   449   @{ML_file "Pure/thm.ML"}. 
   448   @{ML_file "Pure/thm.ML"}. 
   450   \end{readmore}
   449   \end{readmore}
   451 
   450 
   452 *}
   451 *}
   467 
   466 
   468   where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the open 
   467   where @{term C} is the goal to be proved and the @{term "A\<^isub>i"} are the open 
   469   subgoals. 
   468   subgoals. 
   470   Since the goal @{term C} can potentially be an implication, there is a
   469   Since the goal @{term C} can potentially be an implication, there is a
   471   @{text "#"} wrapped around it, which prevents that premises are 
   470   @{text "#"} wrapped around it, which prevents that premises are 
   472   misinterpreted as open subgoals. The protection @{text "# :: prop \<Rightarrow>
   471   misinterpreted as open subgoals. The wrapper @{text "# :: prop \<Rightarrow>
   473   prop"} is just the identity function and used as a syntactic marker. 
   472   prop"} is just the identity function and used as a syntactic marker. 
   474   
   473   
   475   \begin{readmore}
   474   \begin{readmore}
   476   For more on goals see \isccite{sec:tactical-goals}. 
   475   For more on goals see \isccite{sec:tactical-goals}. 
   477   \end{readmore}
   476   \end{readmore}
   482   
   481   
   483   \begin{readmore}
   482   \begin{readmore}
   484   See @{ML_file "Pure/General/seq.ML"} for the implementation of lazy
   483   See @{ML_file "Pure/General/seq.ML"} for the implementation of lazy
   485   sequences. However in day-to-day Isabelle programming, one rarely 
   484   sequences. However in day-to-day Isabelle programming, one rarely 
   486   constructs sequences explicitly, but uses the predefined tactic 
   485   constructs sequences explicitly, but uses the predefined tactic 
   487   combinators (tacticals) instead (see @{ML_file "Pure/tctical.ML"}). 
   486   combinators (tacticals) instead. See @{ML_file "Pure/tctical.ML"} 
   488   (FIXME: Pointer to the old reference manual)
   487   for the code; see Chapters 3 and 4 in the old Isabelle Reference Manual.
   489   \end{readmore}
   488   \end{readmore}
   490 
   489 
   491   While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they 
   490   While tactics can operate on the subgoals (the @{text "A\<^isub>i"} above), they 
   492   are expected to leave the conclusion @{term C} intact, with the 
   491   are expected to leave the conclusion @{term C} intact, with the 
   493   exception of possibly instantiating schematic variables. 
   492   exception of possibly instantiating schematic variables. 
   494  
   493  
   495   To see how tactics work, let us transcribe a simple @{text apply}-style 
   494   To see how tactics work, let us transcribe a simple @{text apply}-style 
   496   proof from the tutorial~\cite{isa-tutorial} into ML:
   495   proof into ML:
   497 *}
   496 *}
   498 
   497 
   499 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P"
   498 lemma disj_swap: "P \<or> Q \<Longrightarrow> Q \<or> P"
   500 apply (erule disjE)
   499 apply (erule disjE)
   501  apply (rule disjI2)
   500  apply (rule disjI2)
   508   To start the proof, the function  @{ML "Goal.prove"}~@{text "ctxt xs As C tac"} sets 
   507   To start the proof, the function  @{ML "Goal.prove"}~@{text "ctxt xs As C tac"} sets 
   509   up a goal state for proving the goal @{text C} under the assumptions @{text As} 
   508   up a goal state for proving the goal @{text C} under the assumptions @{text As} 
   510   (empty in the proof at hand) 
   509   (empty in the proof at hand) 
   511   with the variables @{text xs} that will be generalised once the
   510   with the variables @{text xs} that will be generalised once the
   512   goal is proved. The @{text "tac"} is the tactic which proves the goal and which 
   511   goal is proved. The @{text "tac"} is the tactic which proves the goal and which 
   513   can make use of the local assumptions.
   512   can make use of the local assumptions (there are none in this example).
   514 
   513 
   515 @{ML_response_fake [display]
   514 @{ML_response_fake [display]
   516 "let
   515 "let
   517   val ctxt = @{context}
   516   val ctxt = @{context}
   518   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}
   517   val goal = @{prop \"P \<or> Q \<Longrightarrow> Q \<or> P\"}