ProgTutorial/FirstSteps.thy
changeset 344 83d5bca38bec
parent 343 8f73e80c8c6f
child 346 0fea8b7a14a1
equal deleted inserted replaced
343:8f73e80c8c6f 344:83d5bca38bec
   350   For beginners perhaps the most puzzling parts in the existing code of Isabelle are
   350   For beginners perhaps the most puzzling parts in the existing code of Isabelle are
   351   the combinators. At first they seem to greatly obstruct the
   351   the combinators. At first they seem to greatly obstruct the
   352   comprehension of the code, but after getting familiar with them, they
   352   comprehension of the code, but after getting familiar with them, they
   353   actually ease the understanding and also the programming.
   353   actually ease the understanding and also the programming.
   354 
   354 
   355   The simplest combinator is @{ML_ind  I}, which is just the identity function defined as
   355   The simplest combinator is @{ML_ind I in Basic_Library}, which is just the 
       
   356   identity function defined as
   356 *}
   357 *}
   357 
   358 
   358 ML{*fun I x = x*}
   359 ML{*fun I x = x*}
   359 
   360 
   360 text {* Another simple combinator is @{ML_ind  K}, defined as *}
   361 text {* 
       
   362   Another simple combinator is @{ML_ind K in Library}, defined as 
       
   363 *}
   361 
   364 
   362 ML{*fun K x = fn _ => x*}
   365 ML{*fun K x = fn _ => x*}
   363 
   366 
   364 text {*
   367 text {*
   365   @{ML_ind  K} ``wraps'' a function around the argument @{text "x"}. However, this 
   368   @{ML K} ``wraps'' a function around the argument @{text "x"}. However, this 
   366   function ignores its argument. As a result, @{ML K} defines a constant function 
   369   function ignores its argument. As a result, @{ML K} defines a constant function 
   367   always returning @{text x}.
   370   always returning @{text x}.
   368 
   371 
   369   The next combinator is reverse application, @{ML_ind  "|>"}, defined as: 
   372   The next combinator is reverse application, @{ML_ind  "|>" in Basics}, defined as: 
   370 *}
   373 *}
   371 
   374 
   372 ML{*fun x |> f = f x*}
   375 ML{*fun x |> f = f x*}
   373 
   376 
   374 text {* While just syntactic sugar for the usual function application,
   377 text {* While just syntactic sugar for the usual function application,
   441    |> string_of_term ctxt
   444    |> string_of_term ctxt
   442    |> tracing
   445    |> tracing
   443 end" 
   446 end" 
   444   "P z za zb"}
   447   "P z za zb"}
   445 
   448 
   446   You can read off this behaviour from how @{ML apply_fresh_args} is
   449   You can read off this behaviour from how @{ML apply_fresh_args} is coded: in
   447   coded: in Line 2, the function @{ML_ind  fastype_of} calculates the type of the
   450   Line 2, the function @{ML_ind fastype_of in Term} calculates the type of the
   448   term; @{ML_ind binder_types} in the next line produces the list of argument
   451   term; @{ML_ind binder_types in Term} in the next line produces the list of
   449   types (in the case above the list @{text "[nat, int, unit]"}); Line 4 
   452   argument types (in the case above the list @{text "[nat, int, unit]"}); Line
   450   pairs up each type with the string  @{text "z"}; the
   453   4 pairs up each type with the string @{text "z"}; the function @{ML_ind
   451   function @{ML_ind  variant_frees in Variable} generates for each @{text "z"} a
   454   variant_frees in Variable} generates for each @{text "z"} a unique name
   452   unique name avoiding the given @{text f}; the list of name-type pairs is turned
   455   avoiding the given @{text f}; the list of name-type pairs is turned into a
   453   into a list of variable terms in Line 6, which in the last line is applied
   456   list of variable terms in Line 6, which in the last line is applied by the
   454   by the function @{ML_ind  list_comb} to the term. In this last step we have to 
   457   function @{ML_ind list_comb in Term} to the term. In this last step we have
   455   use the function @{ML_ind  curry}, because @{ML_ind  list_comb} expects the 
   458   to use the function @{ML_ind curry in Library}, because @{ML list_comb}
   456   function and the variables list as a pair. This kind of functions is often needed when
   459   expects the function and the variables list as a pair. This kind of
   457   constructing terms with fresh variables. The infrastructure helps tremendously 
   460   functions is often needed when constructing terms with fresh variables. The
   458   to avoid any name clashes. Consider for example: 
   461   infrastructure helps tremendously to avoid any name clashes. Consider for
       
   462   example:
   459 
   463 
   460    @{ML_response_fake [display,gray]
   464    @{ML_response_fake [display,gray]
   461 "let
   465 "let
   462   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   466   val t = @{term \"za::'a \<Rightarrow> 'b \<Rightarrow> 'c\"}
   463   val ctxt = @{context}
   467   val ctxt = @{context}
   468 end"
   472 end"
   469   "za z zb"}
   473   "za z zb"}
   470   
   474   
   471   where the @{text "za"} is correctly avoided.
   475   where the @{text "za"} is correctly avoided.
   472 
   476 
   473   The combinator @{ML_ind  "#>"} is the reverse function composition. It can be
   477   The combinator @{ML_ind "#>" in Basics} is the reverse function composition. 
   474   used to define the following function
   478   It can be used to define the following function
   475 *}
   479 *}
   476 
   480 
   477 ML{*val inc_by_six = 
   481 ML{*val inc_by_six = 
   478       (fn x => x + 1)
   482       (fn x => x + 1)
   479    #> (fn x => x + 2)
   483    #> (fn x => x + 2)
   483   which is the function composed of first the increment-by-one function and then
   487   which is the function composed of first the increment-by-one function and then
   484   increment-by-two, followed by increment-by-three. Again, the reverse function 
   488   increment-by-two, followed by increment-by-three. Again, the reverse function 
   485   composition allows you to read the code top-down.
   489   composition allows you to read the code top-down.
   486 
   490 
   487   The remaining combinators described in this section add convenience for the
   491   The remaining combinators described in this section add convenience for the
   488   ``waterfall method'' of writing functions. The combinator @{ML_ind  tap} allows
   492   ``waterfall method'' of writing functions. The combinator @{ML_ind tap in
   489   you to get hold of an intermediate result (to do some side-calculations for
   493   Basics} allows you to get hold of an intermediate result (to do some
   490   instance). The function
   494   side-calculations for instance). The function
   491 
       
   492  *}
   495  *}
   493 
   496 
   494 ML %linenosgray{*fun inc_by_three x =
   497 ML %linenosgray{*fun inc_by_three x =
   495      x |> (fn x => x + 1)
   498      x |> (fn x => x + 1)
   496        |> tap (fn x => tracing (PolyML.makestring x))
   499        |> tap (fn x => tracing (PolyML.makestring x))
   497        |> (fn x => x + 2)*}
   500        |> (fn x => x + 2)*}
   498 
   501 
   499 text {* 
   502 text {* 
   500   increments the argument first by @{text "1"} and then by @{text "2"}. In the
   503   increments the argument first by @{text "1"} and then by @{text "2"}. In the
   501   middle (Line 3), however, it uses @{ML_ind  tap} for printing the ``plus-one''
   504   middle (Line 3), however, it uses @{ML tap} for printing the ``plus-one''
   502   intermediate result inside the tracing buffer. The function @{ML_ind  tap} can
   505   intermediate result inside the tracing buffer. The function @{ML tap} can
   503   only be used for side-calculations, because any value that is computed
   506   only be used for side-calculations, because any value that is computed
   504   cannot be merged back into the ``main waterfall''. To do this, you can use
   507   cannot be merged back into the ``main waterfall''. To do this, you can use
   505   the next combinator.
   508   the next combinator.
   506 
   509 
   507   The combinator @{ML_ind  "`"} (a backtick) is similar to @{ML tap}, but applies a
   510   The combinator @{ML_ind "`" in Basics} (a backtick) is similar to @{ML tap},
   508   function to the value and returns the result together with the value (as a
   511   but applies a function to the value and returns the result together with the
   509   pair). For example the function 
   512   value (as a pair). For example the function
   510 *}
   513 *}
   511 
   514 
   512 ML{*fun inc_as_pair x =
   515 ML{*fun inc_as_pair x =
   513      x |> `(fn x => x + 1)
   516      x |> `(fn x => x + 1)
   514        |> (fn (x, y) => (x, y + 1))*}
   517        |> (fn (x, y) => (x, y + 1))*}
   517   takes @{text x} as argument, and then increments @{text x}, but also keeps
   520   takes @{text x} as argument, and then increments @{text x}, but also keeps
   518   @{text x}. The intermediate result is therefore the pair @{ML "(x + 1, x)"
   521   @{text x}. The intermediate result is therefore the pair @{ML "(x + 1, x)"
   519   for x}. After that, the function increments the right-hand component of the
   522   for x}. After that, the function increments the right-hand component of the
   520   pair. So finally the result will be @{ML "(x + 1, x + 1)" for x}.
   523   pair. So finally the result will be @{ML "(x + 1, x + 1)" for x}.
   521 
   524 
   522   The combinators @{ML_ind  "|>>"} and @{ML_ind  "||>"} are defined for 
   525   The combinators @{ML_ind "|>>" in Basics} and @{ML_ind "||>" in Basics} are
   523   functions manipulating pairs. The first applies the function to
   526   defined for functions manipulating pairs. The first applies the function to
   524   the first component of the pair, defined as
   527   the first component of the pair, defined as
   525 *}
   528 *}
   526 
   529 
   527 ML{*fun (x, y) |>> f = (f x, y)*}
   530 ML{*fun (x, y) |>> f = (f x, y)*}
   528 
   531 
   564 text {*
   567 text {*
   565   avoiding the explicit @{text "let"}. While in this example the gain in
   568   avoiding the explicit @{text "let"}. While in this example the gain in
   566   conciseness is only small, in more complicated situations the benefit of
   569   conciseness is only small, in more complicated situations the benefit of
   567   avoiding @{text "lets"} can be substantial.
   570   avoiding @{text "lets"} can be substantial.
   568 
   571 
   569   With the combinator @{ML_ind  "|->"} you can re-combine the elements from a pair.
   572   With the combinator @{ML_ind "|->" in Basics} you can re-combine the 
   570   This combinator is defined as
   573   elements from a pair. This combinator is defined as
   571 *}
   574 *}
   572 
   575 
   573 ML{*fun (x, y) |-> f = f x y*}
   576 ML{*fun (x, y) |-> f = f x y*}
   574 
   577 
   575 text {* 
   578 text {* 
   580 ML{*fun double x =
   583 ML{*fun double x =
   581       x |>  (fn x => (x, x))
   584       x |>  (fn x => (x, x))
   582         |-> (fn x => fn y => x + y)*}
   585         |-> (fn x => fn y => x + y)*}
   583 
   586 
   584 text {* 
   587 text {* 
   585   The combinator @{ML_ind  ||>>} plays a central rôle whenever your task is to update a 
   588   The combinator @{ML_ind ||>> in Basics} plays a central rôle whenever your
   586   theory and the update also produces a side-result (for example a theorem). Functions 
   589   task is to update a theory and the update also produces a side-result (for
   587   for such tasks return a pair whose second component is the theory and the fist 
   590   example a theorem). Functions for such tasks return a pair whose second
   588   component is the side-result. Using @{ML_ind  ||>>}, you can do conveniently the update 
   591   component is the theory and the fist component is the side-result. Using
   589   and also accumulate the side-results. Consider the following simple function. 
   592   @{ML ||>>}, you can do conveniently the update and also
       
   593   accumulate the side-results. Consider the following simple function.
   590 *}
   594 *}
   591 
   595 
   592 ML %linenosgray{*fun acc_incs x =
   596 ML %linenosgray{*fun acc_incs x =
   593     x |> (fn x => ("", x)) 
   597     x |> (fn x => ("", x)) 
   594       ||>> (fn x => (x, x + 1))
   598       ||>> (fn x => (x, x + 1))
   595       ||>> (fn x => (x, x + 1))
   599       ||>> (fn x => (x, x + 1))
   596       ||>> (fn x => (x, x + 1))*}
   600       ||>> (fn x => (x, x + 1))*}
   597 
   601 
   598 text {*
   602 text {*
   599   The purpose of Line 2 is to just pair up the argument with a dummy value (since
   603   The purpose of Line 2 is to just pair up the argument with a dummy value (since
   600   @{ML_ind  "||>>"} operates on pairs). Each of the next three lines just increment 
   604   @{ML ||>>} operates on pairs). Each of the next three lines just increment 
   601   the value by one, but also nest the intermediate results to the left. For example 
   605   the value by one, but also nest the intermediate results to the left. For example 
   602 
   606 
   603   @{ML_response [display,gray]
   607   @{ML_response [display,gray]
   604   "acc_incs 1"
   608   "acc_incs 1"
   605   "((((\"\", 1), 2), 3), 4)"}
   609   "((((\"\", 1), 2), 3), 4)"}
   612 
   616 
   613   \footnote{\bf FIXME: maybe give a ``real world'' example for this combinator.}
   617   \footnote{\bf FIXME: maybe give a ``real world'' example for this combinator.}
   614 *}
   618 *}
   615 
   619 
   616 text {*
   620 text {*
   617   Recall that @{ML_ind  "|>"} is the reverse function application. Recall also that
   621   Recall that @{ML "|>"} is the reverse function application. Recall also that
   618   the related 
   622   the related reverse function composition is @{ML "#>"}. In fact all the
   619   reverse function composition is @{ML_ind  "#>"}. In fact all the combinators 
   623   combinators @{ML "|->"}, @{ML "|>>"} , @{ML "||>"} and @{ML "||>>"}
   620   @{ML_ind  "|->"}, @{ML_ind  "|>>"} , @{ML_ind  "||>"} and @{ML_ind  
   624   described above have related combinators for function composition, namely
   621   "||>>"} described above have related combinators for 
   625   @{ML_ind "#->" in Basics}, @{ML_ind "#>>" in Basics}, @{ML_ind "##>" in
   622   function composition, namely @{ML_ind  "#->"}, @{ML_ind  "#>>"}, 
   626   Basics} and @{ML_ind "##>>" in Basics}. Using @{ML "#->"}, for example, the
   623   @{ML_ind  "##>"} and @{ML_ind  "##>>"}. 
   627   function @{text double} can also be written as:
   624   Using @{ML_ind  "#->"}, for example, the function @{text double} can also be written as:
       
   625 *}
   628 *}
   626 
   629 
   627 ML{*val double =
   630 ML{*val double =
   628             (fn x => (x, x))
   631             (fn x => (x, x))
   629         #-> (fn x => fn y => x + y)*}
   632         #-> (fn x => fn y => x + y)*}
   635   together. We have already seen such plumbing in the function @{ML
   638   together. We have already seen such plumbing in the function @{ML
   636   apply_fresh_args}, where @{ML curry} is needed for making the function @{ML
   639   apply_fresh_args}, where @{ML curry} is needed for making the function @{ML
   637   list_comb} that works over pairs to fit with the combinator @{ML "|>"}. Such 
   640   list_comb} that works over pairs to fit with the combinator @{ML "|>"}. Such 
   638   plumbing is also needed in situations where a function operate over lists, 
   641   plumbing is also needed in situations where a function operate over lists, 
   639   but one calculates only with a single element. An example is the function 
   642   but one calculates only with a single element. An example is the function 
   640   @{ML_ind  check_terms in Syntax}, whose purpose is to type-check a list 
   643   @{ML_ind check_terms in Syntax}, whose purpose is to type-check a list 
   641   of terms. Consider the code:
   644   of terms. Consider the code:
   642 
   645 
   643   @{ML_response_fake [display, gray]
   646   @{ML_response_fake [display, gray]
   644   "let
   647   "let
   645   val ctxt = @{context}
   648   val ctxt = @{context}
   706   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   709   @{ML_response [display,gray] "Context.theory_name @{theory}" "\"FirstSteps\""}
   707  
   710  
   708   where @{text "@{theory}"} is an antiquotation that is substituted with the
   711   where @{text "@{theory}"} is an antiquotation that is substituted with the
   709   current theory (remember that we assumed we are inside the theory 
   712   current theory (remember that we assumed we are inside the theory 
   710   @{text FirstSteps}). The name of this theory can be extracted using
   713   @{text FirstSteps}). The name of this theory can be extracted using
   711   the function @{ML_ind  theory_name in Context}. 
   714   the function @{ML_ind theory_name in Context}. 
   712 
   715 
   713   Note, however, that antiquotations are statically linked, that is their value is
   716   Note, however, that antiquotations are statically linked, that is their value is
   714   determined at ``compile-time'', not at ``run-time''. For example the function
   717   determined at ``compile-time'', not at ``run-time''. For example the function
   715 *}
   718 *}
   716 
   719 
   777   @{ML_response [display,gray]
   780   @{ML_response [display,gray]
   778   "@{binding \"name\"}"
   781   "@{binding \"name\"}"
   779   "name"}
   782   "name"}
   780 
   783 
   781   An example where a qualified name is needed is the function 
   784   An example where a qualified name is needed is the function 
   782   @{ML_ind  define in LocalTheory}.  This function is used below to define 
   785   @{ML_ind define in LocalTheory}.  This function is used below to define 
   783   the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
   786   the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
   784 *}
   787 *}
   785 
   788 
   786 local_setup %gray {* 
   789 local_setup %gray {* 
   787   LocalTheory.define Thm.internalK 
   790   LocalTheory.define Thm.internalK 
   812   also difficult to read. In the next chapter we will see how the (build in)
   815   also difficult to read. In the next chapter we will see how the (build in)
   813   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.  A
   816   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.  A
   814   restriction of this antiquotation is that it does not allow you to use
   817   restriction of this antiquotation is that it does not allow you to use
   815   schematic variables. If you want to have an antiquotation that does not have
   818   schematic variables. If you want to have an antiquotation that does not have
   816   this restriction, you can implement your own using the function @{ML_ind
   819   this restriction, you can implement your own using the function @{ML_ind
   817   ML_Antiquote.inline}. The code for the antiquotation @{text "term_pat"} is
   820   inline in ML_Antiquote}. The code for the antiquotation @{text "term_pat"} is
   818   as follows.
   821   as follows.
   819 *}
   822 *}
   820 
   823 
   821 ML %linenosgray{*let
   824 ML %linenosgray{*let
   822   val parser = Args.context -- Scan.lift Args.name_source
   825   val parser = Args.context -- Scan.lift Args.name_source