CookBook/FirstSteps.thy
changeset 101 123401a5c8e9
parent 100 dd8eebae11ec
child 102 5e309df58557
equal deleted inserted replaced
100:dd8eebae11ec 101:123401a5c8e9
   517 section {* Theorem Attributes *}
   517 section {* Theorem Attributes *}
   518 
   518 
   519 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *}
   519 section {* Printing Terms, CTerms and Theorems\label{sec:printing} *}
   520 
   520 
   521 text {* 
   521 text {* 
   522   It will often be necesseary to inspect terms, cterms or theorems. Isabelle
   522   You will occationally feel the need to inspect terms, cterms or theorems during
   523   contains elaborate pretty-printing functions for that, but for quick-and-dirty
   523   development. Isabelle contains elaborate pretty-printing functions for that, but 
   524   solutions they are too unwieldy. A term can be transformed into a string using
   524   for quick-and-dirty solutions they are way too unwieldy. A simple way to transform 
   525   the function @{ML Syntax.string_of_term}
   525   a term into a string is to use the function @{ML Syntax.string_of_term}.
   526 
   526 
   527   @{ML_response_fake [display,gray]
   527   @{ML_response_fake [display,gray]
   528   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   528   "Syntax.string_of_term @{context} @{term \"1::nat\"}"
   529   "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""}
   529   "\"\\^E\\^Fterm\\^E\\^E\\^Fconst\\^Fname=HOL.one_class.one\\^E1\\^E\\^F\\^E\\^E\\^F\\^E\""}
   530 
   530 
   531   This produces a string, though with printing directions encoded in it. This
   531   This produces a string, though with printing directions encoded in it. The string
   532   can be properly printed, when enclosed in a @{ML warning}
   532   can be properly printed, when enclosed in a @{ML warning}.
   533 
   533 
   534   @{ML_response_fake [display,gray]
   534   @{ML_response_fake [display,gray]
   535   "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})"
   535   "warning (Syntax.string_of_term @{context} @{term \"1::nat\"})"
   536   "\"1\""}
   536   "\"1\""}
   537 
   537 
   538   A @{ML_type cterm} can be transformed into a string by the function:
   538   A @{ML_type cterm} can be transformed into a string by the following function.
   539 *}
   539 *}
   540 
   540 
   541 ML{*fun str_of_cterm ctxt t =  
   541 ML{*fun str_of_cterm ctxt t =  
   542    Syntax.string_of_term ctxt (term_of t)*}
   542    Syntax.string_of_term ctxt (term_of t)*}
   543 
   543 
   544 text {*
   544 text {*
   545   If there are more than one @{ML_type cterm} to be printed, we can use the function
   545   If there are more than one @{ML_type cterm} to be printed, you can use the function
   546   @{ML commas} to conveniently separate them.
   546   @{ML commas} to conveniently separate them.
   547 *} 
   547 *} 
   548 
   548 
   549 ML{*fun str_of_cterms ctxt ts =  
   549 ML{*fun str_of_cterms ctxt ts =  
   550   commas (map (str_of_cterm ctxt) ts)*}
   550   commas (map (str_of_cterm ctxt) ts)*}
   551 
   551 
   552 text {*
   552 text {*
   553   The easiest way to get the string of a theorem, is to transform it
   553   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}.
   554   into a @{ML_type cterm} using the function @{ML crep_thm}.
   555 *}
   555 *}
   556 
   556 
   557 ML{*fun str_of_thm ctxt thm =
   557 ML{*fun str_of_thm ctxt thm =
   558   let
   558   let
   560   in 
   560   in 
   561     str_of_cterm ctxt prop
   561     str_of_cterm ctxt prop
   562   end*}
   562   end*}
   563 
   563 
   564 text {* 
   564 text {* 
   565   For more than one theorem, the following function adds commas in between them. 
   565   Again the function @{ML commas} helps with printing more than one theorem. 
   566 *}
   566 *}
   567 
   567 
   568 ML{*fun str_of_thms ctxt thms =  
   568 ML{*fun str_of_thms ctxt thms =  
   569   commas (map (str_of_thm ctxt) thms)*}
   569   commas (map (str_of_thm ctxt) thms)*}
   570 
   570 
   602   actually ease the understanding and also the programming.
   602   actually ease the understanding and also the programming.
   603 
   603 
   604   \begin{readmore}
   604   \begin{readmore}
   605   The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"}
   605   The most frequently used combinator are defined in the files @{ML_file "Pure/library.ML"}
   606   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   606   and @{ML_file "Pure/General/basics.ML"}. Also \isccite{sec:ML-linear-trans} 
   607   contains further information about combinators.
   607   contains further information about them.
   608   \end{readmore}
   608   \end{readmore}
   609 
   609 
   610   The simplest combinator is @{ML I}, which is just the identity function.
   610   The simplest combinator is @{ML I}, which is just the identity function.
   611 *}
   611 *}
   612 
   612 
   616 
   616 
   617 ML{*fun K x = fn _ => x*}
   617 ML{*fun K x = fn _ => x*}
   618 
   618 
   619 text {*
   619 text {*
   620   @{ML K} ``wraps'' a function around the argument @{text "x"}. However, this 
   620   @{ML K} ``wraps'' a function around the argument @{text "x"}. However, this 
   621   function ignores its argument. As a result @{ML K} defines a constant function 
   621   function ignores its argument. As a result, @{ML K} defines a constant function 
   622   returning @{text x}.
   622   returning @{text x}.
   623 
   623 
   624   The next combinator is reverse application, @{ML "|>"}, defined as 
   624   The next combinator is reverse application, @{ML "|>"}, defined as: 
   625 *}
   625 *}
   626 
   626 
   627 ML{*fun x |> f = f x*}
   627 ML{*fun x |> f = f x*}
   628 
   628 
   629 text {* While just syntactic sugar for the usual function application,
   629 text {* While just syntactic sugar for the usual function application,
   640   which increments the argument @{text x} by 5. It does this by first incrementing 
   640   which increments the argument @{text x} by 5. It does this by first incrementing 
   641   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   641   the argument by 1 (Line 2); then storing the result in a pair (Line 3); taking 
   642   the first component of the pair (Line 4) and finally incrementing the first 
   642   the first component of the pair (Line 4) and finally incrementing the first 
   643   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   643   component by 4 (Line 5). This kind of cascading manipulations of values is quite
   644   common when dealing with theories (for example by adding a definition, followed by
   644   common when dealing with theories (for example by adding a definition, followed by
   645   lemmas and so on). The reverse application allows you to read what happens inside
   645   lemmas and so on). The reverse application allows you to read what happens in 
   646   the function in a top-down manner. This kind of codeing should also be familiar, 
   646   a top-down manner. This kind of coding should also be familiar, 
   647   if you used Haskell's do-notation. Writing the function @{ML inc_by_five} using 
   647   if you used Haskell's do-notation. Writing the function @{ML inc_by_five} using 
   648   the reverse application is much clearer than writing
   648   the reverse application is much clearer than writing
   649 *}
   649 *}
   650 
   650 
   651 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}
   651 ML{*fun inc_by_five x = fst ((fn x => (x, x)) (x + 1)) + 4*}