ProgTutorial/FirstSteps.thy
changeset 255 ef1da1abee46
parent 254 cb86bf5658e4
child 256 1fb8d62c88a0
equal deleted inserted replaced
254:cb86bf5658e4 255:ef1da1abee46
     1 theory FirstSteps
     1 theory FirstSteps
     2 imports Base
     2 imports Base
     3 begin
     3 begin
     4 
     4 
     5 chapter {* First Steps *}
     5 chapter {* First Steps *}
       
     6 
     6 
     7 
     7 text {*
     8 text {*
     8   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
     9   Isabelle programming is done in ML. Just like lemmas and proofs, ML-code
     9   in Isabelle is part of a theory. If you want to follow the code given in
    10   in Isabelle is part of a theory. If you want to follow the code given in
    10   this chapter, we assume you are working inside the theory starting with
    11   this chapter, we assume you are working inside the theory starting with
   108 
   109 
   109 text {*
   110 text {*
   110 
   111 
   111   During development you might find it necessary to inspect some data
   112   During development you might find it necessary to inspect some data
   112   in your code. This can be done in a ``quick-and-dirty'' fashion using 
   113   in your code. This can be done in a ``quick-and-dirty'' fashion using 
   113   the function @{ML "writeln"}. For example 
   114   the function @{ML [indexc] "writeln"}. For example 
   114 
   115 
   115   @{ML_response_fake [display,gray] "writeln \"any string\"" "\"any string\""}
   116   @{ML_response_fake [display,gray] "writeln \"any string\"" "\"any string\""}
   116 
   117 
   117   will print out @{text [quotes] "any string"} inside the response buffer
   118   will print out @{text [quotes] "any string"} inside the response buffer
   118   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
   119   of Isabelle.  This function expects a string as argument. If you develop under PolyML,
   714   writeln (Syntax.string_of_term @{context} omega)
   715   writeln (Syntax.string_of_term @{context} omega)
   715 end"
   716 end"
   716   "x x"}
   717   "x x"}
   717 
   718 
   718   with the raw ML-constructors.
   719   with the raw ML-constructors.
       
   720   
   719   Sometimes the internal representation of terms can be surprisingly different
   721   Sometimes the internal representation of terms can be surprisingly different
   720   from what you see at the user-level, because the layers of
   722   from what you see at the user-level, because the layers of
   721   parsing/type-checking/pretty printing can be quite elaborate. 
   723   parsing/type-checking/pretty printing can be quite elaborate. 
   722 
   724 
   723   \begin{exercise}
   725   \begin{exercise}
   779   definition and many useful operations are implemented 
   781   definition and many useful operations are implemented 
   780   in @{ML_file "Pure/type.ML"}.
   782   in @{ML_file "Pure/type.ML"}.
   781   \end{readmore}
   783   \end{readmore}
   782 *}
   784 *}
   783 
   785 
   784 section {* Constructing Terms and Types Manually\label{sec:terms_types_manually} *} 
   786 section {* Constructing Terms Manually\label{sec:terms_types_manually} *} 
   785 
   787 
   786 text {*
   788 text {*
   787   While antiquotations are very convenient for constructing terms, they can
   789   While antiquotations are very convenient for constructing terms, they can
   788   only construct fixed terms (remember they are ``linked'' at compile-time).
   790   only construct fixed terms (remember they are ``linked'' at compile-time).
   789   However, you often need to construct terms dynamically. For example, a
   791   However, you often need to construct terms dynamically. For example, a
   874 
   876 
   875   @{ML_response_fake [display, gray]
   877   @{ML_response_fake [display, gray]
   876   "subst_free [(@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})] 
   878   "subst_free [(@{term \"(\<lambda>y::nat. y)\"}, @{term \"x::nat\"})] 
   877   @{term \"(\<lambda>x::nat. x)\"}"
   879   @{term \"(\<lambda>x::nat. x)\"}"
   878   "Free (\"x\", \"nat\")"}
   880   "Free (\"x\", \"nat\")"}
       
   881 
       
   882   There are many convenient functions that construct specific HOL-terms. For
       
   883   example @{ML "HOLogic.mk_eq"} constructs an equality out of two terms.
       
   884   The types needed in this equality are calculated from the type of the
       
   885   arguments. For example
       
   886 
       
   887 @{ML_response_fake [gray,display]
       
   888   "writeln (Syntax.string_of_term @{context}
       
   889    (HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})))"
       
   890   "True = False"}
   879 
   891 
   880   \begin{readmore}
   892   \begin{readmore}
   881   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
   893   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file "Pure/logic.ML"} and
   882   @{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms 
   894   @{ML_file "HOL/Tools/hologic.ML"} that make such manual constructions of terms 
   883   and types easier.\end{readmore}
   895   and types easier.\end{readmore}
   895   \begin{exercise}\label{fun:makesum}
   907   \begin{exercise}\label{fun:makesum}
   896   Write a function which takes two terms representing natural numbers
   908   Write a function which takes two terms representing natural numbers
   897   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
   909   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
   898   number representing their sum.
   910   number representing their sum.
   899   \end{exercise}
   911   \end{exercise}
   900 
   912 *}
       
   913 
       
   914 section {* Constants *}
       
   915 
       
   916 text {*
   901   There are a few subtle issues with constants. They usually crop up when
   917   There are a few subtle issues with constants. They usually crop up when
   902   pattern matching terms or types, or when constructing them. While it is perfectly ok
   918   pattern matching terms or types, or when constructing them. While it is perfectly ok
   903   to write the function @{text is_true} as follows
   919   to write the function @{text is_true} as follows
   904 *}
   920 *}
   905 
   921 
  1001 
  1017 
  1002   \begin{readmore}
  1018   \begin{readmore}
  1003   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
  1019   Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};
  1004   functions about signatures in @{ML_file "Pure/sign.ML"}.
  1020   functions about signatures in @{ML_file "Pure/sign.ML"}.
  1005   \end{readmore}
  1021   \end{readmore}
  1006 
  1022 *}
       
  1023 
       
  1024 section {* Constructing Types Manually *}
       
  1025 
       
  1026 text {*
  1007   Although types of terms can often be inferred, there are many
  1027   Although types of terms can often be inferred, there are many
  1008   situations where you need to construct types manually, especially  
  1028   situations where you need to construct types manually, especially  
  1009   when defining constants. For example the function returning a function 
  1029   when defining constants. For example the function returning a function 
  1010   type is as follows:
  1030   type is as follows:
  1011 
  1031 
  1014 ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
  1034 ML{*fun make_fun_type ty1 ty2 = Type ("fun", [ty1, ty2]) *}
  1015 
  1035 
  1016 text {* This can be equally written with the combinator @{ML "-->"} as: *}
  1036 text {* This can be equally written with the combinator @{ML "-->"} as: *}
  1017 
  1037 
  1018 ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
  1038 ML{*fun make_fun_type ty1 ty2 = ty1 --> ty2 *}
       
  1039 
       
  1040 text {*
       
  1041   If you want to construct a function type with more than one argument
       
  1042   type, then you can use @{ML "--->"}.
       
  1043 *}
       
  1044 
       
  1045 ML{*fun make_fun_types tys ty = tys ---> ty *}
  1019 
  1046 
  1020 text {*
  1047 text {*
  1021   A handy function for manipulating terms is @{ML map_types}: it takes a 
  1048   A handy function for manipulating terms is @{ML map_types}: it takes a 
  1022   function and applies it to every type in a term. You can, for example,
  1049   function and applies it to every type in a term. You can, for example,
  1023   change every @{typ nat} in a term into an @{typ int} using the function:
  1050   change every @{typ nat} in a term into an @{typ int} using the function:
  1549   \emph{not} the received way of doing such things. The received way is to 
  1576   \emph{not} the received way of doing such things. The received way is to 
  1550   start a ``data slot'', below called @{text MyThmsData}, generated by the functor 
  1577   start a ``data slot'', below called @{text MyThmsData}, generated by the functor 
  1551   @{text GenericDataFun}:
  1578   @{text GenericDataFun}:
  1552 *}
  1579 *}
  1553 
  1580 
  1554 ML {*structure MyThmsData = GenericDataFun
  1581 ML{*structure MyThmsData = GenericDataFun
  1555  (type T = thm list
  1582  (type T = thm list
  1556   val empty = []
  1583   val empty = []
  1557   val extend = I
  1584   val extend = I
  1558   fun merge _ = Thm.merge_thms) *}
  1585   fun merge _ = Thm.merge_thms) *}
  1559 
  1586