ProgTutorial/FirstSteps.thy
changeset 280 a63ca3a9b44a
parent 279 2927f205abba
child 281 32b4d3704415
equal deleted inserted replaced
279:2927f205abba 280:a63ca3a9b44a
   470 text {* 
   470 text {* 
   471   The combinator @{ML [index] ||>>} plays a central rôle whenever your task is to update a 
   471   The combinator @{ML [index] ||>>} plays a central rôle whenever your task is to update a 
   472   theory and the update also produces a side-result (for example a theorem). Functions 
   472   theory and the update also produces a side-result (for example a theorem). Functions 
   473   for such tasks return a pair whose second component is the theory and the fist 
   473   for such tasks return a pair whose second component is the theory and the fist 
   474   component is the side-result. Using @{ML [index] ||>>}, you can do conveniently the update 
   474   component is the side-result. Using @{ML [index] ||>>}, you can do conveniently the update 
   475   and also accumulate the side-results. Considder the following simple function. 
   475   and also accumulate the side-results. Consider the following simple function. 
   476 *}
   476 *}
   477 
   477 
   478 ML %linenosgray{*fun acc_incs x =
   478 ML %linenosgray{*fun acc_incs x =
   479     x |> (fn x => ("", x)) 
   479     x |> (fn x => ("", x)) 
   480       ||>> (fn x => (x, x + 1))
   480       ||>> (fn x => (x, x + 1))
   482       ||>> (fn x => (x, x + 1))*}
   482       ||>> (fn x => (x, x + 1))*}
   483 
   483 
   484 text {*
   484 text {*
   485   The purpose of Line 2 is to just pair up the argument with a dummy value (since
   485   The purpose of Line 2 is to just pair up the argument with a dummy value (since
   486   @{ML [index] "||>>"} operates on pairs). Each of the next three lines just increment 
   486   @{ML [index] "||>>"} operates on pairs). Each of the next three lines just increment 
   487   the value by one, but also nest the intrermediate results to the left. For example 
   487   the value by one, but also nest the intermediate results to the left. For example 
   488 
   488 
   489   @{ML_response [display,gray]
   489   @{ML_response [display,gray]
   490   "acc_incs 1"
   490   "acc_incs 1"
   491   "((((\"\", 1), 2), 3), 4)"}
   491   "((((\"\", 1), 2), 3), 4)"}
   492 
   492 
  1590 
  1590 
  1591 attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
  1591 attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
  1592   "maintaining a list of my_thms - rough test only!" 
  1592   "maintaining a list of my_thms - rough test only!" 
  1593 
  1593 
  1594 text {*
  1594 text {*
  1595   The parser @{ML [index] add_del in Attrib} is a pre-defined parser for 
  1595   The parser @{ML [index] add_del in Attrib} is a predefined parser for 
  1596   adding and deleting lemmas. Now if you prove the next lemma 
  1596   adding and deleting lemmas. Now if you prove the next lemma 
  1597   and attach to it the attribute @{text "[my_thms]"}
  1597   and attach to it the attribute @{text "[my_thms]"}
  1598 *}
  1598 *}
  1599 
  1599 
  1600 lemma trueI_2[my_thms]: "True" by simp
  1600 lemma trueI_2[my_thms]: "True" by simp
  1658 ML{*val my_thm_add = MyThmsData.map o Thm.add_thm
  1658 ML{*val my_thm_add = MyThmsData.map o Thm.add_thm
  1659 val my_thm_del = MyThmsData.map o Thm.del_thm*}
  1659 val my_thm_del = MyThmsData.map o Thm.del_thm*}
  1660 
  1660 
  1661 text {*
  1661 text {*
  1662   where @{ML MyThmsData.map} updates the data appropriately. The
  1662   where @{ML MyThmsData.map} updates the data appropriately. The
  1663   corresponding theorem addtributes are
  1663   corresponding theorem attributes are
  1664 *}
  1664 *}
  1665 
  1665 
  1666 ML{*val my_add = Thm.declaration_attribute my_thm_add
  1666 ML{*val my_add = Thm.declaration_attribute my_thm_add
  1667 val my_del = Thm.declaration_attribute my_thm_del *}
  1667 val my_del = Thm.declaration_attribute my_thm_del *}
  1668 
  1668 
  1898 
  1898 
  1899 section {* Pretty-Printing\label{sec:pretty} *}
  1899 section {* Pretty-Printing\label{sec:pretty} *}
  1900 
  1900 
  1901 text {*
  1901 text {*
  1902   So far we printed out only plain strings without any formatting except for
  1902   So far we printed out only plain strings without any formatting except for
  1903   occasional explicit linebreaks using @{text [quotes] "\\n"}. This is
  1903   occasional explicit line breaks using @{text [quotes] "\\n"}. This is
  1904   sufficient for ``quick-and-dirty'' printouts. For something more
  1904   sufficient for ``quick-and-dirty'' printouts. For something more
  1905   sophisticated, Isabelle includes an infrastructure for properly formatting text.
  1905   sophisticated, Isabelle includes an infrastructure for properly formatting text.
  1906   This infrastructure is loosely based on a paper by Oppen~\cite{Oppen80}. Most of
  1906   This infrastructure is loosely based on a paper by Oppen~\cite{Oppen80}. Most of
  1907   its functions do not operate on @{ML_type string}s, but on instances of the
  1907   its functions do not operate on @{ML_type string}s, but on instances of the
  1908   type:
  1908   type:
  1928 ML{*fun pprint prt = writeln (Pretty.string_of prt)*}
  1928 ML{*fun pprint prt = writeln (Pretty.string_of prt)*}
  1929 
  1929 
  1930 text {*
  1930 text {*
  1931   The point of the pretty-printing infrastructure is to give hints about how to
  1931   The point of the pretty-printing infrastructure is to give hints about how to
  1932   layout text and let Isabelle do the actual layout. Let us first explain
  1932   layout text and let Isabelle do the actual layout. Let us first explain
  1933   how you can insert places where a linebreak can occur. For this assume the
  1933   how you can insert places where a line break can occur. For this assume the
  1934   following function that replicates a string n times:
  1934   following function that replicates a string n times:
  1935 *}
  1935 *}
  1936 
  1936 
  1937 ML{*fun rep n str = implode (replicate n str) *}
  1937 ML{*fun rep n str = implode (replicate n str) *}
  1938 
  1938 
  1941 *}
  1941 *}
  1942 
  1942 
  1943 ML{*val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "*}
  1943 ML{*val test_str = rep 8 "fooooooooooooooobaaaaaaaaaaaar "*}
  1944 
  1944 
  1945 text {*
  1945 text {*
  1946   We deliberately chosed a large string so that is spans over more than one line. 
  1946   We deliberately chose a large string so that is spans over more than one line. 
  1947   If we print out the string using the usual ``quick-and-dirty'' method, then
  1947   If we print out the string using the usual ``quick-and-dirty'' method, then
  1948   we obtain the ugly output:
  1948   we obtain the ugly output:
  1949 
  1949 
  1950 @{ML_response_fake [display,gray]
  1950 @{ML_response_fake [display,gray]
  1951 "writeln test_str"
  1951 "writeln test_str"
  1962 ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
  1962 ooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaa
  1963 aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
  1963 aaaaaaar fooooooooooooooobaaaaaaaaaaaar fooooooooooooooobaaaaaaaaaaaar fo
  1964 oooooooooooooobaaaaaaaaaaaar"}
  1964 oooooooooooooobaaaaaaaaaaaar"}
  1965 
  1965 
  1966   However by using pretty types you have the ability to indicate a possible
  1966   However by using pretty types you have the ability to indicate a possible
  1967   linebreak for example at each space. You can achieve this with the function
  1967   line break for example at each space. You can achieve this with the function
  1968   @{ML [index] breaks in Pretty}, which expects a list of pretty types and inserts a
  1968   @{ML [index] breaks in Pretty}, which expects a list of pretty types and inserts a
  1969   possible linebreak in between every two elements in this list. To print
  1969   possible line break in between every two elements in this list. To print
  1970   this list of pretty types as a single string, we concatenate them 
  1970   this list of pretty types as a single string, we concatenate them 
  1971   with the function @{ML [index] blk in Pretty} as follows:
  1971   with the function @{ML [index] blk in Pretty} as follows:
  1972 
  1972 
  1973 
  1973 
  1974 @{ML_response_fake [display,gray]
  1974 @{ML_response_fake [display,gray]
  2046 
  2046 
  2047   As can be seen, this function prints out the ``set'' so that starting 
  2047   As can be seen, this function prints out the ``set'' so that starting 
  2048   from the second, each new line as an indentation of 2.
  2048   from the second, each new line as an indentation of 2.
  2049   
  2049   
  2050   If you print out something that goes beyond the capabilities of the
  2050   If you print out something that goes beyond the capabilities of the
  2051   standard functions, you can do realatively easily the formating
  2051   standard functions, you can do relatively easily the formatting
  2052   yourself. Assume you want to print out a list of items where like in ``English''
  2052   yourself. Assume you want to print out a list of items where like in ``English''
  2053   the last two items are separated by @{text [quotes] "and"}. For this you can
  2053   the last two items are separated by @{text [quotes] "and"}. For this you can
  2054   write the function
  2054   write the function
  2055 
  2055 
  2056 *}
  2056 *}
  2067 
  2067 
  2068 text {*
  2068 text {*
  2069   where Line 7 prints the beginning of the list and Line
  2069   where Line 7 prints the beginning of the list and Line
  2070   8 the last item. We have to use @{ML "Pretty.brk 1"} in order
  2070   8 the last item. We have to use @{ML "Pretty.brk 1"} in order
  2071   to insert a space (of length 1) before the 
  2071   to insert a space (of length 1) before the 
  2072   @{text [quotes] "and"}. This space is also a pleace where a linebreak 
  2072   @{text [quotes] "and"}. This space is also a place where a line break 
  2073   can occur. We do the same ater the @{text [quotes] "and"}. This gives you
  2073   can occur. We do the same after the @{text [quotes] "and"}. This gives you
  2074   for example
  2074   for example
  2075 
  2075 
  2076 @{ML_response_fake [display,gray]
  2076 @{ML_response_fake [display,gray]
  2077 "let
  2077 "let
  2078   val ptrs = map (Pretty.str o string_of_int) (1 upto 22)
  2078   val ptrs = map (Pretty.str o string_of_int) (1 upto 22)
  2102   where a space is. In Lines 4 and 5 we pretty-print the term and its type
  2102   where a space is. In Lines 4 and 5 we pretty-print the term and its type
  2103   using the functions @{ML [index] pretty_term in Syntax} and @{ML [index]
  2103   using the functions @{ML [index] pretty_term in Syntax} and @{ML [index]
  2104   pretty_typ in Syntax}. We also use the function @{ML [index] quote in
  2104   pretty_typ in Syntax}. We also use the function @{ML [index] quote in
  2105   Pretty} in order to enclose the term and type inside quotation marks. In
  2105   Pretty} in order to enclose the term and type inside quotation marks. In
  2106   Line 9 we add a period right after the type without the possibility of a
  2106   Line 9 we add a period right after the type without the possibility of a
  2107   linebreak, because we do not want that a linebreak occurs there.
  2107   line break, because we do not want that a line break occurs there.
  2108 
  2108 
  2109 
  2109 
  2110   Now you can write
  2110   Now you can write
  2111 
  2111 
  2112   @{ML_response_fake [display,gray]
  2112   @{ML_response_fake [display,gray]
  2113   "tell_type @{context} @{term \"min (Suc 0)\"}"
  2113   "tell_type @{context} @{term \"min (Suc 0)\"}"
  2114   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
  2114   "The term \"min (Suc 0)\" has type \"nat \<Rightarrow> nat\"."}
  2115   
  2115   
  2116   To see the proper linebreaking, you can try out the function on a bigger term 
  2116   To see the proper line breaking, you can try out the function on a bigger term 
  2117   and type. For example:
  2117   and type. For example:
  2118 
  2118 
  2119   @{ML_response_fake [display,gray]
  2119   @{ML_response_fake [display,gray]
  2120   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
  2120   "tell_type @{context} @{term \"op = (op = (op = (op = (op = op =))))\"}"
  2121   "The term \"op = (op = (op = (op = (op = op =))))\" has type 
  2121   "The term \"op = (op = (op = (op = (op = op =))))\" has type