823 |
823 |
824 While we obtained a theorem as result, this theorem is not |
824 While we obtained a theorem as result, this theorem is not |
825 yet stored in Isabelle's theorem database. Consequently, it cannot be |
825 yet stored in Isabelle's theorem database. Consequently, it cannot be |
826 referenced on the user level. One way to store it in the theorem database is |
826 referenced on the user level. One way to store it in the theorem database is |
827 by using the function @{ML_ind note in LocalTheory}.\footnote{\bf FIXME: make sure a pointer |
827 by using the function @{ML_ind note in LocalTheory}.\footnote{\bf FIXME: make sure a pointer |
828 to the section about local-setup is given eralier.} |
828 to the section about local-setup is given earlier.} |
829 *} |
829 *} |
830 |
830 |
831 local_setup %gray {* |
831 local_setup %gray {* |
832 LocalTheory.note Thm.theoremK |
832 LocalTheory.note Thm.theoremK |
833 ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
833 ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
834 |
834 |
835 text {* |
835 text {* |
836 The first argument @{ML_ind theoremK in Thm} is a kind indicator, which |
836 The fourth argument of @{ML note in LocalTheory} is the list of theorems we |
837 classifies the theorem. There are several such kind indicators: for a |
837 want to store under a name. The first argument @{ML_ind theoremK in Thm} is |
838 theorem arising from a definition we should use @{ML_ind definitionK in |
838 a kind indicator, which classifies the theorem. There are several such kind |
839 Thm}, for an axiom @{ML_ind axiomK in Thm}, and for ``normal'' theorems the |
839 indicators: for a theorem arising from a definition you should use @{ML_ind |
840 kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK in Thm}. The second |
840 definitionK in Thm}, for an axiom @{ML_ind axiomK in Thm}, and for |
841 argument of @{ML note in LocalTheory} is the name under which we store the |
841 ``normal'' theorems the kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK |
842 theorem or theorems. The third argument can contain a list of theorem |
842 in Thm}. The second argument of @{ML note in LocalTheory} is the name under |
843 attributes, which we will explain in detail in Section~\ref{sec:attributes}. |
843 which we store the theorem or theorems. The third argument can contain a |
844 Below we just use one such attribute in order add |
844 list of theorem attributes, which we will explain in detail in |
845 the theorem to the simpset: |
845 Section~\ref{sec:attributes}. Below we just use one such attribute in order |
|
846 add the theorem to the simpset: |
846 *} |
847 *} |
847 |
848 |
848 local_setup %gray {* |
849 local_setup %gray {* |
849 LocalTheory.note Thm.theoremK |
850 LocalTheory.note Thm.theoremK |
850 ((@{binding "my_thm_simp"}, |
851 ((@{binding "my_thm_simp"}, |
851 [Attrib.internal (K Simplifier.simp_add)]), [my_thm]) #> snd *} |
852 [Attrib.internal (K Simplifier.simp_add)]), [my_thm]) #> snd *} |
852 |
853 |
853 text {* |
854 text {* |
854 Note that we have to use another name under which the theorem is stored, |
855 Note that we have to use another name under which the theorem is stored, |
855 since Isabelle does not allow us to store two theorems under the same |
856 since Isabelle does not allow us to call @{ML_ind note in LocalTheory} twice |
856 name. The attribute needs to be wrapped inside the function @{ML_ind |
857 with the same name. The attribute needs to be wrapped inside the function @{ML_ind |
857 internal in Attrib}. If we use the function @{ML get_thm_names_from_ss} from |
858 internal in Attrib} from the structure @{ML_struct Attrib}. If we use the function |
|
859 @{ML get_thm_names_from_ss} from |
858 the previous chapter, we can check whether the theorem has actually been |
860 the previous chapter, we can check whether the theorem has actually been |
859 added. |
861 added. |
860 |
862 |
861 |
863 |
862 @{ML_response [display,gray] |
864 @{ML_response [display,gray] |
952 For the functions @{text "assume"}, @{text "forall_elim"} etc |
954 For the functions @{text "assume"}, @{text "forall_elim"} etc |
953 see \isccite{sec:thms}. The basic functions for theorems are defined in |
955 see \isccite{sec:thms}. The basic functions for theorems are defined in |
954 @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. |
956 @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. |
955 \end{readmore} |
957 \end{readmore} |
956 |
958 |
957 The simplifier can be used to unfold definition in theorms. To show |
959 The simplifier can be used to unfold definition in theorems. To show |
958 this we build the theorem @{term "True \<equiv> True"} (Line 1) and then |
960 this we build the theorem @{term "True \<equiv> True"} (Line 1) and then |
959 unfold the constant @{term "True"} according to its definition (Line 2). |
961 unfold the constant @{term "True"} according to its definition (Line 2). |
960 |
962 |
961 @{ML_response_fake [display,gray,linenos] |
963 @{ML_response_fake [display,gray,linenos] |
962 "Thm.reflexive @{cterm \"True\"} |
964 "Thm.reflexive @{cterm \"True\"} |
964 |> string_of_thm @{context} |
966 |> string_of_thm @{context} |
965 |> tracing" |
967 |> tracing" |
966 "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"} |
968 "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"} |
967 |
969 |
968 Often it is necessary to transform theorems to and from the object |
970 Often it is necessary to transform theorems to and from the object |
969 logic, that is eplacing all @{text "\<longrightarrow>"} and @{text "\<forall>"} with @{text "\<Longrightarrow>"} |
971 logic, that is replacing all @{text "\<longrightarrow>"} and @{text "\<forall>"} by @{text "\<Longrightarrow>"} |
970 and @{text "\<And>"}, respectively. A reason for such transformations is |
972 and @{text "\<And>"}, or the other way around. A reason for such a transformation |
971 that definitions can only be stated using object logic connectives, while |
973 might be stating a definition. The reason is that definitions can only be |
972 theorems using the connectives from the meta logic are more convenient for |
974 stated using object logic connectives, while theorems using the connectives |
973 reasoning. The function @{ML_ind rulify in ObjectLogic} replaces all |
975 from the meta logic are more convenient for reasoning. Therefore there are |
974 object connectives by equivalents in the meta logic. For example |
976 some build in functions which help with these transformations. The function |
|
977 @{ML_ind rulify in ObjectLogic} |
|
978 replaces all object connectives by equivalents in the meta logic. For example |
975 |
979 |
976 @{ML_response_fake [display, gray] |
980 @{ML_response_fake [display, gray] |
977 "ObjectLogic.rulify @{thm foo_test2}" |
981 "ObjectLogic.rulify @{thm foo_test2}" |
978 "\<lbrakk>?A; ?B\<rbrakk> \<Longrightarrow> ?C"} |
982 "\<lbrakk>?A; ?B\<rbrakk> \<Longrightarrow> ?C"} |
979 |
983 |
991 |
995 |
992 In this code the function @{ML atomize in ObjectLogic} produces |
996 In this code the function @{ML atomize in ObjectLogic} produces |
993 a meta-equation between the given theorem and the theorem transformed |
997 a meta-equation between the given theorem and the theorem transformed |
994 into the object logic. The result is the theorem with object logic |
998 into the object logic. The result is the theorem with object logic |
995 connectives. However, in order to completely transform a theorem |
999 connectives. However, in order to completely transform a theorem |
996 such as @{thm [source] list.induct}, which is of the form |
1000 involving meta variables, such as @{thm [source] list.induct}, which |
|
1001 is of the form |
997 |
1002 |
998 @{thm [display] list.induct} |
1003 @{thm [display] list.induct} |
999 |
1004 |
1000 we have to first abstract over the meta variables @{text "?P"} and |
1005 we have to first abstract over the meta variables @{text "?P"} and |
1001 @{text "?list"} in the theorem. For this we can use the function |
1006 @{text "?list"}. For this we can use the function |
1002 @{ML_ind forall_intr_vars in Drule}. This allows us to implement the |
1007 @{ML_ind forall_intr_vars in Drule}. This allows us to implement the |
1003 following function for atomizing a theorem. |
1008 following function for atomizing a theorem. |
1004 *} |
1009 *} |
1005 |
1010 |
1006 ML{*fun atomize_thm thm = |
1011 ML{*fun atomize_thm thm = |
1017 @{ML_response_fake [display, gray] |
1022 @{ML_response_fake [display, gray] |
1018 "atomize_thm @{thm list.induct}" |
1023 "atomize_thm @{thm list.induct}" |
1019 "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"} |
1024 "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"} |
1020 |
1025 |
1021 Theorems can also be produced from terms by giving an explicit proof. |
1026 Theorems can also be produced from terms by giving an explicit proof. |
1022 One way to achive this is by using the function @{ML_ind prove in Goal} |
1027 One way to achieve this is by using the function @{ML_ind prove in Goal} |
1023 in the structure @{ML_struct Goal}. For example below we prove the term |
1028 in the structure @{ML_struct Goal}. For example below we use this function |
1024 @{term "P \<Longrightarrow> P"}. |
1029 to prove the term @{term "P \<Longrightarrow> P"}. |
1025 |
1030 |
1026 @{ML_response_fake [display,gray] |
1031 @{ML_response_fake [display,gray] |
1027 "let |
1032 "let |
1028 val trm = @{term \"P \<Longrightarrow> P::bool\"} |
1033 val trm = @{term \"P \<Longrightarrow> P::bool\"} |
1029 val tac = K (atac 1) |
1034 val tac = K (atac 1) |
1033 "?P \<Longrightarrow> ?P"} |
1038 "?P \<Longrightarrow> ?P"} |
1034 |
1039 |
1035 This function takes first a context and second a list of strings. This list |
1040 This function takes first a context and second a list of strings. This list |
1036 specifies which variables should be turned into meta-variables once the term |
1041 specifies which variables should be turned into meta-variables once the term |
1037 is proved. The fourth argument is the term to be proved. The fifth is a |
1042 is proved. The fourth argument is the term to be proved. The fifth is a |
1038 corresponding proof given in form of a tactic. We explain tactics in |
1043 corresponding proof given in form of a tactic (we explain tactics in |
1039 Chapter~\ref{chp:tactical}. In the code above, the tactic proves the theorem |
1044 Chapter~\ref{chp:tactical}). In the code above, the tactic proves the theorem |
1040 by assumption. |
1045 by assumption. As before this code will produce a theorem, but the theorem |
|
1046 is not yet stored in the theorem database. |
1041 |
1047 |
1042 Theorems also contain auxiliary data, such as the name of the theorem, its |
1048 Theorems also contain auxiliary data, such as the name of the theorem, its |
1043 kind, the names for cases and so on. This data is stored in a string-string |
1049 kind, the names for cases and so on. This data is stored in a string-string |
1044 list and can be retrieved with the function @{ML_ind get_tags in |
1050 list and can be retrieved with the function @{ML_ind get_tags in |
1045 Thm}. Assume the following lemma. |
1051 Thm}. Assume you prove the following lemma. |
1046 *} |
1052 *} |
1047 |
1053 |
1048 lemma foo_data: "P \<Longrightarrow> P \<Longrightarrow> P" by assumption |
1054 lemma foo_data: |
1049 |
1055 shows "P \<Longrightarrow> P \<Longrightarrow> P" by assumption |
1050 text {* |
1056 |
1051 So far the the auxiliary data of this lemma is: |
1057 text {* |
|
1058 The auxiliary data of this lemma can be retrieved using the function |
|
1059 @{ML_ind get_tags in Thm}. So far the the auxiliary data of this lemma is |
1052 |
1060 |
1053 @{ML_response_fake [display,gray] |
1061 @{ML_response_fake [display,gray] |
1054 "Thm.get_tags @{thm foo_data}" |
1062 "Thm.get_tags @{thm foo_data}" |
1055 "[(\"name\", \"General.foo_data\"), (\"kind\", \"lemma\")]"} |
1063 "[(\"name\", \"General.foo_data\"), (\"kind\", \"lemma\")]"} |
1056 |
1064 |
1057 When we store lemmas in the theorem database, we may want to explicitly extend |
1065 consisting of a name and a kind. When we store lemmas in the theorem database, |
1058 this data by attaching case names to the two premises of the lemma. This can |
1066 we might want to explicitly extend this data by attaching case names to the |
1059 be achieved with the function @{ML_ind name in RuleCases}. |
1067 two premises of the lemma. This can be done with the function @{ML_ind name in RuleCases} |
|
1068 from the structure @{ML_struct RuleCases}. |
1060 *} |
1069 *} |
1061 |
1070 |
1062 local_setup %gray {* |
1071 local_setup %gray {* |
1063 LocalTheory.note Thm.lemmaK |
1072 LocalTheory.note Thm.lemmaK |
1064 ((@{binding "foo_data'"}, []), |
1073 ((@{binding "foo_data'"}, []), |
1071 @{ML_response_fake [display,gray] |
1080 @{ML_response_fake [display,gray] |
1072 "Thm.get_tags @{thm foo_data'}" |
1081 "Thm.get_tags @{thm foo_data'}" |
1073 "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), |
1082 "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), |
1074 (\"case_names\", \"foo_case_one;foo_case_two\")]"} |
1083 (\"case_names\", \"foo_case_one;foo_case_two\")]"} |
1075 |
1084 |
1076 You can notice the case names on the user level when using the proof |
1085 You can observe the case names of this lemma on the user level when using |
1077 methods @{ML_text cases} and @{ML_text induct}. In the proof below |
1086 the proof methods @{ML_text cases} and @{ML_text induct}. In the proof below |
1078 *} |
1087 *} |
1079 |
1088 |
1080 lemma |
1089 lemma |
1081 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1090 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1082 proof (cases rule: foo_data') |
1091 proof (cases rule: foo_data') |
1115 \end{tabular}*} |
1124 \end{tabular}*} |
1116 |
1125 |
1117 |
1126 |
1118 text {* |
1127 text {* |
1119 One great feature of Isabelle is its document preparation system, where |
1128 One great feature of Isabelle is its document preparation system, where |
1120 proved theorems can be quoted in the text directly from the formalisation. |
1129 proved theorems can be quoted in documents referencing directly their |
1121 This helps minimises cut-and-paste errors. However, sometimes the verbatim |
1130 formalisation. This helps tremendously to minimise cut-and-paste errors. However, |
1122 quoting is not what is wanted. For such situations Isabelle allows the |
1131 sometimes the verbatim quoting is not what is wanted or what can be shown to |
1123 installation of \emph{styles}. These are, roughly speaking, functions from |
1132 readers. For such situations Isabelle allows the installation of \emph{theorem |
1124 terms to terms. The input term stands for the theorem to be presented. |
1133 styles}. These are, roughly speaking, functions from terms to terms. The input |
1125 Let us assume we want to display theorems without leading quantifiers. |
1134 term stands for the theorem to be presented; the output can be constructed to |
1126 For this we can implement the following function that strips off |
1135 ones wishes. Let us, for example, assume we want to quote theorems without |
1127 meta-quantifiers. |
1136 leading @{text \<forall>}-quantifiers. For this we can implement the following function |
1128 *} |
1137 that strips off meta-quantifiers. |
1129 |
1138 *} |
1130 ML {*fun strip_all (Const (@{const_name "All"}, _) $ Abs body) = |
1139 |
1131 Term.dest_abs body |> snd |> strip_all |
1140 ML %linenosgray {*fun strip_all_qnt (Const (@{const_name "All"}, _) $ Abs body) = |
1132 | strip_all (Const (@{const_name "Trueprop"}, _) $ t) = strip_all t |
1141 Term.dest_abs body |> snd |> strip_all_qnt |
1133 | strip_all t = t*} |
1142 | strip_all_qnt (Const (@{const_name "Trueprop"}, _) $ t) = |
1134 |
1143 strip_all_qnt t |
1135 ML {* strip_all @{term "\<forall>x y z. P x y z"}*} |
1144 | strip_all_qnt t = t*} |
1136 |
1145 |
1137 text {* |
1146 text {* |
1138 Now we can install this function as the theorem style named |
1147 We use in Line 2 the function @{ML_ind dest_abs in Term} for deconstructing abstractions, |
1139 @{text "strip_all"}. |
1148 since this function deals correctly with potential name clashes. This function produces |
|
1149 a pair consisting of the variable and the body of the abstraction. We are only interested |
|
1150 in the body, which we feed into the recursive call. In Line 3 and 4, we also |
|
1151 have to explicitly strip of the outermost @{term Trueprop}-coercion. Now we can |
|
1152 install this function as the theorem style named @{text "my_strip_all_qnt"}. |
1140 *} |
1153 *} |
1141 |
1154 |
1142 setup %gray {* |
1155 setup %gray {* |
1143 Term_Style.setup "strip_all" (Scan.succeed (K strip_all)) |
1156 Term_Style.setup "my_strip_all_qnt" (Scan.succeed (K strip_all_qnt)) |
1144 *} |
1157 *} |
1145 |
1158 |
1146 text {* |
1159 text {* |
1147 We can test the theorem style with the following theorem |
1160 We can test this theorem style with the following theorem |
1148 *} |
1161 *} |
1149 |
1162 |
1150 theorem style_test: |
1163 theorem style_test: |
1151 shows "\<forall>x y z. (x, x) = (y, z)" sorry |
1164 shows "\<forall>x y z. (x, x) = (y, z)" sorry |
1152 |
1165 |
1153 text {* |
1166 text {* |
1154 Now printing out the theorem @{thm [source] style_test} normally |
1167 Now printing out in a document the theorem @{thm [source] style_test} normally |
1155 in a document produces |
1168 using @{text "@{thm \<dots>}"} produces |
1156 |
1169 |
1157 @{thm [display] style_test} |
1170 \begin{isabelle} |
1158 |
1171 @{text "@{thm style_test}"}\\ |
1159 as expected. But with the theorem style @{text "@{thm (strip_all) \<dots>}"} |
1172 @{text ">"}~@{thm style_test} |
|
1173 \end{isabelle} |
|
1174 |
|
1175 as expected. But with the theorem style @{text "@{thm (my_strip_all_qnt) \<dots>}"} |
1160 we obtain |
1176 we obtain |
1161 |
1177 |
1162 @{thm [display] (strip_all) style_test} |
1178 \begin{isabelle} |
1163 |
1179 @{text "@{thm (my_strip_all_qnt) style_test}"}\\ |
1164 without the leading quantifiers. Such theorem styles allow one to |
1180 @{text ">"}~@{thm (my_strip_all_qnt) style_test}\\ |
1165 print out theorems in documents formatted in any way wanted. Next we |
1181 \end{isabelle} |
1166 explain theorem attributes, which is another mechanism for treating |
1182 |
1167 theorems. |
1183 without the leading quantifiers. We can improve this theorem style by explicitly |
1168 *} |
1184 giving a list of strings that should be used for the replacement of the |
1169 |
1185 variables. For this we implement the function which takes a list of strings |
|
1186 and uses them as name in the outermost abstractions. |
|
1187 *} |
|
1188 |
|
1189 ML {*fun rename_all [] t = t |
|
1190 | rename_all (x::xs) (Const (@{const_name "All"}, U) $ Abs (_, T, t)) = |
|
1191 Const (@{const_name "All"}, U) $ Abs (x, T, rename_all xs t) |
|
1192 | rename_all xs (Const (@{const_name "Trueprop"}, U) $ t) = |
|
1193 rename_all xs t |
|
1194 | rename_all _ t = t*} |
|
1195 |
|
1196 text {* |
|
1197 We can now install a the modified theorem style as follows |
|
1198 *} |
|
1199 |
|
1200 setup %gray {* |
|
1201 let |
|
1202 val parser = Scan.repeat Args.name |
|
1203 fun action xs = K (rename_all xs #> strip_all_qnt) |
|
1204 in |
|
1205 Term_Style.setup "my_strip_all_qnt2" (parser >> action) |
|
1206 end *} |
|
1207 |
|
1208 text {* |
|
1209 We can now suggest, for example, two variables for stripping |
|
1210 off the @{text \<forall>}-quantifiers, namely: |
|
1211 |
|
1212 \begin{isabelle} |
|
1213 @{text "@{thm (my_strip_all_qnt2 x' x'') style_test}"}\\ |
|
1214 @{text ">"}~@{thm (my_strip_all_qnt2 x' x'') style_test} |
|
1215 \end{isabelle} |
|
1216 |
|
1217 Such theorem styles allow one to print out theorems in documents formatted to |
|
1218 ones heart content. Next we explain theorem attributes, which is another |
|
1219 mechanism for dealing with theorems. |
|
1220 |
|
1221 \begin{readmore} |
|
1222 Theorem styles are implemented in @{ML_file "Pure/Thy/term_style.ML"}. |
|
1223 \end{readmore} |
|
1224 *} |
1170 |
1225 |
1171 section {* Theorem Attributes\label{sec:attributes} *} |
1226 section {* Theorem Attributes\label{sec:attributes} *} |
1172 |
1227 |
1173 text {* |
1228 text {* |
1174 Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text |
1229 Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text |