CookBook/FirstSteps.thy
changeset 151 7e0bf13bf743
parent 149 253ea99c1441
child 153 c22b507e1407
equal deleted inserted replaced
150:cb39c41548bd 151:7e0bf13bf743
   892   "[symmetric]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
   892   "[symmetric]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags
   893   annotated to theorems, but functions that do further processing once a
   893   annotated to theorems, but functions that do further processing once a
   894   theorem is proven. In particular, it is not possible to find out
   894   theorem is proven. In particular, it is not possible to find out
   895   what are all theorems that have a given attribute in common, unless of course
   895   what are all theorems that have a given attribute in common, unless of course
   896   the function behind the attribute stores the theorems in a retrivable 
   896   the function behind the attribute stores the theorems in a retrivable 
   897   datastructure. This can be easily done by the recipe described in 
   897   datastructure. 
   898   \ref{rec:named}. 
       
   899 
   898 
   900   If you want to print out all currently known attributes a theorem 
   899   If you want to print out all currently known attributes a theorem 
   901   can have, you can use the function:
   900   can have, you can use the function:
   902 
   901 
   903   @{ML_response_fake [display,gray] "Attrib.print_attributes @{theory}" 
   902   @{ML_response_fake [display,gray] "Attrib.print_attributes @{theory}" 
   925   using the function @{ML Attrib.add_attributes} as follows.
   924   using the function @{ML Attrib.add_attributes} as follows.
   926 *}
   925 *}
   927 
   926 
   928 setup {*
   927 setup {*
   929   Attrib.add_attributes 
   928   Attrib.add_attributes 
   930     [("my_sym", Attrib.no_args my_symmetric, "applying the sym rule")]
   929     [("my_sym", Attrib.no_args my_symmetric, "applying the sym rule")] *}
   931 *}
       
   932 
   930 
   933 text {*
   931 text {*
   934   The attribute does not expect any further arguments (unlike @{text "[OF
   932   The attribute does not expect any further arguments (unlike @{text "[OF
   935   \<dots>]"}, for example, which can take a list of theorems as argument). Therefore
   933   \<dots>]"}, for example, which can take a list of theorems as argument). Therefore
   936   we use the function @{ML Attrib.no_args}. Later on we will also consider
   934   we use the function @{ML Attrib.no_args}. Later on we will also consider
   947   \begin{isabelle}
   945   \begin{isabelle}
   948   \isacommand{thm}~@{text "test[my_sym]"}\\
   946   \isacommand{thm}~@{text "test[my_sym]"}\\
   949   @{text "> "}~@{thm test[my_sym]}
   947   @{text "> "}~@{thm test[my_sym]}
   950   \end{isabelle}
   948   \end{isabelle}
   951 
   949 
   952 *}
   950   The purpose of @{ML Thm.rule_attribute} is to directly manipulate theorems.
   953 
   951   Another usage of attributes is to add and delete theorems from stored data.
   954 text {*
   952   For example the attribute @{text "[simp]"} adds or deletes a theorem from the
   955 What are: 
   953   current simpset. For these applications, you can use @{ML Thm.declaration_attribute}. 
   956 
   954   To illustrate this function, let us introduce a reference containing a list
   957 
   955   of theorems.
   958 @{text "declaration_attribute"}
   956 *}
   959 
   957 
   960 @{text "theory_attributes"}
   958 ML{*val my_thms = ref ([]:thm list)*}
   961 
   959 
   962 @{text "proof_attributes"}
   960 text {* 
       
   961   A word of warning: such references must not be used in any code that
       
   962   is meant to be more than just for testing purposes! Here it is only used 
       
   963   to illustrate matters. We will show later how to store data properly without 
       
   964   using references. The function @{ML Thm.declaration_attribute} expects us to 
       
   965   provide two functions that add and delete theorems from this list. At
       
   966   the moment we use the two functions:
       
   967 *}
       
   968 
       
   969 ML{*fun my_thms_add thm ctxt =
       
   970   (my_thms := Thm.add_thm thm (!my_thms); ctxt)
       
   971 
       
   972 fun my_thms_del thm ctxt =
       
   973   (my_thms := Thm.del_thm thm (!my_thms); ctxt)*}
       
   974 
       
   975 text {*
       
   976   These functions take a theorem and a context and, for what we are explaining
       
   977   here it is sufficient to just return the context unchanged. They change
       
   978   however the reference @{ML my_thms}, whereby the function @{ML Thm.add_thm}
       
   979   adds a theorem if it is not already included in the list, and @{ML
       
   980   Thm.del_thm} deletes one. Both functions use the predicate @{ML
       
   981   Thm.eq_thm_prop} which compares theorems according to their proved
       
   982   propositions (modulo alpha-equivalence).
       
   983 
       
   984 
       
   985   We can turn both functions into attributes using
       
   986 *}
       
   987 
       
   988 ML{*val my_add = Thm.declaration_attribute my_thms_add
       
   989 val my_del = Thm.declaration_attribute my_thms_del *}
       
   990 
       
   991 text {* 
       
   992   and set up the attributes as follows
       
   993 *}
       
   994 
       
   995 setup {*
       
   996   Attrib.add_attributes 
       
   997     [("my_thms", Attrib.add_del_args my_add my_del, 
       
   998         "maintaining a list of my_thms")] *}
       
   999 
       
  1000 text {*
       
  1001   Now if you prove the lemma attaching the attribute @{text "[my_thms]"}
       
  1002 *}
       
  1003 
       
  1004 lemma trueI_2[my_thms]: "True" by simp
       
  1005 
       
  1006 text {*
       
  1007   then you can see the lemma is added to the initially empty list.
       
  1008 
       
  1009   @{ML_response_fake [display,gray]
       
  1010   "!my_thms" "[\"True\"]"}
       
  1011 
       
  1012   We can also add theorems using the command \isacommand{declare}
       
  1013 *}
       
  1014 
       
  1015 declare test[my_thms] trueI_2[my_thms add]
       
  1016 
       
  1017 text {*
       
  1018   The @{text "add"} is the default operation and does not need
       
  1019   to be given. This declaration will cause the theorem list to be 
       
  1020   updated as follows.
       
  1021 
       
  1022   @{ML_response_fake [display,gray]
       
  1023   "!my_thms"
       
  1024   "[\"True\", \"Suc (Suc 0) = 2\"]"}
       
  1025 
       
  1026   The theorem @{thm [source] trueI_2} only appears once, since the 
       
  1027   function @{ML Thm.add_thm} tests for duplicates, before extending
       
  1028   the list. Deletion from the list works as follows:
       
  1029 *}
       
  1030 
       
  1031 declare test[my_thms del]
       
  1032 
       
  1033 text {* After this, the theorem list is: 
       
  1034 
       
  1035   @{ML_response_fake [display,gray]
       
  1036   "!my_thms"
       
  1037   "[\"True\"]"}
       
  1038 
       
  1039   We used in this example two functions declared as @{ML Thm.declaration_attribute}, 
       
  1040   but there can be any number of them. We just have to change the parser for reading
       
  1041   the arguments accordingly. 
       
  1042 
       
  1043   However, as said at the beginning using references for storing theorems is
       
  1044   \emph{not} the received way of doing such things. The received way is to 
       
  1045   start a ``data slot'' in a context by using the functor @{text GenericDataFun}:
       
  1046 *}
       
  1047 
       
  1048 ML {*structure Data = GenericDataFun
       
  1049  (type T = thm list
       
  1050   val empty = []
       
  1051   val extend = I
       
  1052   fun merge _ = Thm.merge_thms) *}
       
  1053 
       
  1054 text {*
       
  1055   To use this data slot, we only have to change the functions @{ML my_thms_add} and
       
  1056   @{ML my_thms_del} to:
       
  1057 *}
       
  1058 
       
  1059 ML{*val thm_add = Data.map o Thm.add_thm
       
  1060 val thm_del = Data.map o Thm.del_thm*}
       
  1061 
       
  1062 text {*
       
  1063   where @{ML Data.map} updates the data appropriately in the context. Since storing
       
  1064   theorems in a special list is such a common task, there is the functor @{text NamedThmsFun},
       
  1065   which does most of the work for you. To obtain such a named theorem lists, you just
       
  1066   declare 
       
  1067 *}
       
  1068 
       
  1069 ML{*structure FooRules = NamedThmsFun 
       
  1070  (val name = "foo" 
       
  1071   val description = "Rules for foo"); *}
       
  1072 
       
  1073 text {*
       
  1074   and set up the @{ML_struct FooRules} with the command
       
  1075 *}
       
  1076 
       
  1077 setup {* FooRules.setup *}
       
  1078 
       
  1079 text {*
       
  1080   This code declares a data slot where the theorems are stored,
       
  1081   an attribute @{text foo} (with the @{text add} and @{text del} options
       
  1082   for adding and deleting theorems) and an internal ML interface to retrieve and 
       
  1083   modify the theorems.
       
  1084 
       
  1085   Furthermore, the facts are made available on the user level under the dynamic 
       
  1086   fact name @{text foo}. For example we can declare three lemmas to be of the kind
       
  1087   @{text foo} by:
       
  1088 *}
       
  1089 
       
  1090 lemma rule1[foo]: "A" sorry
       
  1091 lemma rule2[foo]: "B" sorry
       
  1092 lemma rule3[foo]: "C" sorry
       
  1093 
       
  1094 text {* and undeclare the first one by: *}
       
  1095 
       
  1096 declare rule1[foo del]
       
  1097 
       
  1098 text {* and query the remaining ones with:
       
  1099 
       
  1100   \begin{isabelle}
       
  1101   \isacommand{thm}~@{text "foo"}\\
       
  1102   @{text "> ?C"}\\
       
  1103   @{text "> ?B"}
       
  1104   \end{isabelle}
       
  1105 
       
  1106   On the ML-level the rules marked with @{text "foo"} an be retrieved
       
  1107   using the function @{ML FooRules.get}:
       
  1108 
       
  1109   @{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"?C\",\"?B\"]"}
       
  1110 
       
  1111   \begin{readmore}
       
  1112   For more information see @{ML_file "Pure/Tools/named_thms.ML"} and also
       
  1113   the recipe in Section~\ref{recipe:storingdata} about storing arbitrary
       
  1114   data.
       
  1115   \end{readmore}
       
  1116 
       
  1117   What are: 
       
  1118 
       
  1119   @{text "theory_attributes"}
       
  1120   @{text "proof_attributes"}
   963 
  1121 
   964 
  1122 
   965   \begin{readmore}
  1123   \begin{readmore}
   966   FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"}
  1124   FIXME: @{ML_file "Pure/more_thm.ML"} @{ML_file "Pure/Isar/attrib.ML"}
   967   \end{readmore}
  1125   \end{readmore}
   968 
  1126 *}
   969 
  1127 
   970 *}
  1128 
   971 
  1129 section {* Theories, Contexts and Local Theories *}
   972 
       
   973 section {* Theories and Local Theories *}
       
   974 
  1130 
   975 text {*
  1131 text {*
   976   (FIXME: expand)
  1132   (FIXME: expand)
   977 
  1133 
   978   (FIXME: explain \isacommand{setup})
  1134   (FIXME: explain \isacommand{setup})