CookBook/FirstSteps.thy
changeset 81 8fda6b452f28
parent 78 ef778679d3e0
child 82 6dfe6975bda0
equal deleted inserted replaced
80:95e9c4556221 81:8fda6b452f28
   110 
   110 
   111 text {*
   111 text {*
   112   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   112   Calling @{ML "redirect_tracing"} with @{ML "(TextIO.openOut \"foo.bar\")"} 
   113   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   113   will cause that all tracing information is printed into the file @{text "foo.bar"}.
   114 
   114 
   115   Error messages can be printed using the function @{ML error} as in
   115   Error messages can be printed using the function @{ML error}, as in
   116 
   116 
   117   @{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\""}
   118 
   118 
   119 *}
   119 *}
   120 
   120 
   136   where @{text "@{theory}"} is an antiquotation that is substituted with the
   136   where @{text "@{theory}"} is an antiquotation that is substituted with the
   137   current theory (remember that we assumed we are inside the theory 
   137   current theory (remember that we assumed we are inside the theory 
   138   @{text FirstSteps}). The name of this theory can be extracted with
   138   @{text FirstSteps}). The name of this theory can be extracted with
   139   the function @{ML "Context.theory_name"}. 
   139   the function @{ML "Context.theory_name"}. 
   140 
   140 
   141   Note, however, that antiquotations are statically scoped, that is the value is
   141   Note, however, that antiquotations are statically scoped, that is their value is
   142   determined at ``compile-time'', not ``run-time''. For example the function
   142   determined at ``compile-time'', not ``run-time''. For example the function
   143 *}
   143 *}
   144 
   144 
   145 ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   145 ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   146 
   146 
   152   function is called. Operationally speaking,  the antiquotation @{text "@{theory}"} is 
   152   function is called. Operationally speaking,  the antiquotation @{text "@{theory}"} is 
   153   \emph{not} replaced with code that will look up the current theory in 
   153   \emph{not} replaced with code that will look up the current theory in 
   154   some data structure and return it. Instead, it is literally
   154   some data structure and return it. Instead, it is literally
   155   replaced with the value representing the theory name.
   155   replaced with the value representing the theory name.
   156 
   156 
   157   In a similar way you can use antiquotations to refer to theorems:
   157   In a similar way you can use antiquotations to refer to proved theorems:
   158 
   158 
   159   @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   159   @{ML_response_fake [display,gray] "@{thm allI}" "(\<And>x. ?P x) \<Longrightarrow> \<forall>x. ?P x"}
   160 
   160 
   161   or simpsets:
   161   or simpsets:
   162 
   162 
   165   val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset}
   165   val ({rules,...},_) = MetaSimplifier.rep_ss @{simpset}
   166 in
   166 in
   167   map #name (Net.entries rules)
   167   map #name (Net.entries rules)
   168 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   168 end" "[\"Nat.of_nat_eq_id\", \"Int.of_int_eq_id\", \"Nat.One_nat_def\", \<dots>]"}
   169 
   169 
   170   The code above extracts the theorem names that are stored in the current simpset.
   170   The code about simpsets extracts the theorem names that are stored in the
   171   We refer to the simpset with the antiquotation @{text "@{simpset}"}.
   171   current simpset.  We get hold of the current simpset with the antiquotation 
   172   The function @{ML rep_ss in MetaSimplifier} returns a record
   172   @{text "@{simpset}"}.  The function @{ML rep_ss in MetaSimplifier} returns a record
   173   containing all information about the simpset. The rules of a simpset are stored
   173   containing all information about the simpset. The rules of a simpset are
   174   in a \emph{discrimination net} (a datastructure for fast indexing). From this net
   174   stored in a \emph{discrimination net} (a datastructure for fast
   175   we can extract the entries using the function @{ML Net.entries}.
   175   indexing). From this net we can extract the entries using the function @{ML
       
   176   Net.entries}.
       
   177 
   176 
   178 
   177   \begin{readmore}
   179   \begin{readmore}
   178   The infrastructure for simpsets is contained in @{ML_file "Pure/meta_simplifier.ML"}
   180   The infrastructure for simpsets is implemented in @{ML_file "Pure/meta_simplifier.ML"}
   179   and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented
   181   and @{ML_file "Pure/simplifier.ML"}. Discrimination nets are implemented
   180   in @{ML_file "Pure/net.ML"}.
   182   in @{ML_file "Pure/net.ML"}.
   181   \end{readmore}
   183   \end{readmore}
   182 
   184 
   183   While antiquotations have many applications, they were originally introduced in order 
   185   While antiquotations have many applications, they were originally introduced in order 
   273 
   275 
   274 
   276 
   275 section {* Constructing Terms and Types Manually *} 
   277 section {* Constructing Terms and Types Manually *} 
   276 
   278 
   277 text {*
   279 text {*
   278 
   280   While antiquotations are very convenient for constructing terms, they can
   279   While antiquotations are very convenient for constructing terms, 
   281   only construct fixed terms (remember they are ``linked'' at
   280   they can only construct fixed terms (remember they are ``linked'' at compile-time). 
   282   compile-time). See Recipe~\ref{rec:external} on Page~\pageref{rec:external}
   281   However, one often needs to construct terms
   283   for a function that pattern-matches over terms and where the pattern are
   282   dynamically. For example, a function that returns the implication 
   284   constructed from antiquotations.  However, one often needs to construct
   283   @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the type @{term "\<tau>"}
   285   terms dynamically. For example, a function that returns the implication
   284   as arguments can only be written as
   286   @{text "\<And>(x::\<tau>). P x \<Longrightarrow> Q x"} taking @{term P}, @{term Q} and the type @{term
       
   287   "\<tau>"} as arguments can only be written as
   285 *}
   288 *}
   286 
   289 
   287 ML{*fun make_imp P Q tau =
   290 ML{*fun make_imp P Q tau =
   288   let
   291   let
   289     val x = Free ("x",tau)
   292     val x = Free ("x",tau)
   308     "Const \<dots> $ 
   311     "Const \<dots> $ 
   309     Abs (\"x\", Type (\"nat\",[]),
   312     Abs (\"x\", Type (\"nat\",[]),
   310       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   313       Const \<dots> $ (Free (\"S\",\<dots>) $ \<dots>) $ 
   311                   (Free (\"T\",\<dots>) $ \<dots>))"}
   314                   (Free (\"T\",\<dots>) $ \<dots>))"}
   312 
   315 
   313   Whereas with @{ML make_wrong_imp} we obtain a term involving the @{term "P"} 
   316   whereas with @{ML make_wrong_imp} we obtain a term involving the @{term "P"} 
   314   and @{text "Q"} from the antiquotation.
   317   and @{text "Q"} from the antiquotation.
   315 
   318 
   316   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T} @{typ nat}" 
   319   @{ML_response [display,gray] "make_wrong_imp @{term S} @{term T} @{typ nat}" 
   317     "Const \<dots> $ 
   320     "Const \<dots> $ 
   318     Abs (\"x\", \<dots>,
   321     Abs (\"x\", \<dots>,
   319       Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   322       Const \<dots> $ (Const \<dots> $ (Free (\"P\",\<dots>) $ \<dots>)) $ 
   320                   (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"}
   323                   (Const \<dots> $ (Free (\"Q\",\<dots>) $ \<dots>)))"}
       
   324 
       
   325   (FIXME: expand the following point)
   321 
   326 
   322   One tricky point in constructing terms by hand is to obtain the fully
   327   One tricky point in constructing terms by hand is to obtain the fully
   323   qualified name for constants. For example the names for @{text "zero"} and
   328   qualified name for constants. For example the names for @{text "zero"} and
   324   @{text "+"} are more complex than one first expects, namely
   329   @{text "+"} are more complex than one first expects, namely
   325 
   330 
   388   term is well-formed, or type-checks, relative to a theory.
   393   term is well-formed, or type-checks, relative to a theory.
   389   Type-checking is done via the function @{ML cterm_of}, which converts 
   394   Type-checking is done via the function @{ML cterm_of}, which converts 
   390   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   395   a @{ML_type term} into a  @{ML_type cterm}, a \emph{certified} term. 
   391   Unlike @{ML_type term}s, which are just trees, @{ML_type
   396   Unlike @{ML_type term}s, which are just trees, @{ML_type
   392   "cterm"}s are abstract objects that are guaranteed to be
   397   "cterm"}s are abstract objects that are guaranteed to be
   393   type-correct, and they can only be constructed via the ``official
   398   type-correct, and they can only be constructed via ``official
   394   interfaces''.
   399   interfaces''.
   395 
   400 
   396   Type-checking is always relative to a theory context. For now we use
   401   Type-checking is always relative to a theory context. For now we use
   397   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   402   the @{ML "@{theory}"} antiquotation to get hold of the current theory.
   398   For example we can write
   403   For example we can write
   399 
   404 
   400   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   405   @{ML_response_fake [display,gray] "cterm_of @{theory} @{term \"a + b = c\"}" "a + b = c"}
   401 
   406 
   402   or use the antiquotation
   407   This can also be wirtten with an antiquotation
   403 
   408 
   404   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   409   @{ML_response_fake [display,gray] "@{cterm \"(a::nat) + b = c\"}" "a + b = c"}
   405 
   410 
   406   Attempting to obtain the certified term for
   411   Attempting to obtain the certified term for
   407 
   412 
   503 *}
   508 *}
   504 
   509 
   505 section {* Combinators\label{sec:combinators} *}
   510 section {* Combinators\label{sec:combinators} *}
   506 
   511 
   507 text {*
   512 text {*
   508   Perhaps one of the most puzzling aspects for a beginner when reading  
   513   Perhaps one of the most puzzling aspect for a beginner when reading  
   509   existing Isabelle code is the liberal use of combinators. At first they 
   514   existing Isabelle code special purpose combinators. At first they 
   510   seem to obstruct the comprehension of the code, but after getting familiar 
   515   seem to obstruct the comprehension of the code, but after getting familiar 
   511   with them they actually ease the reading and also the programming.
   516   with them they actually ease the understanding and also the programming.
   512 
   517 
   513   \begin{readmore}
   518   \begin{readmore}
   514   The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"}
   519   The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"}
   515   and @{ML_file "Pure/General/basics.ML"}.
   520   and @{ML_file "Pure/General/basics.ML"}.
   516   \end{readmore}
   521   \end{readmore}
   518   The simplest combinator is @{ML I} which is just the identity function.
   523   The simplest combinator is @{ML I} which is just the identity function.
   519 *}
   524 *}
   520 
   525 
   521 ML{*fun I x = x*}
   526 ML{*fun I x = x*}
   522 
   527 
   523 text {* Another frequently used combinator is @{ML K} *}
   528 text {* Another combinator is @{ML K}, defined as *}
   524 
   529 
   525 ML{*fun K x = fn _ => x*}
   530 ML{*fun K x = fn _ => x*}
   526 
   531 
   527 text {*
   532 text {*
   528   which ``wraps'' a function around the argument @{text "x"}. This function 
   533   It ``wraps'' a function around the argument @{text "x"}. However, this 
   529   ignores its argument. 
   534   function ignores its argument. 
   530 
   535 
   531   The next combinator is reverse application defined as 
   536   The next combinator is reverse application, @{ML "(op |>)"}, defined as 
   532 *}
   537 *}
   533 
   538 
   534 ML{*fun x |> f = f x*}
   539 ML{*fun x |> f = f x*}
   535 
   540 
   536 text {* The purpose of this combinator is to implement functions in a  
   541 text {* While just syntactic sugar for the usual function application,
       
   542   the purpose of this combinator is to implement functions in a  
   537   ``waterfall fashion''. Consider for example the function *}
   543   ``waterfall fashion''. Consider for example the function *}
   538 
   544 
   539 ML %linenumbers{*fun inc_by_five x =
   545 ML %linenumbers{*fun inc_by_five x =
   540   x |> (fn x => x + 1)
   546   x |> (fn x => x + 1)
   541     |> (fn x => (x, x))
   547     |> (fn x => (x, x))
   545 text {*
   551 text {*
   546   which increments the argument @{text x} by 5. It does this by first incrementing 
   552   which increments the argument @{text x} by 5. It does this by first incrementing 
   547   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   553   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   548   the first component of the pair (Line 4) and finally incrementing the first 
   554   the first component of the pair (Line 4) and finally incrementing the first 
   549   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   555   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   550   common when extending theories (for example by adding a definition, followed by
   556   common when dealing with theories (for example by adding a definition, followed by
   551   lemmas and so on). Writing the function @{ML inc_by_five} using the reverse
   557   lemmas and so on). Writing the function @{ML inc_by_five} using the reverse
   552   application is much clearer than writing
   558   application is much clearer than writing
   553 *}
   559 *}
   554 
   560 
   555 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   561 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   557 text {* or *}
   563 text {* or *}
   558 
   564 
   559 ML{*fun inc_by_five x = 
   565 ML{*fun inc_by_five x = 
   560        ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   566        ((fn x => x + 4) o fst o (fn x => (x, x)) o (fn x => x + 1)) x*}
   561 
   567 
   562 text {* and much more economical than *}
   568 text {* and typographically more economical than *}
   563 
   569 
   564 ML{*fun inc_by_five x =
   570 ML{*fun inc_by_five x =
   565    let val y1 = x + 1
   571    let val y1 = x + 1
   566        val y2 = (y1, y1)
   572        val y2 = (y1, y1)
   567        val y3 = fst y2
   573        val y3 = fst y2
   568        val y4 = y3 + 4
   574        val y4 = y3 + 4
   569    in y4 end*}
   575    in y4 end*}
   570 
   576 
   571 text {* 
   577 text {* 
       
   578   (FIXME: give a real world example involving theories)
       
   579 
   572   Similarly, the combinator @{ML "(op #>)"} is the reverse function 
   580   Similarly, the combinator @{ML "(op #>)"} is the reverse function 
   573   composition. It allows us to define functions as follows
   581   composition. It can be used to define functions as follows
   574 *}
   582 *}
   575 
   583 
   576 ML{*val inc_by_six = 
   584 ML{*val inc_by_six = 
   577       (fn x => x + 1)
   585       (fn x => x + 1)
   578    #> (fn x => x + 2)
   586    #> (fn x => x + 2)
   587 
   595 
   588   as expected.
   596   as expected.
   589 
   597 
   590   The remaining combinators add convenience for the ``waterfall method''
   598   The remaining combinators add convenience for the ``waterfall method''
   591   of writing functions. The combinator @{ML tap} allows one to get 
   599   of writing functions. The combinator @{ML tap} allows one to get 
   592   hold of a intermediate result for some side-calculations. For
   600   hold of an intermediate result (to do some side-calculations for instance). 
   593   example the function *}
   601   The function *}
   594 
   602 
   595 ML{*fun inc_by_three x =
   603 ML{*fun inc_by_three x =
   596      x |> (fn x => x + 1)
   604      x |> (fn x => x + 1)
   597        |> tap (fn x => tracing (makestring x))
   605        |> tap (fn x => tracing (makestring x))
   598        |> (fn x => x + 2)*}
   606        |> (fn x => x + 2)*}
   599 
   607 
   600 text {* increments the argument first by one and then by two. In the middle,
   608 text {* increments the argument first by one and then by two. In the middle,
   601   however, it prints the ``plus-one'' intermediate result inside the
   609   however, it uses @{ML tap} for printing the ``plus-one'' intermediate 
   602   tracing buffer.
   610   result inside the tracing buffer.
   603 
   611 
   604   The combinator @{ML "(op `)"} is similar, but applies a function to the value
   612   The combinator @{ML "(op `)"} is similar, but applies a function to the value
   605   and returns the result together with the original value as pair. For example
   613   and returns the result together with the original value (as pair). For example
   606   the following function takes @{text x} then increments @{text x} and returns
   614   the following function takes @{text x} as argument, and then first 
   607   the pair @{ML "(x + 1,x)" for x}. It then increments the right-hand component 
   615   increments @{text x}, but also keeps @{text x}. The intermediate result is 
   608   of the pair.
   616   therefore the pair @{ML "(x + 1,x)" for x}. The function then increments the 
       
   617   right-hand component of the pair.
   609 *}
   618 *}
   610 
   619 
   611 ML{*fun inc_as_pair x =
   620 ML{*fun inc_as_pair x =
   612      x |> `(fn x => x + 1)
   621      x |> `(fn x => x + 1)
   613        |> (fn (x, y) => (x, y + 1))*}
   622        |> (fn (x, y) => (x, y + 1))*}
   614 
   623 
   615 text {*
   624 text {*
   616   The combinators @{ML "(op |>>)"} and @{ML "(op ||>)"} are defined for 
   625   The combinators @{ML "(op |>>)"} and @{ML "(op ||>)"} are defined for 
   617   functions manipulating pairs. The first applies the function to
   626   functions manipulating pairs. The first applies the function to
   618   the first component of the pair:
   627   the first component of the pair, defined as:
   619 *}
   628 *}
   620 
   629 
   621 ML{*fun (x, y) |>> f = (f x, y)*}
   630 ML{*fun (x, y) |>> f = (f x, y)*}
   622 
   631 
   623 text {*
   632 text {*
   624   and the second combinator to the second component:
   633   and the second combinator to the second component, defined as
   625 *}
   634 *}
   626 
   635 
   627 ML{*fun (x, y) ||> f = (x, f y)*}
   636 ML{*fun (x, y) ||> f = (x, f y)*}
   628 
   637 
       
   638 text {*
       
   639   (FIXME: find a good exercise for combinators)
       
   640 *}
   629 
   641 
   630 end
   642 end