ProgTutorial/FirstSteps.thy
changeset 329 5dffcab68680
parent 328 c0cae24b9d46
child 330 7718da58d9c0
equal deleted inserted replaced
328:c0cae24b9d46 329:5dffcab68680
   118   ML-file should not contain any \isacommand{use} itself. Otherwise Isabelle
   118   ML-file should not contain any \isacommand{use} itself. Otherwise Isabelle
   119   is unable to record all file dependencies, which is a nuisance if you have
   119   is unable to record all file dependencies, which is a nuisance if you have
   120   to track down errors.
   120   to track down errors.
   121 *}
   121 *}
   122 
   122 
   123 section {* Debugging and Printing\label{sec:printing} *}
   123 section {* Printing and Debugging\label{sec:printing} *}
   124 
   124 
   125 text {*
   125 text {*
   126   During development you might find it necessary to inspect some data in your
   126   During development you might find it necessary to inspect some data in your
   127   code. This can be done in a ``quick-and-dirty'' fashion using the function
   127   code. This can be done in a ``quick-and-dirty'' fashion using the function
   128   @{ML_ind  "writeln"}. For example
   128   @{ML_ind  "writeln"}. For example
   209   Most often you want to inspect data of Isabelle's most basic data
   209   Most often you want to inspect data of Isabelle's most basic data
   210   structures, namely @{ML_type term}, @{ML_type cterm} and @{ML_type
   210   structures, namely @{ML_type term}, @{ML_type cterm} and @{ML_type
   211   thm}. Isabelle contains elaborate pretty-printing functions for printing
   211   thm}. Isabelle contains elaborate pretty-printing functions for printing
   212   them (see Section \ref{sec:pretty}), but for quick-and-dirty solutions they
   212   them (see Section \ref{sec:pretty}), but for quick-and-dirty solutions they
   213   are a bit unwieldy. One way to transform a term into a string is to use the
   213   are a bit unwieldy. One way to transform a term into a string is to use the
   214   function @{ML_ind  string_of_term in Syntax} in structure @{ML_struct
   214   function @{ML_ind  string_of_term in Syntax} in the structure @{ML_struct
   215   Syntax}, which we bind for more convenience to the toplevel.
   215   Syntax}, which we bind for more convenience to the toplevel.
   216 *}
   216 *}
   217 
   217 
   218 ML{*val string_of_term = Syntax.string_of_term*}
   218 ML{*val string_of_term = Syntax.string_of_term*}
   219 
   219 
   633   When using combinators for writing functions in waterfall fashion, it is
   633   When using combinators for writing functions in waterfall fashion, it is
   634   sometimes necessary to do some ``plumbing'' in order to fit functions
   634   sometimes necessary to do some ``plumbing'' in order to fit functions
   635   together. We have already seen such plumbing in the function @{ML
   635   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
   636   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 
   637   list_comb} that works over pairs to fit with the combinator @{ML "|>"}. Such 
   638   plumbing is also needed in situations where a functions operate over lists, 
   638   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 
   639   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 
   640   @{ML_ind  check_terms in Syntax}, whose purpose is to type-check a list 
   641   of terms.
   641   of terms.
   642 
   642 
   643   @{ML_response_fake [display, gray]
   643   @{ML_response_fake [display, gray]
   651 end"
   651 end"
   652   "m + n, m * n, m - n"}
   652   "m + n, m * n, m - n"}
   653 *}
   653 *}
   654 
   654 
   655 text {*
   655 text {*
   656   In this example we obtain three terms in which @{text m} and @{text n} are of
   656   In this example we obtain three terms whose variables @{text m} and @{text
   657   type @{typ "nat"}. If you have only a single term, then @{ML
   657   n} are of type @{typ "nat"}. If you have only a single term, then @{ML
   658   check_terms in Syntax} needs plumbing. This can be done with the function
   658   check_terms in Syntax} needs plumbing. This can be done with the function
   659   @{ML singleton}.\footnote{There is already a function @{ML check_term in
   659   @{ML singleton}.\footnote{There is already a function @{ML check_term in
   660   Syntax} in the Isabelle sources that is defined in terms of @{ML singleton}
   660   Syntax} in the Isabelle sources that is defined in terms of @{ML singleton}
   661   and @{ML check_terms in Syntax}.} For example
   661   and @{ML check_terms in Syntax}.} For example
   662 
   662 
   711   current theory (remember that we assumed we are inside the theory 
   711   current theory (remember that we assumed we are inside the theory 
   712   @{text FirstSteps}). The name of this theory can be extracted using
   712   @{text FirstSteps}). The name of this theory can be extracted using
   713   the function @{ML_ind  theory_name in Context}. 
   713   the function @{ML_ind  theory_name in Context}. 
   714 
   714 
   715   Note, however, that antiquotations are statically linked, that is their value is
   715   Note, however, that antiquotations are statically linked, that is their value is
   716   determined at ``compile-time'', not ``run-time''. For example the function
   716   determined at ``compile-time'', not at ``run-time''. For example the function
   717 *}
   717 *}
   718 
   718 
   719 ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   719 ML{*fun not_current_thyname () = Context.theory_name @{theory} *}
   720 
   720 
   721 text {*
   721 text {*
   741 ((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"}  
   741 ((?P \<and> ?Q) \<and> ?R) = (?P \<and> ?Q \<and> ?R)"}  
   742 
   742 
   743   The point of these antiquotations is that referring to theorems in this way
   743   The point of these antiquotations is that referring to theorems in this way
   744   makes your code independent from what theorems the user might have stored
   744   makes your code independent from what theorems the user might have stored
   745   under this name (this becomes especially important when you deal with
   745   under this name (this becomes especially important when you deal with
   746   theorem lists; see Section \ref{sec:attributes}).
   746   theorem lists; see Section \ref{sec:storing}).
   747 
   747 
   748   You can also refer to the current simpset via an antiquotation. To illustrate 
   748   You can also refer to the current simpset via an antiquotation. To illustrate 
   749   this we implement the function that extracts the theorem names stored in a 
   749   this we implement the function that extracts the theorem names stored in a 
   750   simpset.
   750   simpset.
   751 *}
   751 *}
   782 
   782 
   783   An example where a qualified name is needed is the function 
   783   An example where a qualified name is needed is the function 
   784   @{ML_ind  define in LocalTheory}.  This function is used below to define 
   784   @{ML_ind  define in LocalTheory}.  This function is used below to define 
   785   the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
   785   the constant @{term "TrueConj"} as the conjunction @{term "True \<and> True"}.
   786 *}
   786 *}
   787   
   787 
   788 local_setup %gray {* 
   788 local_setup %gray {* 
   789   LocalTheory.define Thm.internalK 
   789   LocalTheory.define Thm.internalK 
   790     ((@{binding "TrueConj"}, NoSyn), 
   790     ((@{binding "TrueConj"}, NoSyn), 
   791       (Attrib.empty_binding, @{term "True \<and> True"})) #> snd *}
   791       (Attrib.empty_binding, @{term "True \<and> True"})) #> snd *}
   792 
   792 
   796   \begin{isabelle}
   796   \begin{isabelle}
   797   \isacommand{thm}~@{text "TrueConj_def"}\\
   797   \isacommand{thm}~@{text "TrueConj_def"}\\
   798   @{text "> "}~@{thm TrueConj_def}
   798   @{text "> "}~@{thm TrueConj_def}
   799   \end{isabelle}
   799   \end{isabelle}
   800 
   800 
       
   801   \begin{readmore}
       
   802   The basic operations on bindings are implemented in 
       
   803   @{ML_file "Pure/General/binding.ML"}.
       
   804   \end{readmore}
       
   805 
   801   \footnote{\bf FIXME give a better example why bindings are important; maybe
   806   \footnote{\bf FIXME give a better example why bindings are important; maybe
   802   give a pointer to \isacommand{local\_setup}; if not, then explain
   807   give a pointer to \isacommand{local\_setup}; if not, then explain
   803   why @{ML snd} is needed.}
   808   why @{ML snd} is needed.}
       
   809   \footnote{\bf FIXME: There should probably a separate section on binding, long-names
       
   810   and sign.}
   804 
   811 
   805   It is also possible to define your own antiquotations. But you should
   812   It is also possible to define your own antiquotations. But you should
   806   exercise care when introducing new ones, as they can also make your code
   813   exercise care when introducing new ones, as they can also make your code
   807   also difficult to read. In the next chapter we will see how the (build in)
   814   also difficult to read. In the next chapter we will see how the (build in)
   808   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.  A
   815   antiquotation @{text "@{term \<dots>}"} can be used to construct terms.  A
  1014 
  1021 
  1015   @{ML_response_fake [display,gray]
  1022   @{ML_response_fake [display,gray]
  1016   "WrongRefData.get @{theory}"
  1023   "WrongRefData.get @{theory}"
  1017   "ref []"}
  1024   "ref []"}
  1018 
  1025 
  1019   For updating the reference we use the following function.
  1026   For updating the reference we use the following function
  1020 *}
  1027 *}
  1021 
  1028 
  1022 ML{*fun ref_update n = WrongRefData.map 
  1029 ML{*fun ref_update n = WrongRefData.map 
  1023       (fn r => let val _ = r := n::(!r) in r end)*}
  1030       (fn r => let val _ = r := n::(!r) in r end)*}
  1024 
  1031 
  1025 text {*
  1032 text {*
       
  1033   which takes an integer and adds it to the content of the reference.
  1026   As above we update the reference with the command 
  1034   As above we update the reference with the command 
  1027   \isacommand{setup}. 
  1035   \isacommand{setup}. 
  1028 *}
  1036 *}
  1029 
  1037 
  1030 setup %gray{* ref_update 1 *}
  1038 setup %gray{* ref_update 1 *}
  1049   "WrongRefData.get @{theory}"
  1057   "WrongRefData.get @{theory}"
  1050   "ref [1, 1]"}
  1058   "ref [1, 1]"}
  1051 
  1059 
  1052   Now imagine how often you go backwards and forwards in your proof scripts. 
  1060   Now imagine how often you go backwards and forwards in your proof scripts. 
  1053   By using references in Isabelle code, you are bound to cause all
  1061   By using references in Isabelle code, you are bound to cause all
  1054   hell to break lose. Therefore observe the coding convention: 
  1062   hell to break loose. Therefore observe the coding convention: 
  1055   Do not use references for storing data!
  1063   Do not use references for storing data!
  1056 
  1064 
  1057   \begin{readmore}
  1065   \begin{readmore}
  1058   The functors for data storage are defined in @{ML_file "Pure/context.ML"}.
  1066   The functors for data storage are defined in @{ML_file "Pure/context.ML"}.
  1059   Isabelle contains implementations of several container data structures,
  1067   Isabelle contains implementations of several container data structures,
  1060   including association lists in @{ML_file "Pure/General/alist.ML"},
  1068   including association lists in @{ML_file "Pure/General/alist.ML"},
  1061   directed graphs in @{ML_file "Pure/General/graph.ML"}. and 
  1069   directed graphs in @{ML_file "Pure/General/graph.ML"}. and 
  1062   tables and symtables in @{ML_file "Pure/General/table.ML"}.
  1070   tables and symtables in @{ML_file "Pure/General/table.ML"}.
  1063   \end{readmore}
       
  1064 
       
  1065   A special instance of the data storage mechanism described above are
       
  1066   configuration values. They are used to enable users to configure tools
       
  1067   without having to resort to the ML-level (and also to avoid
       
  1068   references). Assume you want the user to control three values, say @{text
       
  1069   bval} containing a boolean, @{text ival} containing an integer and @{text
       
  1070   sval} containing a string. These values can be declared by
       
  1071 *}
       
  1072 
       
  1073 ML{*val (bval, setup_bval) = Attrib.config_bool "bval" false
       
  1074 val (ival, setup_ival) = Attrib.config_int "ival" 0
       
  1075 val (sval, setup_sval) = Attrib.config_string "sval" "some string" *}
       
  1076 
       
  1077 text {* 
       
  1078   where each value needs to be given a default. To enable these values, they need to 
       
  1079   be set up with
       
  1080 *}
       
  1081 
       
  1082 setup %gray {* 
       
  1083   setup_bval #> 
       
  1084   setup_ival 
       
  1085 *}
       
  1086 
       
  1087 text {*
       
  1088   The user can now manipulate the values from the user-level of Isabelle 
       
  1089   with the command
       
  1090 *}
       
  1091 
       
  1092 declare [[bval = true, ival = 3]]
       
  1093 
       
  1094 text {*
       
  1095   On the ML-level these values can be retrieved using the 
       
  1096   function @{ML Config.get}.
       
  1097 
       
  1098   @{ML_response [display,gray] "Config.get @{context} bval" "true"}
       
  1099 
       
  1100   \begin{readmore}
       
  1101   For more information about configuration values see 
       
  1102   @{ML_file "Pure/Isar/attrib.ML"} and @{ML_file "Pure/config.ML"}.
       
  1103   \end{readmore}
  1071   \end{readmore}
  1104 
  1072 
  1105   Storing data in a proof context is done in a similar fashion. The
  1073   Storing data in a proof context is done in a similar fashion. The
  1106   corresponding functor is @{ML_funct_ind ProofDataFun}. With the 
  1074   corresponding functor is @{ML_funct_ind ProofDataFun}. With the 
  1107   following code we can store a list of terms in a proof context. 
  1075   following code we can store a list of terms in a proof context. 
  1153   Isabelle code, although the ``context flow'' is usually only linear.
  1121   Isabelle code, although the ``context flow'' is usually only linear.
  1154   Note also that the calculation above has no effect on the underlying
  1122   Note also that the calculation above has no effect on the underlying
  1155   theory. Once we throw away the contexts, we have no access to their
  1123   theory. Once we throw away the contexts, we have no access to their
  1156   associated data. This is different to theories, where the command 
  1124   associated data. This is different to theories, where the command 
  1157   \isacommand{setup} registers the data with the current and future 
  1125   \isacommand{setup} registers the data with the current and future 
  1158   theories, and therefore can access the data potentially indefinitely. 
  1126   theories, and therefore can access the data potentially 
  1159 *}
  1127   indefinitely.\footnote{\bf FIXME: check this; it seems that is in
  1160 
  1128   conflict with the statements below.} 
       
  1129 
       
  1130   \footnote{\bf FIXME: Say something about generic contexts.}
       
  1131 
       
  1132   There are two special instances of the data storage mechanism described 
       
  1133   above. The first instance are named theorem lists. Since storing theorems in a list 
       
  1134   is such a common task, there is the special functor @{ML_funct_ind Named_Thms}. 
       
  1135   To obtain a named theorem list, you just declare
       
  1136 *}
       
  1137 
       
  1138 ML{*structure FooRules = Named_Thms
       
  1139   (val name = "foo" 
       
  1140    val description = "Theorems for foo") *}
       
  1141 
       
  1142 text {*
       
  1143   and set up the @{ML_struct FooRules} with the command
       
  1144 *}
       
  1145 
       
  1146 setup %gray {* FooRules.setup *}
       
  1147 
       
  1148 text {*
       
  1149   This code declares a data container where the theorems are stored,
       
  1150   an attribute @{text foo} (with the @{text add} and @{text del} options
       
  1151   for adding and deleting theorems) and an internal ML-interface to retrieve and 
       
  1152   modify the theorems.
       
  1153 
       
  1154   Furthermore, the facts are made available on the user-level under the dynamic 
       
  1155   fact name @{text foo}. For example you can declare three lemmas to be of the kind
       
  1156   @{text foo} by:
       
  1157 *}
       
  1158 
       
  1159 lemma rule1[foo]: "A" sorry
       
  1160 lemma rule2[foo]: "B" sorry
       
  1161 lemma rule3[foo]: "C" sorry
       
  1162 
       
  1163 text {* and undeclare the first one by: *}
       
  1164 
       
  1165 declare rule1[foo del]
       
  1166 
       
  1167 text {* and query the remaining ones with:
       
  1168 
       
  1169   \begin{isabelle}
       
  1170   \isacommand{thm}~@{text "foo"}\\
       
  1171   @{text "> ?C"}\\
       
  1172   @{text "> ?B"}
       
  1173   \end{isabelle}
       
  1174 
       
  1175   On the ML-level, we can add theorems to the list with @{ML FooRules.add_thm}:
       
  1176 *} 
       
  1177 
       
  1178 setup %gray {* 
       
  1179   Context.theory_map (FooRules.add_thm @{thm TrueI}) 
       
  1180 *}
       
  1181 
       
  1182 text {*
       
  1183   The rules in the list can be retrieved using the function 
       
  1184   @{ML FooRules.get}:
       
  1185 
       
  1186   @{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"True\", \"?C\",\"?B\"]"}
       
  1187 
       
  1188   \begin{readmore}
       
  1189   For more information see @{ML_file "Pure/Tools/named_thms.ML"}.
       
  1190   \end{readmore}
       
  1191 
       
  1192   The second special instance of the data storage mechanism are configuration
       
  1193   values. They are used to enable users to configure tools without having to
       
  1194   resort to the ML-level (and also to avoid references). Assume you want the
       
  1195   user to control three values, say @{text bval} containing a boolean, @{text
       
  1196   ival} containing an integer and @{text sval} containing a string. These
       
  1197   values can be declared by
       
  1198 *}
       
  1199 
       
  1200 ML{*val (bval, setup_bval) = Attrib.config_bool "bval" false
       
  1201 val (ival, setup_ival) = Attrib.config_int "ival" 0
       
  1202 val (sval, setup_sval) = Attrib.config_string "sval" "some string" *}
       
  1203 
       
  1204 text {* 
       
  1205   where each value needs to be given a default. To enable these values, they need to 
       
  1206   be set up with
       
  1207 *}
       
  1208 
       
  1209 setup %gray {* 
       
  1210   setup_bval #> 
       
  1211   setup_ival 
       
  1212 *}
       
  1213 
       
  1214 text {*
       
  1215   The user can now manipulate the values from the user-level of Isabelle 
       
  1216   with the command
       
  1217 *}
       
  1218 
       
  1219 declare [[bval = true, ival = 3]]
       
  1220 
       
  1221 text {*
       
  1222   On the ML-level these values can be retrieved using the 
       
  1223   function @{ML Config.get}.
       
  1224 
       
  1225   @{ML_response [display,gray] "Config.get @{context} bval" "true"}
       
  1226 
       
  1227   \begin{readmore}
       
  1228   For more information about configuration values see 
       
  1229   @{ML_file "Pure/Isar/attrib.ML"} and @{ML_file "Pure/config.ML"}.
       
  1230   \end{readmore}
       
  1231 *}
  1161 
  1232 
  1162 
  1233 
  1163 (**************************************************)
  1234 (**************************************************)
  1164 (* bak                                            *)
  1235 (* bak                                            *)
  1165 (**************************************************)
  1236 (**************************************************)