ProgTutorial/General.thy
changeset 329 5dffcab68680
parent 328 c0cae24b9d46
child 335 163ac0662211
equal deleted inserted replaced
328:c0cae24b9d46 329:5dffcab68680
     5 chapter {* Isabelle -- The Good, the Bad and the Ugly *}
     5 chapter {* Isabelle -- The Good, the Bad and the Ugly *}
     6 
     6 
     7 text {*
     7 text {*
     8   Isabelle is build around a few central ideas. One is the LCF-approach to
     8   Isabelle is build around a few central ideas. One is the LCF-approach to
     9   theorem proving where there is a small trusted core and everything else is
     9   theorem proving where there is a small trusted core and everything else is
    10   build on top of this trusted core.
    10   build on top of this trusted core. The central data structures involved
       
    11   in this core are certified terms and types as well as theorems.
    11 
    12 
    12 *}
    13 *}
    13 
    14 
    14 
    15 
    15 section {* Terms and Types *}
    16 section {* Terms and Types *}
    16 
    17 
    17 text {*
    18 text {*
    18   One way to construct Isabelle terms, is by using the antiquotation 
    19   In Isabelle there are certified terms (respectively types) and uncertified
    19   \mbox{@{text "@{term \<dots>}"}}. For example
    20   terms. The latter are called just terms. One way to construct them is by 
       
    21   using the antiquotation \mbox{@{text "@{term \<dots>}"}}. For example
    20 
    22 
    21   @{ML_response [display,gray] 
    23   @{ML_response [display,gray] 
    22 "@{term \"(a::nat) + b = c\"}" 
    24 "@{term \"(a::nat) + b = c\"}" 
    23 "Const (\"op =\", \<dots>) $ 
    25 "Const (\"op =\", \<dots>) $ 
    24   (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
    26   (Const (\"HOL.plus_class.plus\", \<dots>) $ \<dots> $ \<dots>) $ \<dots>"}
   444   For example
   446   For example
   445 
   447 
   446   @{ML_response [display,gray]
   448   @{ML_response [display,gray]
   447   "@{type_name \"list\"}" "\"List.list\""}
   449   "@{type_name \"list\"}" "\"List.list\""}
   448 
   450 
   449   (FIXME: Explain the following better.)
   451   \footnote{\bf FIXME: Explain the following better; maybe put in a separate
       
   452   section and link with the comment in the antiquotation section.}
   450 
   453 
   451   Occasionally you have to calculate what the ``base'' name of a given
   454   Occasionally you have to calculate what the ``base'' name of a given
   452   constant is. For this you can use the function @{ML_ind  "Sign.extern_const"} or
   455   constant is. For this you can use the function @{ML_ind  "Sign.extern_const"} or
   453   @{ML_ind  Long_Name.base_name}. For example:
   456   @{ML_ind  Long_Name.base_name}. For example:
   454 
   457 
   535   Write a function which takes two terms representing natural numbers
   538   Write a function which takes two terms representing natural numbers
   536   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
   539   in unary notation (like @{term "Suc (Suc (Suc 0))"}), and produces the
   537   number representing their sum.
   540   number representing their sum.
   538   \end{exercise}
   541   \end{exercise}
   539 
   542 
   540   \begin{exercise}\footnote{Personal communication of
   543   \begin{exercise}\label{ex:debruijn}
   541   de Bruijn to Dyckhoff.}\label{ex:debruijn}
   544   Implement the function, which we below name deBruijn\footnote{According to 
   542   Implement the function, which we below name deBruijn, that depends on a natural
   545   personal communication of de Bruijn to Dyckhoff.}, that depends on a natural
   543   number n$>$0 and constructs terms of the form:
   546   number n$>$0 and constructs terms of the form:
   544   
   547   
   545   \begin{center}
   548   \begin{center}
   546   \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
   549   \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l}
   547   {\it rhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n.  P\,i}\\
   550   {\it rhs n} & $\dn$ & {\large$\bigwedge$}{\it i=1\ldots n.  P\,i}\\
   549                         $\longrightarrow$ {\it rhs n}\\
   552                         $\longrightarrow$ {\it rhs n}\\
   550   {\it deBruijn n} & $\dn$ & {\it lhs n} $\longrightarrow$ {\it rhs n}\\
   553   {\it deBruijn n} & $\dn$ & {\it lhs n} $\longrightarrow$ {\it rhs n}\\
   551   \end{tabular}
   554   \end{tabular}
   552   \end{center}
   555   \end{center}
   553 
   556 
   554   For n=3 this function returns the term
   557   This function returns for n=3 the term
   555 
   558 
   556   \begin{center}
   559   \begin{center}
   557   \begin{tabular}{l}
   560   \begin{tabular}{l}
   558   (P 1 = P 2 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\
   561   (P 1 = P 2 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\
   559   (P 2 = P 3 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\ 
   562   (P 2 = P 3 $\longrightarrow$ P 1 $\wedge$ P 2 $\wedge$ P 3) $\wedge$\\ 
   683   checking and pretty-printing of terms are defined. Functions related to
   686   checking and pretty-printing of terms are defined. Functions related to
   684   type-inference are implemented in @{ML_file "Pure/type.ML"} and 
   687   type-inference are implemented in @{ML_file "Pure/type.ML"} and 
   685   @{ML_file "Pure/type_infer.ML"}. 
   688   @{ML_file "Pure/type_infer.ML"}. 
   686   \end{readmore}
   689   \end{readmore}
   687 
   690 
   688   (FIXME: say something about sorts)
   691   \footnote{\bf FIXME: say something about sorts.}
   689 
   692 
   690   \begin{exercise}
   693   \begin{exercise}
   691   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   694   Check that the function defined in Exercise~\ref{fun:revsum} returns a
   692   result that type-checks. See what happens to the  solutions of this 
   695   result that type-checks. See what happens to the  solutions of this 
   693   exercise given in \ref{ch:solutions} when they receive an ill-typed term
   696   exercise given in Appendix \ref{ch:solutions} when they receive an 
   694   as input.
   697   ill-typed term as input.
   695   \end{exercise}
   698   \end{exercise}
   696 *}
   699 *}
   697 
   700 
   698 
   701 
   699 section {* Theorems *}
   702 section {* Theorems *}
   980   @{text "> "}~@{thm test[my_sym, MY_THEN eq_reflection]}
   983   @{text "> "}~@{thm test[my_sym, MY_THEN eq_reflection]}
   981   \end{isabelle}
   984   \end{isabelle}
   982   
   985   
   983   However, here also a weakness of the concept
   986   However, here also a weakness of the concept
   984   of theorem attributes shows through: since theorem attributes can be
   987   of theorem attributes shows through: since theorem attributes can be
   985   arbitrary functions, they do not in general commute. If you try
   988   arbitrary functions, they do not commute in general. If you try
   986 
   989 
   987   \begin{isabelle}
   990   \begin{isabelle}
   988   \isacommand{thm}~@{text "test[MY_THEN eq_reflection, my_sym]"}\\
   991   \isacommand{thm}~@{text "test[MY_THEN eq_reflection, my_sym]"}\\
   989   @{text "> "}~@{text "exception THM 1 raised: RSN: no unifiers"}
   992   @{text "> "}~@{text "exception THM 1 raised: RSN: no unifiers"}
   990   \end{isabelle}
   993   \end{isabelle}
   991 
   994 
   992   you get an exception indicating that the theorem @{thm [source] sym}
   995   you get an exception indicating that the theorem @{thm [source] sym}
   993   does not resolve with meta-equations. 
   996   does not resolve with meta-equations. 
   994 
   997 
   995   The purpose of @{ML_ind  rule_attribute in Thm} is to directly manipulate theorems.
   998   The purpose of @{ML_ind rule_attribute in Thm} is to directly manipulate
   996   Another usage of theorem attributes is to add and delete theorems from stored data.
   999   theorems.  Another usage of theorem attributes is to add and delete theorems
   997   For example the theorem attribute @{text "[simp]"} adds or deletes a theorem from the
  1000   from stored data.  For example the theorem attribute @{text "[simp]"} adds
   998   current simpset. For these applications, you can use @{ML_ind  declaration_attribute in Thm}. 
  1001   or deletes a theorem from the current simpset. For these applications, you
   999   To illustrate this function, let us introduce a reference containing a list
  1002   can use @{ML_ind declaration_attribute in Thm}. To illustrate this function,
  1000   of theorems.
  1003   let us introduce a theorem list.
  1001 *}
  1004 *}
  1002 
  1005 
  1003 ML{*val my_thms = Unsynchronized.ref ([] : thm list)*}
  1006 ML{*structure MyThms = Named_Thms
       
  1007   (val name = "attr_thms" 
       
  1008    val description = "Theorems for an Attribute") *}
  1004 
  1009 
  1005 text {* 
  1010 text {* 
  1006   The purpose of this reference is to store a list of theorems.
  1011   We are going to modify this list by adding and deleting theorems.
  1007   We are going to modify it by adding and deleting theorems.
  1012   For this we use the two functions @{ML MyThms.add_thm} and
  1008   However, a word of warning: such references must not 
  1013   @{ML MyThms.del_thm}. You can turn them into attributes 
  1009   be used in any code that is meant to be more than just for testing purposes! 
  1014   with the code
  1010   Here it is only used to illustrate matters. We will show later how to store 
  1015 *}
  1011   data properly without using references.
  1016 
  1012  
  1017 ML{*val my_add = Thm.declaration_attribute MyThms.add_thm
  1013   We need to provide two functions that add and delete theorems from this list. 
  1018 val my_del = Thm.declaration_attribute MyThms.del_thm *}
  1014   For this we use the two functions:
       
  1015 *}
       
  1016 
       
  1017 ML{*fun my_thm_add thm ctxt =
       
  1018   (my_thms := Thm.add_thm thm (!my_thms); ctxt)
       
  1019 
       
  1020 fun my_thm_del thm ctxt =
       
  1021   (my_thms := Thm.del_thm thm (!my_thms); ctxt)*}
       
  1022 
       
  1023 text {*
       
  1024   These functions take a theorem and a context and, for what we are explaining
       
  1025   here it is sufficient that they just return the context unchanged. They change
       
  1026   however the reference @{ML my_thms}, whereby the function 
       
  1027   @{ML_ind  add_thm in Thm} adds a theorem if it is not already included in 
       
  1028   the list, and @{ML_ind  del_thm in Thm} deletes one (both functions use the 
       
  1029   predicate @{ML_ind  eq_thm_prop in Thm}, which compares theorems according to 
       
  1030   their proved propositions modulo alpha-equivalence).
       
  1031 
       
  1032   You can turn functions @{ML my_thm_add} and @{ML my_thm_del} into 
       
  1033   attributes with the code
       
  1034 *}
       
  1035 
       
  1036 ML{*val my_add = Thm.declaration_attribute my_thm_add
       
  1037 val my_del = Thm.declaration_attribute my_thm_del *}
       
  1038 
  1019 
  1039 text {* 
  1020 text {* 
  1040   and set up the attributes as follows
  1021   and set up the attributes as follows
  1041 *}
  1022 *}
  1042 
  1023 
  1043 attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
  1024 attribute_setup %gray my_thms = {* Attrib.add_del my_add my_del *} 
  1044   "maintaining a list of my_thms - rough test only!" 
  1025   "maintaining a list of my_thms" 
  1045 
  1026 
  1046 text {*
  1027 text {*
  1047   The parser @{ML_ind  add_del in Attrib} is a predefined parser for 
  1028   The parser @{ML_ind  add_del in Attrib} is a predefined parser for 
  1048   adding and deleting lemmas. Now if you prove the next lemma 
  1029   adding and deleting lemmas. Now if you prove the next lemma 
  1049   and attach to it the attribute @{text "[my_thms]"}
  1030   and attach to it the attribute @{text "[my_thms]"}
  1053 
  1034 
  1054 text {*
  1035 text {*
  1055   then you can see it is added to the initially empty list.
  1036   then you can see it is added to the initially empty list.
  1056 
  1037 
  1057   @{ML_response_fake [display,gray]
  1038   @{ML_response_fake [display,gray]
  1058   "!my_thms" "[\"True\"]"}
  1039   "MyThms.get @{context}" 
       
  1040   "[\"True\"]"}
  1059 
  1041 
  1060   You can also add theorems using the command \isacommand{declare}.
  1042   You can also add theorems using the command \isacommand{declare}.
  1061 *}
  1043 *}
  1062 
  1044 
  1063 declare test[my_thms] trueI_2[my_thms add] 
  1045 declare test[my_thms] trueI_2[my_thms add]
  1064 
  1046 
  1065 text {*
  1047 text {*
  1066   With this attribute, the @{text "add"} operation is the default and does 
  1048   With this attribute, the @{text "add"} operation is the default and does 
  1067   not need to be explicitly given. These three declarations will cause the 
  1049   not need to be explicitly given. These three declarations will cause the 
  1068   theorem list to be updated as:
  1050   theorem list to be updated as:
  1069 
  1051 
  1070   @{ML_response_fake [display,gray]
  1052   @{ML_response_fake [display,gray]
  1071   "!my_thms"
  1053   "MyThms.get @{context}"
  1072   "[\"True\", \"Suc (Suc 0) = 2\"]"}
  1054   "[\"True\", \"Suc (Suc 0) = 2\"]"}
  1073 
  1055 
  1074   The theorem @{thm [source] trueI_2} only appears once, since the 
  1056   The theorem @{thm [source] trueI_2} only appears once, since the 
  1075   function @{ML_ind  add_thm in Thm} tests for duplicates, before extending
  1057   function @{ML_ind  add_thm in Thm} tests for duplicates, before extending
  1076   the list. Deletion from the list works as follows:
  1058   the list. Deletion from the list works as follows:
  1079 declare test[my_thms del]
  1061 declare test[my_thms del]
  1080 
  1062 
  1081 text {* After this, the theorem list is again: 
  1063 text {* After this, the theorem list is again: 
  1082 
  1064 
  1083   @{ML_response_fake [display,gray]
  1065   @{ML_response_fake [display,gray]
  1084   "!my_thms"
  1066   "MyThms.get @{context}"
  1085   "[\"True\"]"}
  1067   "[\"True\"]"}
  1086 
  1068 
  1087   We used in this example two functions declared as @{ML_ind  declaration_attribute in Thm}, 
  1069   We used in this example two functions declared as @{ML_ind
  1088   but there can be any number of them. We just have to change the parser for reading
  1070   declaration_attribute in Thm}, but there can be any number of them. We just
  1089   the arguments accordingly. 
  1071   have to change the parser for reading the arguments accordingly.
  1090 
  1072 
  1091   However, as said at the beginning of this example, using references for storing theorems is
  1073   \footnote{\bf FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?}
  1092   \emph{not} the received way of doing such things. The received way is to 
       
  1093   start a ``data slot'', below called @{text MyThmsData}, generated by the functor 
       
  1094   @{text GenericDataFun}:
       
  1095 *}
       
  1096 
       
  1097 ML{*structure MyThmsData = GenericDataFun
       
  1098  (type T = thm list
       
  1099   val empty = []
       
  1100   val extend = I
       
  1101   fun merge _ = Thm.merge_thms) *}
       
  1102 
       
  1103 text {*
       
  1104   The type @{text "T"} of this data slot is @{ML_type "thm list"}.\footnote{FIXME: give a pointer
       
  1105   to where data slots are explained properly.}
       
  1106   To use this data slot, you only have to change @{ML my_thm_add} and
       
  1107   @{ML my_thm_del} to:
       
  1108 *}
       
  1109 
       
  1110 ML{*val my_thm_add = MyThmsData.map o Thm.add_thm
       
  1111 val my_thm_del = MyThmsData.map o Thm.del_thm*}
       
  1112 
       
  1113 text {*
       
  1114   where @{ML MyThmsData.map} updates the data appropriately. The
       
  1115   corresponding theorem attributes are
       
  1116 *}
       
  1117 
       
  1118 ML{*val my_add = Thm.declaration_attribute my_thm_add
       
  1119 val my_del = Thm.declaration_attribute my_thm_del *}
       
  1120 
       
  1121 text {*
       
  1122   and the setup is as follows
       
  1123 *}
       
  1124 
       
  1125 attribute_setup %gray my_thms2 = {* Attrib.add_del my_add my_del *} 
       
  1126   "properly maintaining a list of my_thms"
       
  1127 
       
  1128 text {*
       
  1129   Initially, the data slot is empty 
       
  1130 
       
  1131   @{ML_response_fake [display,gray]
       
  1132   "MyThmsData.get (Context.Proof @{context})"
       
  1133   "[]"}
       
  1134 
       
  1135   but if you prove
       
  1136 *}
       
  1137 
       
  1138 lemma three[my_thms2]: "3 = Suc (Suc (Suc 0))" by simp
       
  1139 
       
  1140 text {*
       
  1141   then the lemma is recorded. 
       
  1142 
       
  1143   @{ML_response_fake [display,gray]
       
  1144   "MyThmsData.get (Context.Proof @{context})"
       
  1145   "[\"3 = Suc (Suc (Suc 0))\"]"}
       
  1146 
       
  1147   With theorem attribute @{text my_thms2} you can also nicely see why it 
       
  1148   is important to 
       
  1149   store data in a ``data slot'' and \emph{not} in a reference. Backtrack
       
  1150   to the point just before the lemma @{thm [source] three} was proved and 
       
  1151   check the the content of @{ML_struct MyThmsData}: it should be empty. 
       
  1152   The addition has been properly retracted. Now consider the proof:
       
  1153 *}
       
  1154 
       
  1155 lemma four[my_thms]: "4 = Suc (Suc (Suc (Suc 0)))" by simp
       
  1156 
       
  1157 text {*
       
  1158   Checking the content of @{ML my_thms} gives
       
  1159 
       
  1160   @{ML_response_fake [display,gray]
       
  1161   "!my_thms"
       
  1162   "[\"4 = Suc (Suc (Suc (Suc 0)))\", \"True\"]"}
       
  1163 
       
  1164   as expected, but if you backtrack before the lemma @{thm [source] four}, the
       
  1165   content of @{ML my_thms} is unchanged. The backtracking mechanism
       
  1166   of Isabelle is completely oblivious about what to do with references, but
       
  1167   properly treats ``data slots''!
       
  1168 
       
  1169   Since storing theorems in a list is such a common task, there is the special
       
  1170   functor @{ML_functor Named_Thms}, which does most of the work for you. To obtain
       
  1171   a named theorem list, you just declare
       
  1172 *}
       
  1173 
       
  1174 ML{*structure FooRules = Named_Thms
       
  1175  (val name = "foo" 
       
  1176   val description = "Rules for foo") *}
       
  1177 
       
  1178 text {*
       
  1179   and set up the @{ML_struct FooRules} with the command
       
  1180 *}
       
  1181 
       
  1182 setup %gray {* FooRules.setup *}
       
  1183 
       
  1184 text {*
       
  1185   This code declares a data slot where the theorems are stored,
       
  1186   an attribute @{text foo} (with the @{text add} and @{text del} options
       
  1187   for adding and deleting theorems) and an internal ML interface to retrieve and 
       
  1188   modify the theorems.
       
  1189 
       
  1190   Furthermore, the facts are made available on the user-level under the dynamic 
       
  1191   fact name @{text foo}. For example you can declare three lemmas to be of the kind
       
  1192   @{text foo} by:
       
  1193 *}
       
  1194 
       
  1195 lemma rule1[foo]: "A" sorry
       
  1196 lemma rule2[foo]: "B" sorry
       
  1197 lemma rule3[foo]: "C" sorry
       
  1198 
       
  1199 text {* and undeclare the first one by: *}
       
  1200 
       
  1201 declare rule1[foo del]
       
  1202 
       
  1203 text {* and query the remaining ones with:
       
  1204 
       
  1205   \begin{isabelle}
       
  1206   \isacommand{thm}~@{text "foo"}\\
       
  1207   @{text "> ?C"}\\
       
  1208   @{text "> ?B"}
       
  1209   \end{isabelle}
       
  1210 
       
  1211   On the ML-level the rules marked with @{text "foo"} can be retrieved
       
  1212   using the function @{ML FooRules.get}:
       
  1213 
       
  1214   @{ML_response_fake [display,gray] "FooRules.get @{context}" "[\"?C\",\"?B\"]"}
       
  1215 
       
  1216   \begin{readmore}
       
  1217   For more information see @{ML_file "Pure/Tools/named_thms.ML"}.
       
  1218   \end{readmore}
       
  1219 
       
  1220   (FIXME What are: @{text "theory_attributes"}, @{text "proof_attributes"}?)
       
  1221 
       
  1222 
  1074 
  1223   \begin{readmore}
  1075   \begin{readmore}
  1224   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  1076   FIXME: @{ML_file "Pure/more_thm.ML"}; parsers for attributes is in 
  1225   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  1077   @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about
  1226   parsing.
  1078   parsing.