CookBook/FirstSteps.thy
changeset 178 fb8f22dd8ad0
parent 177 4e2341f6599d
child 183 8bb4eaa2ec92
equal deleted inserted replaced
177:4e2341f6599d 178:fb8f22dd8ad0
   246 text {* 
   246 text {* 
   247   Another reason why the let-bindings in the code above are better to be
   247   Another reason why the let-bindings in the code above are better to be
   248   avoided: it is more than easy to get the intermediate values wrong, not to 
   248   avoided: it is more than easy to get the intermediate values wrong, not to 
   249   mention the nightmares the maintenance of this code causes!
   249   mention the nightmares the maintenance of this code causes!
   250 
   250 
   251   A ``real world'' example for a function written in the waterfall fashion might
   251   In the context of Isabelle, a ``real world'' example for a function written in 
   252   be the following:
   252   the waterfall fashion might be the following code:
   253 *}
   253 *}
   254 
   254 
   255 ML %linenosgray{*fun apply_fresh_args pred ctxt =
   255 ML %linenosgray{*fun apply_fresh_args pred ctxt =
   256   pred |> fastype_of
   256   pred |> fastype_of
   257        |> binder_types 
   257        |> binder_types 
   259        |> Variable.variant_frees ctxt [pred]
   259        |> Variable.variant_frees ctxt [pred]
   260        |> map Free  
   260        |> map Free  
   261        |> (curry list_comb) pred *}
   261        |> (curry list_comb) pred *}
   262 
   262 
   263 text {*
   263 text {*
   264   The point of this function is to extract the argument types of the given
   264   The point of this code is to extract the argument types of the given
   265   predicate and then generate for each type a distinct variable; finally it
   265   predicate and then generate for each type a distinct variable; finally it
   266   applies the generated variables to the predicate. You can read this off from
   266   applies the generated variables to the predicate. You can read this off from
   267   how the function is coded: in Line 2, the function @{ML fastype_of}
   267   how the function is coded: in Line 2, the function @{ML fastype_of}
   268   calculates the type of the predicate; in Line 3, @{ML binder_types} produces
   268   calculates the type of the predicate; in Line 3, @{ML binder_types} produces
   269   the list of argument types; Line 4 pairs up each type with the string/name
   269   the list of argument types; Line 4 pairs up each type with the string (or name)
   270   @{text "z"}; the function @{ML variant_frees in Variable} generates for each
   270   @{text "z"}; the function @{ML variant_frees in Variable} generates for each
   271   @{text "z"} a unique name avoiding @{text pred}; the list of name-type pairs
   271   @{text "z"} a unique name avoiding @{text pred}; the list of name-type pairs
   272   is turned into a list of variable terms in Line 6, which in the last line
   272   is turned into a list of variable terms in Line 6, which in the last line
   273   are applied by the function @{ML list_comb} to the predicate. We have to use
   273   are applied by the function @{ML list_comb} to the predicate. We have to use
   274   the function @{ML curry}, because @{ML list_comb} expects the predicate and
   274   the function @{ML curry}, because @{ML list_comb} expects the predicate and
   780 in
   780 in
   781   cterm_of @{theory} 
   781   cterm_of @{theory} 
   782       (Const (@{const_name plus}, natT --> natT --> natT) $ zero $ zero)
   782       (Const (@{const_name plus}, natT --> natT --> natT) $ zero $ zero)
   783 end" "0 + 0"}
   783 end" "0 + 0"}
   784 
   784 
   785   In Isabelle also types need can be certified. For example, you obtain
   785   In Isabelle not just types need to be certified, but also types. For example, 
   786   the certified type for the Isablle type @{typ "nat \<Rightarrow> bool"} on the ML-level
   786   you obtain the certified type for the Isablle type @{typ "nat \<Rightarrow> bool"} on 
   787   as follows:
   787   the ML-level as follows:
   788 
   788 
   789   @{ML_response_fake [display,gray]
   789   @{ML_response_fake [display,gray]
   790   "ctyp_of @{theory} (@{typ nat} --> @{typ bool})"
   790   "ctyp_of @{theory} (@{typ nat} --> @{typ bool})"
   791   "nat \<Rightarrow> bool"}
   791   "nat \<Rightarrow> bool"}
   792 
   792 
   798   \begin{exercise}
   798   \begin{exercise}
   799   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   799   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   800   result that type-checks.
   800   result that type-checks.
   801   \end{exercise}
   801   \end{exercise}
   802 
   802 
   803   Remember that in Isabelle a term contains enough typing information
   803   Remember Isabelle foolows the Church-style typing for terms, i.e.~a term contains 
   804   (constants, free variables and abstractions all have typing 
   804   enough typing information (constants, free variables and abstractions all have typing 
   805   information) so that it is always clear what the type of a term is. 
   805   information) so that it is always clear what the type of a term is. 
   806   Given a well-typed term, the function @{ML type_of} returns the 
   806   Given a well-typed term, the function @{ML type_of} returns the 
   807   type of a term. Consider for example:
   807   type of a term. Consider for example:
   808 
   808 
   809   @{ML_response [display,gray] 
   809   @{ML_response [display,gray] 
   963   returns another theorem (namely @{text thm} resolved with the lemma 
   963   returns another theorem (namely @{text thm} resolved with the lemma 
   964   @{thm [source] sym}: @{thm sym[no_vars]}). The function @{ML "Thm.rule_attribute"} then returns 
   964   @{thm [source] sym}: @{thm sym[no_vars]}). The function @{ML "Thm.rule_attribute"} then returns 
   965   an attribute.
   965   an attribute.
   966 
   966 
   967   Before we can use the attribute, we need to set it up. This can be done
   967   Before we can use the attribute, we need to set it up. This can be done
   968   using the function @{ML Attrib.add_attributes} as follows.
   968   using the function @{ML Attrib.setup} as follows.
   969 *}
   969 *}
   970 
   970 
   971 setup %gray {* Attrib.add_attributes 
   971 setup %gray {* Attrib.setup @{binding "my_sym"} 
   972     [("my_sym", Attrib.no_args my_symmetric, "applying the sym rule")] *}
   972   (Scan.succeed my_symmetric) "applying the sym rule"*}
   973 
   973 
   974 text {*
   974 text {*
   975   The attribute does not expect any further arguments (unlike @{text "[OF
   975   The attribute does not expect any further arguments (unlike @{text "[OF
   976   \<dots>]"}, for example, which can take a list of theorems as argument). Therefore
   976   \<dots>]"}, for example, which can take a list of theorems as argument). Therefore
   977   we use the function @{ML Attrib.no_args}. Later on we will also consider
   977   we use the parser @{ML Scan.succeed}. Later on we will also consider
   978   attributes taking further arguments. An example for the attribute @{text
   978   attributes taking further arguments. An example for the attribute @{text
   979   "[my_sym]"} is the proof
   979   "[my_sym]"} is the proof
   980 *} 
   980 *} 
   981 
   981 
   982 lemma test[my_sym]: "2 = Suc (Suc 0)" by simp
   982 lemma test[my_sym]: "2 = Suc (Suc 0)" by simp
  1033 
  1033 
  1034 text {* 
  1034 text {* 
  1035   and set up the attributes as follows
  1035   and set up the attributes as follows
  1036 *}
  1036 *}
  1037 
  1037 
  1038 setup %gray {* Attrib.add_attributes 
  1038 setup %gray {* Attrib.setup @{binding "my_thms"}
  1039           [("my_thms", Attrib.add_del_args my_add my_del, 
  1039   (Attrib.add_del my_add my_del) "maintaining a list of my_thms" *}
  1040               "maintaining a list of my_thms")] *}
       
  1041 
  1040 
  1042 text {*
  1041 text {*
  1043   Now if you prove the lemma attaching the attribute @{text "[my_thms]"}
  1042   Now if you prove the lemma attaching the attribute @{text "[my_thms]"}
  1044 *}
  1043 *}
  1045 
  1044 
  1163   FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"}
  1162   FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"}
  1164   \end{readmore}
  1163   \end{readmore}
  1165 *}
  1164 *}
  1166 
  1165 
  1167 
  1166 
       
  1167 section {* Setups (TBD) *}
       
  1168 
       
  1169 text {*
       
  1170   In the previous section we used \isacommand{setup} in order to make
       
  1171   a theorem attribute known to Isabelle. What happens behind the scenes
       
  1172   is that \isacommand{setup} expects a functions from @{ML_type theory}
       
  1173   to @{ML_type theory}: the input theory is the current theory and the 
       
  1174   output the theory where the theory attribute has been stored.
       
  1175   
       
  1176   This is a fundamental principle in Isabelle. A similar situation occurs 
       
  1177   for example with declaring constants. The function that declares a 
       
  1178   constant on the ML-level is @{ML Sign.add_consts_i}. Recall that ML-code 
       
  1179   needs to be \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"}.
       
  1180   If you write 
       
  1181 *}  
       
  1182 
       
  1183 ML{*Sign.add_consts_i [(Binding.name "BAR", @{typ "nat"}, NoSyn)] @{theory} *}
       
  1184 
       
  1185 text {*
       
  1186   for declaring the constant @{text "BAR"} with type @{typ nat} and 
       
  1187   run the code, then you indeed obtain a theory as result. But if you 
       
  1188   query the constant with \isacommand{term}
       
  1189 
       
  1190   \begin{isabelle}
       
  1191   \isacommand{term}~@{text [quotes] "BAR"}\\
       
  1192   @{text "> \"BAR\" :: \"'a\""}
       
  1193   \end{isabelle}
       
  1194 
       
  1195   you do not obtain a constant of type @{typ nat}, but a free variable (printed in 
       
  1196   blue) of polymorphic type. The problem is that the ML-expression above did 
       
  1197   not register the declaration with the current theory. This is what the command
       
  1198   \isacommand{setup} is for. The constant is properly declared with
       
  1199 *}
       
  1200 
       
  1201 setup %gray {* Sign.add_consts_i [(Binding.name "BAR", @{typ "nat"}, NoSyn)] *}
       
  1202 
       
  1203 text {* 
       
  1204   Now 
       
  1205   
       
  1206   \begin{isabelle}
       
  1207   \isacommand{term}~@{text [quotes] "BAR"}\\
       
  1208   @{text "> \"BAR\" :: \"nat\""}
       
  1209   \end{isabelle}
       
  1210 
       
  1211   returns a (black) constant with the type @{typ nat}.
       
  1212 
       
  1213   A similar command is \isacommand{local\_setup}, which expects a function
       
  1214   of type @{ML_type "local_theory -> local_theory"}. Later on we will also
       
  1215   use the commands \isacommand{method\_setup} for installing methods in the
       
  1216   current theory and \isacommand{simproc\_setup} for adding new simprocs to
       
  1217   the current simpset.
       
  1218 *}
       
  1219 
  1168 section {* Theories, Contexts and Local Theories (TBD) *}
  1220 section {* Theories, Contexts and Local Theories (TBD) *}
  1169 
  1221 
  1170 text {*
  1222 text {*
  1171   (FIXME: expand)
       
  1172 
       
  1173   (FIXME: explain \isacommand{setup})
       
  1174 
       
  1175   There are theories, proof contexts and local theories (in this order, if you
  1223   There are theories, proof contexts and local theories (in this order, if you
  1176   want to order them). 
  1224   want to order them). 
  1177 
  1225 
  1178   In contrast to an ordinary theory, which simply consists of a type
  1226   In contrast to an ordinary theory, which simply consists of a type
  1179   signature, as well as tables for constants, axioms and theorems, a local
  1227   signature, as well as tables for constants, axioms and theorems, a local
  1180   theory also contains additional context information, such as locally fixed
  1228   theory also contains additional context information, such as locally fixed
  1181   variables and local assumptions that may be used by the package. The type
  1229   variables and local assumptions that may be used by the package. The type
  1182   @{ML_type local_theory} is identical to the type of \emph{proof contexts}
  1230   @{ML_type local_theory} is identical to the type of \emph{proof contexts}
  1183   @{ML_type "Proof.context"}, although not every proof context constitutes a
  1231   @{ML_type "Proof.context"}, although not every proof context constitutes a
  1184   valid local theory.
  1232   valid local theory.
  1185 
  1233 *}
  1186  *}
       
  1187 
       
  1188 
       
  1189 
  1234 
  1190 section {* Storing Theorems\label{sec:storing} (TBD) *}
  1235 section {* Storing Theorems\label{sec:storing} (TBD) *}
  1191 
  1236 
  1192 text {* @{ML PureThy.add_thms_dynamic} *}
  1237 text {* @{ML PureThy.add_thms_dynamic} *}
  1193 
  1238