CookBook/FirstSteps.thy
changeset 102 5e309df58557
parent 101 123401a5c8e9
child 104 5dcad9348e4d
equal deleted inserted replaced
101:123401a5c8e9 102:5e309df58557
    35 @{text "\<verbclose>"}\isanewline
    35 @{text "\<verbclose>"}\isanewline
    36 @{text "> 7"}\smallskip
    36 @{text "> 7"}\smallskip
    37 \end{graybox}
    37 \end{graybox}
    38 \end{isabelle}
    38 \end{isabelle}
    39 
    39 
    40   Like normal Isabelle proof scripts, 
    40   Like normal Isabelle proof scripts, \isacommand{ML}-commands can be
    41   \isacommand{ML}-commands can be evaluated by using the advance and undo buttons of 
    41   evaluated by using the advance and undo buttons of your Isabelle
    42   your Isabelle environment. The code inside the \isacommand{ML}-command 
    42   environment. The code inside the \isacommand{ML}-command can also contain
    43   can also contain value and function bindings, and even those can be
    43   value and function bindings, and even those can be undone when the proof
    44   undone when the proof script is retracted. As mentioned earlier, we will  
    44   script is retracted. As mentioned earlier, we will drop the
    45   drop the \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"} 
    45   \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"} scaffolding whenever we
    46   scaffolding whenever we show code.
    46   show code. The lines prefixed with @{text ">"} are not part of the
    47 
    47   code, rather they indicate what the response is when the code is evaluated.
    48   Once a portion of code is relatively stable, one usually wants to 
    48 
    49   export it to a separate ML-file. Such files can then be included in a 
    49   Once a portion of code is relatively stable, you usually want to export it
    50   theory by using the \isacommand{uses}-command in the header of the theory, like:
    50   to a separate ML-file. Such files can then be included in a theory by using
       
    51   the \isacommand{uses}-command in the header of the theory, like:
    51 
    52 
    52   \begin{center}
    53   \begin{center}
    53   \begin{tabular}{@ {}l}
    54   \begin{tabular}{@ {}l}
    54   \isacommand{theory} FirstSteps\\
    55   \isacommand{theory} FirstSteps\\
    55   \isacommand{imports} Main\\
    56   \isacommand{imports} Main\\
   113 
   114 
   114   You can print out error messages with the function @{ML error}, as in:
   115   You can print out error messages with the function @{ML error}, as in:
   115 
   116 
   116   @{ML_response_fake [display,gray] "if 0=1 then 1 else (error \"foo\")" "\"foo\""}
   117   @{ML_response_fake [display,gray] "if 0=1 then 1 else (error \"foo\")" "\"foo\""}
   117 
   118 
       
   119   See leter on in Section~\ref{sec:printing} for information about printing 
       
   120   out data of type @{ML_type term}, @{ML_type cterm} and @{ML_type thm}.
   118 *}
   121 *}
   119 
   122 
   120 
   123 
   121 
   124 
   122 
   125 
   275 
   278 
   276 section {* Constructing Terms and Types Manually *} 
   279 section {* Constructing Terms and Types Manually *} 
   277 
   280 
   278 text {*
   281 text {*
   279   While antiquotations are very convenient for constructing terms, they can
   282   While antiquotations are very convenient for constructing terms, they can
   280   only construct fixed terms (remember they are ``linked'' at
   283   only construct fixed terms (remember they are ``linked'' at compile-time).
   281   compile-time). See Recipe~\ref{rec:external} on Page~\pageref{rec:external}
   284   However, you often need to construct terms dynamically. For example, a
   282   for a function that pattern-matches over terms and where the patterns are
   285   function that returns the implication @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking
   283   constructed using antiquotations.  However, one often needs to construct
   286   @{term P}, @{term Q} and the type @{term "\<tau>"} as arguments can only be
   284   terms dynamically. For example, a function that returns the implication
   287   written as:
   285   @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the type @{term
   288 
   286   "\<tau>"} as arguments can only be written as:
       
   287 *}
   289 *}
   288 
   290 
   289 ML{*fun make_imp P Q tau =
   291 ML{*fun make_imp P Q tau =
   290   let
   292   let
   291     val x = Free ("x",tau)
   293     val x = Free ("x",tau)
   292   in 
   294   in 
   293     Logic.all x (Logic.mk_implies (P $ x, Q $ x))
   295     Logic.all x (Logic.mk_implies (P $ x, Q $ x))
   294   end *}
   296   end *}
   295 
   297 
   296 text {*
   298 text {*
   297   The reason is that one cannot pass the arguments @{term P}, @{term Q} and 
   299   The reason is that you cannot pass the arguments @{term P}, @{term Q} and 
   298   @{term "tau"} into an antiquotation. For example the following does \emph{not} work:
   300   @{term "tau"} into an antiquotation. For example the following does \emph{not} work:
   299 *}
   301 *}
   300 
   302 
   301 ML{*fun make_wrong_imp P Q tau = @{prop "\<And>x. P x \<Longrightarrow> Q x"} *}
   303 ML{*fun make_wrong_imp P Q tau = @{prop "\<And>x. P x \<Longrightarrow> Q x"} *}
   302 
   304 
   303 text {*
   305 text {*
   304   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   306   To see this apply @{text "@{term S}"}, @{text "@{term T}"} and @{text "@{typ nat}"} 
   305   to both functions. With @{ML make_imp} we obtain the intended term involving 
   307   to both functions. With @{ML make_imp} we obtain the intended term involving 
   306   @{term "S"}, @{text "T"} and  @{text "@{typ nat}"} 
   308   the given arguments
   307 
   309 
   308   @{ML_response [display,gray] "make_imp @{term S} @{term T} @{typ nat}" 
   310   @{ML_response [display,gray] "make_imp @{term S} @{term T} @{typ nat}" 
   309     "Const \<dots> $ 
   311     "Const \<dots> $ 
   310     Abs (\"x\", Type (\"nat\",[]),
   312     Abs (\"x\", Type (\"nat\",[]),
   311       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   313       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   340 
   342 
   341   @{ML_response_fake [display,gray] "@{const_name \"Nil\"}" "List.list.Nil"}
   343   @{ML_response_fake [display,gray] "@{const_name \"Nil\"}" "List.list.Nil"}
   342 
   344 
   343   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   345   (FIXME: Is it useful to explain @{text "@{const_syntax}"}?)
   344 
   346 
   345   Similarly, one can construct types manually. For example the function returning
   347   Similarly, you occasionally need to construct types manually. For example 
   346   a function type is as follows:
   348   the function returning a function type is as follows:
   347 
   349 
   348 *} 
   350 *} 
   349 
   351 
   350 ML{*fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2]) *}
   352 ML{*fun make_fun_type tau1 tau2 = Type ("fun",[tau1,tau2]) *}
   351 
   353 
   355 
   357 
   356 text {*
   358 text {*
   357 
   359 
   358   \begin{readmore}
   360   \begin{readmore}
   359   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
   361   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
   360   @{ML_file "HOL/hologic.ML"} that make such manual constructions of terms 
   362   @{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms 
   361   and types easier.\end{readmore}
   363   and types easier.\end{readmore}
   362 
   364 
   363   Have a look at these files and try to solve the following two exercises:
   365   Have a look at these files and try to solve the following two exercises:
   364 
   366 
   365 *}
   367 *}
   401 
   403 
   402 section {* Type-Checking *}
   404 section {* Type-Checking *}
   403 
   405 
   404 text {* 
   406 text {* 
   405   
   407   
   406   We can freely construct and manipulate terms, since they are just
   408   You can freely construct and manipulate terms, since they are just
   407   arbitrary unchecked trees. However, we eventually want to see if a
   409   arbitrary unchecked trees. However, you eventually want to see if a
   408   term is well-formed, or type-checks, relative to a theory.
   410   term is well-formed, or type-checks, relative to a theory.
   409   Type-checking is done via the function @{ML cterm_of}, which converts 
   411   Type-checking is done via the function @{ML cterm_of}, which converts 
   410   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   412   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   411   Unlike @{ML_type term}s, which are just trees, @{ML_type
   413   Unlike @{ML_type term}s, which are just trees, @{ML_type
   412   "cterm"}s are abstract objects that are guaranteed to be
   414   "cterm"}s are abstract objects that are guaranteed to be
   413   type-correct, and they can only be constructed via ``official
   415   type-correct, and they can only be constructed via ``official
   414   interfaces''.
   416   interfaces''.
   415 
   417 
   416   Type-checking is always relative to a theory context. For now we use
   418   Type-checking is always relative to a theory context. For now we use
   417   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   419   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   418   For example we can write
   420   For example you can write:
   419 
   421 
   420   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   422   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   421 
   423 
   422   This can also be wirtten with an antiquotation
   424   This can also be wirtten with an antiquotation:
   423 
   425 
   424   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   426   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   425 
   427 
   426   Attempting to obtain the certified term for
   428   Attempting to obtain the certified term for
   427 
   429 
   428   @{ML_response_fake_both [display,gray] "@{cterm \"1 + True\"}" "Type unification failed \<dots>"}
   430   @{ML_response_fake_both [display,gray] "@{cterm \"1 + True\"}" "Type unification failed \<dots>"}
   429 
   431 
   430   yields an error (since the term is not typable). A slightly more elaborate
   432   yields an error (since the term is not typable). A slightly more elaborate
   431   example that type-checks is
   433   example that type-checks is:
   432 
       
   433 
   434 
   434 @{ML_response_fake [display,gray] 
   435 @{ML_response_fake [display,gray] 
   435 "let
   436 "let
   436   val natT = @{typ \"nat\"}
   437   val natT = @{typ \"nat\"}
   437   val zero = @{term \"0::nat\"}
   438   val zero = @{term \"0::nat\"}
   501           }
   502           }
   502        }
   503        }
   503     }
   504     }
   504   \]
   505   \]
   505 
   506 
       
   507   However, while we obtained a theorem as result, this theorem is not
       
   508   yet stored in Isabelle's theorem database. So it cannot be referenced later
       
   509   on. How to store theorems will be explained in the next section.
   506 
   510 
   507   \begin{readmore}
   511   \begin{readmore}
   508   For the functions @{text "assume"}, @{text "forall_elim"} etc 
   512   For the functions @{text "assume"}, @{text "forall_elim"} etc 
   509   see \isccite{sec:thms}. The basic functions for theorems are defined in
   513   see \isccite{sec:thms}. The basic functions for theorems are defined in
   510   @{ML_file "Pure/thm.ML"}. 
   514   @{ML_file "Pure/thm.ML"}. 
   517 section {* Theorem Attributes *}
   521 section {* Theorem Attributes *}
   518 
   522 
   519 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *}
   523 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *}
   520 
   524 
   521 text {* 
   525 text {* 
   522   You will occationally feel the need to inspect terms, cterms or theorems during
   526   During development, you will occationally feel the need to inspect terms, cterms 
   523   development. Isabelle contains elaborate pretty-printing functions for that, but 
   527   or theorems. Isabelle contains elaborate pretty-printing functions for that, but 
   524   for quick-and-dirty solutions they are way too unwieldy. A simple way to transform 
   528   for quick-and-dirty solutions they are way too unwieldy. A simple way to transform 
   525   a term into a string is to use the function @{ML Syntax.string_of_term}.
   529   a term into a string is to use the function @{ML Syntax.string_of_term}.
   526 
   530 
   527   @{ML_response_fake [display,gray]
   531   @{ML_response_fake [display,gray]
   528   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   532   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   540 
   544 
   541 ML{*fun str_of_cterm ctxt t =  
   545 ML{*fun str_of_cterm ctxt t =  
   542    Syntax.string_of_term ctxt (term_of t)*}
   546    Syntax.string_of_term ctxt (term_of t)*}
   543 
   547 
   544 text {*
   548 text {*
   545   If there are more than one @{ML_type cterm} to be printed, you can use the function
   549   If there are more than one @{ML_type cterm}s to be printed, you can use the 
   546   @{ML commas} to conveniently separate them.
   550   function @{ML commas} to separate them.
   547 *} 
   551 *} 
   548 
   552 
   549 ML{*fun str_of_cterms ctxt ts =  
   553 ML{*fun str_of_cterms ctxt ts =  
   550   commas (map (str_of_cterm ctxt) ts)*}
   554    commas (map (str_of_cterm ctxt) ts)*}
   551 
   555 
   552 text {*
   556 text {*
   553   The easiest way to get the string of a theorem is to transform it
   557   The easiest way to get the string of a theorem is to transform it
   554   into a @{ML_type cterm} using the function @{ML crep_thm}.
   558   into a @{ML_type cterm} using the function @{ML crep_thm}.
   555 *}
   559 *}
   720   for x}. After that, the function increments the right-hand component of the
   724   for x}. After that, the function increments the right-hand component of the
   721   pair. So finally the result will be @{ML "(x + 1, x + 1)" for x}.
   725   pair. So finally the result will be @{ML "(x + 1, x + 1)" for x}.
   722 
   726 
   723   The combinators @{ML "|>>"} and @{ML "||>"} are defined for 
   727   The combinators @{ML "|>>"} and @{ML "||>"} are defined for 
   724   functions manipulating pairs. The first applies the function to
   728   functions manipulating pairs. The first applies the function to
   725   the first component of the pair, defined as:
   729   the first component of the pair, defined as
   726 *}
   730 *}
   727 
   731 
   728 ML{*fun (x, y) |>> f = (f x, y)*}
   732 ML{*fun (x, y) |>> f = (f x, y)*}
   729 
   733 
   730 text {*
   734 text {*