ProgTutorial/FirstSteps.thy
changeset 196 840b49bfb1cf
parent 192 2fff636e1fa0
child 197 2fe1877f705f
equal deleted inserted replaced
195:7305beb69893 196:840b49bfb1cf
    78   then there is a convenient, though again ``quick-and-dirty'', method for
    78   then there is a convenient, though again ``quick-and-dirty'', method for
    79   converting values into strings, namely the function @{ML makestring}:
    79   converting values into strings, namely the function @{ML makestring}:
    80 
    80 
    81   @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} 
    81   @{ML_response_fake [display,gray] "warning (makestring 1)" "\"1\""} 
    82 
    82 
    83   However @{ML makestring} only works if the type of what is converted is monomorphic 
    83   However, @{ML makestring} only works if the type of what is converted is monomorphic 
    84   and not a function.
    84   and not a function.
    85 
    85 
    86   The function @{ML "warning"} should only be used for testing purposes, because any
    86   The function @{ML "warning"} should only be used for testing purposes, because any
    87   output this function generates will be overwritten as soon as an error is
    87   output this function generates will be overwritten as soon as an error is
    88   raised. For printing anything more serious and elaborate, the
    88   raised. For printing anything more serious and elaborate, the
    90   a separate tracing buffer. For example:
    90   a separate tracing buffer. For example:
    91 
    91 
    92   @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
    92   @{ML_response_fake [display,gray] "tracing \"foo\"" "\"foo\""}
    93 
    93 
    94   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    94   It is also possible to redirect the ``channel'' where the string @{text "foo"} is 
    95   printed to a separate file, e.g.~to prevent ProofGeneral from choking on massive 
    95   printed to a separate file, e.g., to prevent ProofGeneral from choking on massive 
    96   amounts of trace output. This redirection can be achieved with the code:
    96   amounts of trace output. This redirection can be achieved with the code:
    97 *}
    97 *}
    98 
    98 
    99 ML{*val strip_specials =
    99 ML{*val strip_specials =
   100 let
   100 let
   199 
   199 
   200 text {* 
   200 text {* 
   201   Theorem @{thm [source] conjI} looks now as follows
   201   Theorem @{thm [source] conjI} looks now as follows
   202 
   202 
   203   @{ML_response_fake [display, gray]
   203   @{ML_response_fake [display, gray]
   204   "warning (str_of_thm_raw @{context} @{thm conjI})"
   204   "warning (str_of_thm @{context} @{thm conjI})"
   205   "\<lbrakk>?P; ?Q\<rbrakk> \<Longrightarrow> ?P \<and> ?Q"}
   205   "\<lbrakk>P; Q\<rbrakk> \<Longrightarrow> P \<and> Q"}
   206   
   206   
   207   Again the function @{ML commas} helps with printing more than one theorem. 
   207   Again the function @{ML commas} helps with printing more than one theorem. 
   208 *}
   208 *}
   209 
   209 
   210 ML{*fun str_of_thms ctxt thms =  
   210 ML{*fun str_of_thms ctxt thms =  
   249     |> (fn x => (x, x))
   249     |> (fn x => (x, x))
   250     |> fst
   250     |> fst
   251     |> (fn x => x + 4)*}
   251     |> (fn x => x + 4)*}
   252 
   252 
   253 text {*
   253 text {*
   254   which increments its argument @{text x} by 5. It does this by first incrementing 
   254   which increments its argument @{text x} by 5. It proceeds by first incrementing 
   255   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   255   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   256   the first component of the pair (Line 4) and finally incrementing the first 
   256   the first component of the pair (Line 4) and finally incrementing the first 
   257   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   257   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   258   common when dealing with theories (for example by adding a definition, followed by
   258   common when dealing with theories (for example by adding a definition, followed by
   259   lemmas and so on). The reverse application allows you to read what happens in 
   259   lemmas and so on). The reverse application allows you to read what happens in 
   350   intermediate result inside the tracing buffer. The function @{ML tap} can
   350   intermediate result inside the tracing buffer. The function @{ML tap} can
   351   only be used for side-calculations, because any value that is computed
   351   only be used for side-calculations, because any value that is computed
   352   cannot be merged back into the ``main waterfall''. To do this, you can use
   352   cannot be merged back into the ``main waterfall''. To do this, you can use
   353   the next combinator.
   353   the next combinator.
   354 
   354 
   355   The combinator @{ML "`"} is similar to @{ML tap}, but applies a function to the value
   355   The combinator @{ML "`"} (a backtick) is similar to @{ML tap}, but applies a
   356   and returns the result together with the value (as a pair). For example
   356   function to the value and returns the result together with the value (as a
   357   the function 
   357   pair). For example the function 
   358 *}
   358 *}
   359 
   359 
   360 ML{*fun inc_as_pair x =
   360 ML{*fun inc_as_pair x =
   361      x |> `(fn x => x + 1)
   361      x |> `(fn x => x + 1)
   362        |> (fn (x, y) => (x, y + 1))*}
   362        |> (fn (x, y) => (x, y + 1))*}
   394 ML{*fun double x =
   394 ML{*fun double x =
   395       x |>  (fn x => (x, x))
   395       x |>  (fn x => (x, x))
   396         |-> (fn x => fn y => x + y)*}
   396         |-> (fn x => fn y => x + y)*}
   397 
   397 
   398 text {*
   398 text {*
   399   Recall that @{ML "|>"} is the reverse function applications. Recall also that the related 
   399   Recall that @{ML "|>"} is the reverse function application. Recall also that
       
   400   the related 
   400   reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"},
   401   reverse function composition is @{ML "#>"}. In fact all the combinators @{ML "|->"},
   401   @{ML "|>>"} and @{ML "||>"} described above have related combinators for function
   402   @{ML "|>>"} and @{ML "||>"} described above have related combinators for function
   402   composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, 
   403   composition, namely @{ML "#->"}, @{ML "#>>"} and @{ML "##>"}. Using @{ML "#->"}, 
   403   for example, the function @{text double} can also be written as:
   404   for example, the function @{text double} can also be written as:
   404 *}
   405 *}
   410 text {*
   411 text {*
   411   
   412   
   412   (FIXME: find a good exercise for combinators)
   413   (FIXME: find a good exercise for combinators)
   413 
   414 
   414   \begin{readmore}
   415   \begin{readmore}
   415   The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"}
   416   The most frequently used combinators are defined in the files @{ML_file
       
   417   "Pure/library.ML"}
   416   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   418   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   417   contains further information about combinators.
   419   contains further information about combinators.
   418   \end{readmore}
   420   \end{readmore}
   419  
   421  
   420 *}
   422 *}
   484 
   486 
   485   @{ML_response_fake [display,gray] 
   487   @{ML_response_fake [display,gray] 
   486   "get_thm_names_from_ss @{simpset}" 
   488   "get_thm_names_from_ss @{simpset}" 
   487   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   489   "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   488 
   490 
   489   Again, this way or referencing simpsets makes you independent from additions
   491   Again, this way of referencing simpsets makes you independent from additions
   490   of lemmas to the simpset by the user that potentially cause loops.
   492   of lemmas to the simpset by the user that potentially cause loops.
   491 
   493 
   492   On the ML-level of Isabelle, you often have to work with qualified names;
   494   On the ML-level of Isabelle, you often have to work with qualified names;
   493   these are strings with some additional information, such positional information
   495   these are strings with some additional information, such as positional information
   494   and qualifiers. Such bindings can be generated with the antiquotation 
   496   and qualifiers. Such bindings can be generated with the antiquotation 
   495   @{text "@{bindin \<dots>}"}.
   497   @{text "@{binding \<dots>}"}.
   496 
   498 
   497   @{ML_response [display,gray]
   499   @{ML_response [display,gray]
   498   "@{binding \"name\"}"
   500   "@{binding \"name\"}"
   499   "name"}
   501   "name"}
   500 
   502 
   501   An example where a binding is needed is the function @{ML define in LocalTheory}.
   503   An example where a binding is needed is the function @{ML define in
   502   Below this function defines the constant @{term "TrueConj"} as the conjunction
   504   LocalTheory}.  Below, this function is used to define the constant @{term
       
   505   "TrueConj"} as the conjunction
   503   @{term "True \<and> True"}.
   506   @{term "True \<and> True"}.
   504 *}
   507 *}
   505   
   508   
   506 local_setup %gray {* 
   509 local_setup %gray {* 
   507   snd o LocalTheory.define Thm.internalK 
   510   snd o LocalTheory.define Thm.internalK 
   508     ((@{binding "TrueConj"}, NoSyn), 
   511     ((@{binding "TrueConj"}, NoSyn), 
   509      (Attrib.empty_binding, @{term "True \<and> True"})) *}
   512      (Attrib.empty_binding, @{term "True \<and> True"})) *}
   510 
   513 
   511 text {*
   514 text {*
   512   While antiquotations have many applications, they were originally introduced in order 
   515   While antiquotations have many applications, they were originally introduced
   513   to avoid explicit bindings for theorems such as:
   516   in order to avoid explicit bindings of theorems such as:
   514 *}
   517 *}
   515 
   518 
   516 ML{*val allI = thm "allI" *}
   519 ML{*val allI = thm "allI" *}
   517 
   520 
   518 text {*
   521 text {*
   519   These bindings are difficult to maintain and also can be accidentally
   522   Such bindings are difficult to maintain and can be overwritten by the
   520   overwritten by the user. This often broke Isabelle
   523   user accidentally. This often broke Isabelle
   521   packages. Antiquotations solve this problem, since they are ``linked''
   524   packages. Antiquotations solve this problem, since they are ``linked''
   522   statically at compile-time.  However, this static linkage also limits their
   525   statically at compile-time.  However, this static linkage also limits their
   523   usefulness in cases where data needs to be build up dynamically. In the
   526   usefulness in cases where data needs to be build up dynamically. In the
   524   course of this chapter you will learn more about these antiquotations:
   527   course of this chapter you will learn more about antiquotations:
   525   they can simplify Isabelle programming since one can directly access all
   528   they can simplify Isabelle programming since one can directly access all
   526   kinds of logical elements from th ML-level.
   529   kinds of logical elements from the ML-level.
   527 *}
   530 *}
   528 
   531 
   529 section {* Terms and Types *}
   532 section {* Terms and Types *}
   530 
   533 
   531 text {*
   534 text {*