777 text {* |
777 text {* |
778 If we print out the value of @{ML my_thm} then we see only the |
778 If we print out the value of @{ML my_thm} then we see only the |
779 final statement of the theorem. |
779 final statement of the theorem. |
780 |
780 |
781 @{ML_response_fake [display, gray] |
781 @{ML_response_fake [display, gray] |
782 "string_of_thm @{context} my_thm |
782 "tracing (string_of_thm @{context} my_thm)" |
783 |> tracing" |
|
784 "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"} |
783 "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"} |
785 |
784 |
786 However, internally the code-snippet constructs the following |
785 However, internally the code-snippet constructs the following |
787 proof. |
786 proof. |
788 |
787 |
799 } |
798 } |
800 \] |
799 \] |
801 |
800 |
802 While we obtained a theorem as result, this theorem is not |
801 While we obtained a theorem as result, this theorem is not |
803 yet stored in Isabelle's theorem database. Consequently, it cannot be |
802 yet stored in Isabelle's theorem database. Consequently, it cannot be |
804 referenced later on. One way to store it in the theorem database is |
803 referenced on the user level. One way to store it in the theorem database is |
805 by using the function @{ML_ind note in LocalTheory}. |
804 by using the function @{ML_ind note in LocalTheory}. |
806 *} |
805 *} |
807 |
806 |
808 local_setup %gray {* |
807 local_setup %gray {* |
809 LocalTheory.note Thm.theoremK |
808 LocalTheory.note Thm.theoremK |
810 ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
809 ((@{binding "my_thm"}, []), [my_thm]) #> snd *} |
811 |
810 |
812 text {* |
811 text {* |
813 The first argument @{ML_ind theoremK in Thm} is a kind indicator, which |
812 The first argument @{ML_ind theoremK in Thm} is a kind indicator, which |
814 classifies the theorem. For a theorem arising from a definition we should |
813 classifies the theorem. There are several such kind indicators: for a |
815 use @{ML_ind definitionK in Thm}, for an axiom @{ML_ind axiomK in Thm}, for |
814 theorem arising from a definition we should use @{ML_ind definitionK in |
816 ``normal'' theorems the kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK |
815 Thm}, for an axiom @{ML_ind axiomK in Thm}, for ``normal'' theorems the |
817 in Thm}. The second argument is the name under which we store the theorem |
816 kinds @{ML_ind theoremK in Thm} or @{ML_ind lemmaK in Thm}. The second |
818 or theorems. The third can contain a list of (theorem) attributes. We will |
817 argument of @{ML note in LocalTheory} is the name under which we store the |
819 explain them in detail in Section~\ref{sec:attributes}. Below we |
818 theorem or theorems. The third argument can contain a list of (theorem) |
820 use such an attribute in order add the theorem to the simpset. |
819 attributes. We will explain them in detail in |
821 have to declare: |
820 Section~\ref{sec:attributes}. Below we just use one such attribute in order add |
|
821 the theorem to the simpset: |
822 *} |
822 *} |
823 |
823 |
824 local_setup %gray {* |
824 local_setup %gray {* |
825 LocalTheory.note Thm.theoremK |
825 LocalTheory.note Thm.theoremK |
826 ((@{binding "my_thm_simp"}, |
826 ((@{binding "my_thm_simp"}, |
827 [Attrib.internal (K Simplifier.simp_add)]), [my_thm]) #> snd *} |
827 [Attrib.internal (K Simplifier.simp_add)]), [my_thm]) #> snd *} |
828 |
828 |
829 text {* |
829 text {* |
830 Note that we have to use another name for the theorem, since Isabelle does |
830 Note that we have to use another name under which the theorem is stored, |
831 not allow to store another theorem under the same name. The attribute needs to |
831 since Isabelle does not allow us to store another theorem under the same |
832 be wrapped inside the function @{ML_ind internal in Attrib}. If we use the |
832 name. The attribute needs to be wrapped inside the function @{ML_ind |
833 function @{ML get_thm_names_from_ss} from the previous chapter, we can check |
833 internal in Attrib}. If we use the function @{ML get_thm_names_from_ss} from |
834 whether the theorem has actually been added. |
834 the previous chapter, we can check whether the theorem has actually been |
|
835 added. |
|
836 |
835 |
837 |
836 @{ML_response [display,gray] |
838 @{ML_response [display,gray] |
837 "let |
839 "let |
838 fun pred s = match_string \"my_thm_simp\" s |
840 fun pred s = match_string \"my_thm_simp\" s |
839 in |
841 in |
851 @{text ">"}~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"} |
853 @{text ">"}~@{prop "\<lbrakk>\<And>x. P x \<Longrightarrow> Q x; P t\<rbrakk> \<Longrightarrow> Q t"} |
852 \end{isabelle} |
854 \end{isabelle} |
853 |
855 |
854 or with the @{text "@{thm \<dots>}"}-antiquotation on the ML-level. As can be seen |
856 or with the @{text "@{thm \<dots>}"}-antiquotation on the ML-level. As can be seen |
855 the theorem does not have any meta-variables that would be present if we proved |
857 the theorem does not have any meta-variables that would be present if we proved |
856 this theorem on the user-level. We will see later on, we have to construct |
858 this theorem on the user-level. We will see later on that usually we have to |
857 meta-variables in a theorem explicitly. |
859 construct meta-variables in theorems explicitly. |
858 *} |
860 *} |
859 |
861 |
860 text {* |
862 text {* |
861 There is a multitude of functions that manage or manipulate theorems. For example |
863 There is a multitude of functions that manage or manipulate theorems. For example |
862 we can test theorems for (alpha) equality. Suppose you proved the following three |
864 we can test theorems for alpha equality. Suppose you proved the following three |
863 facts. |
865 theorems. |
864 *} |
866 *} |
865 |
867 |
866 lemma |
868 lemma |
867 shows thm1: "\<forall>x. P x" |
869 shows thm1: "\<forall>x. P x" |
868 and thm2: "\<forall>y. P y" |
870 and thm2: "\<forall>y. P y" |
869 and thm3: "\<forall>y. Q y" sorry |
871 and thm3: "\<forall>y. Q y" sorry |
870 |
872 |
871 text {* |
873 text {* |
872 Testing for equality using the function @{ML_ind eq_thm in Thm} produces: |
874 Testing them for alpha equality using the function @{ML_ind eq_thm in Thm} produces: |
873 |
875 |
874 @{ML_response [display,gray] |
876 @{ML_response [display,gray] |
875 "(Thm.eq_thm (@{thm thm1}, @{thm thm2}), |
877 "(Thm.eq_thm (@{thm thm1}, @{thm thm2}), |
876 Thm.eq_thm (@{thm thm2}, @{thm thm3}))" |
878 Thm.eq_thm (@{thm thm2}, @{thm thm3}))" |
877 "(true, false)"} |
879 "(true, false)"} |
883 @{ML_response_fake [display,gray] |
885 @{ML_response_fake [display,gray] |
884 "let |
886 "let |
885 val eq = @{thm True_def} |
887 val eq = @{thm True_def} |
886 in |
888 in |
887 (Thm.lhs_of eq, Thm.rhs_of eq) |
889 (Thm.lhs_of eq, Thm.rhs_of eq) |
888 |> pairself (tracing o string_of_cterm @{context}) |
890 |> pairself (string_of_cterm @{context}) |
889 end" |
891 end" |
890 "True |
892 "(True, (\<lambda>x. x) = (\<lambda>x. x))"} |
891 (\<lambda>x. x) = (\<lambda>x. x)"} |
|
892 |
893 |
893 Other function produce terms that can be pattern-matched. |
894 Other function produce terms that can be pattern-matched. |
894 Suppose the following two theorems. |
895 Suppose the following two theorems. |
895 *} |
896 *} |
896 |
897 |
897 lemma |
898 lemma |
898 shows foo_test1: "A \<Longrightarrow> B \<Longrightarrow> C" |
899 shows foo_test1: "A \<Longrightarrow> B \<Longrightarrow> C" |
899 and foo_test2: "A \<longrightarrow> B \<longrightarrow> C" sorry |
900 and foo_test2: "A \<longrightarrow> B \<longrightarrow> C" sorry |
900 |
901 |
901 text {* |
902 text {* |
902 We can deconstruct them into premises and conclusions as follows. |
903 We can destruct them into premises and conclusions as follows. |
903 |
904 |
904 @{ML_response_fake [display,gray] |
905 @{ML_response_fake [display,gray] |
905 "let |
906 "let |
906 val ctxt = @{context} |
907 val ctxt = @{context} |
907 fun prems_and_concl thm = |
908 fun prems_and_concl thm = |
908 [\"Premises: \" ^ |
909 [\"Premises: \" ^ (string_of_terms ctxt (Thm.prems_of thm))] @ |
909 (string_of_terms ctxt (Thm.prems_of thm))] @ |
910 [\"Conclusion: \" ^ (string_of_term ctxt (Thm.concl_of thm))] |
910 [\"Conclusion: \" ^ |
|
911 (string_of_term ctxt (Thm.concl_of thm))] |
|
912 |> cat_lines |
911 |> cat_lines |
913 |> tracing |
912 |> tracing |
914 in |
913 in |
915 prems_and_concl @{thm foo_test1}; |
914 prems_and_concl @{thm foo_test1}; |
916 prems_and_concl @{thm foo_test2} |
915 prems_and_concl @{thm foo_test2} |
1078 shows "A \<Longrightarrow> B" |
1077 shows "A \<Longrightarrow> B" |
1079 and "C \<Longrightarrow> D" |
1078 and "C \<Longrightarrow> D" |
1080 oops |
1079 oops |
1081 |
1080 |
1082 |
1081 |
1083 section {* Setups (TBD) *} |
|
1084 |
|
1085 text {* |
|
1086 In the previous section we used \isacommand{setup} in order to make |
|
1087 a theorem attribute known to Isabelle. What happens behind the scenes |
|
1088 is that \isacommand{setup} expects a function of type |
|
1089 @{ML_type "theory -> theory"}: the input theory is the current theory and the |
|
1090 output the theory where the theory attribute has been stored. |
|
1091 |
|
1092 This is a fundamental principle in Isabelle. A similar situation occurs |
|
1093 for example with declaring constants. The function that declares a |
|
1094 constant on the ML-level is @{ML_ind add_consts_i in Sign}. |
|
1095 If you write\footnote{Recall that ML-code needs to be |
|
1096 enclosed in \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"}.} |
|
1097 *} |
|
1098 |
|
1099 ML{*Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] @{theory} *} |
|
1100 |
|
1101 text {* |
|
1102 for declaring the constant @{text "BAR"} with type @{typ nat} and |
|
1103 run the code, then you indeed obtain a theory as result. But if you |
|
1104 query the constant on the Isabelle level using the command \isacommand{term} |
|
1105 |
|
1106 \begin{isabelle} |
|
1107 \isacommand{term}~@{text [quotes] "BAR"}\\ |
|
1108 @{text "> \"BAR\" :: \"'a\""} |
|
1109 \end{isabelle} |
|
1110 |
|
1111 you do not obtain a constant of type @{typ nat}, but a free variable (printed in |
|
1112 blue) of polymorphic type. The problem is that the ML-expression above did |
|
1113 not register the declaration with the current theory. This is what the command |
|
1114 \isacommand{setup} is for. The constant is properly declared with |
|
1115 *} |
|
1116 |
|
1117 setup %gray {* Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] *} |
|
1118 |
|
1119 text {* |
|
1120 Now |
|
1121 |
|
1122 \begin{isabelle} |
|
1123 \isacommand{term}~@{text [quotes] "BAR"}\\ |
|
1124 @{text "> \"BAR\" :: \"nat\""} |
|
1125 \end{isabelle} |
|
1126 |
|
1127 returns a (black) constant with the type @{typ nat}. |
|
1128 |
|
1129 A similar command is \isacommand{local\_setup}, which expects a function |
|
1130 of type @{ML_type "local_theory -> local_theory"}. Later on we will also |
|
1131 use the commands \isacommand{method\_setup} for installing methods in the |
|
1132 current theory and \isacommand{simproc\_setup} for adding new simprocs to |
|
1133 the current simpset. |
|
1134 *} |
|
1135 |
|
1136 section {* Theorem Attributes\label{sec:attributes} *} |
1082 section {* Theorem Attributes\label{sec:attributes} *} |
1137 |
1083 |
1138 text {* |
1084 text {* |
1139 Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text |
1085 Theorem attributes are @{text "[symmetric]"}, @{text "[THEN \<dots>]"}, @{text |
1140 "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags |
1086 "[simp]"} and so on. Such attributes are \emph{neither} tags \emph{nor} flags |
1356 @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about |
1302 @{ML_file "Pure/Isar/attrib.ML"}...also explained in the chapter about |
1357 parsing. |
1303 parsing. |
1358 \end{readmore} |
1304 \end{readmore} |
1359 *} |
1305 *} |
1360 |
1306 |
1361 |
1307 section {* Setups (TBD) *} |
|
1308 |
|
1309 text {* |
|
1310 In the previous section we used \isacommand{setup} in order to make |
|
1311 a theorem attribute known to Isabelle. What happens behind the scenes |
|
1312 is that \isacommand{setup} expects a function of type |
|
1313 @{ML_type "theory -> theory"}: the input theory is the current theory and the |
|
1314 output the theory where the theory attribute has been stored. |
|
1315 |
|
1316 This is a fundamental principle in Isabelle. A similar situation occurs |
|
1317 for example with declaring constants. The function that declares a |
|
1318 constant on the ML-level is @{ML_ind add_consts_i in Sign}. |
|
1319 If you write\footnote{Recall that ML-code needs to be |
|
1320 enclosed in \isacommand{ML}~@{text "\<verbopen> \<dots> \<verbclose>"}.} |
|
1321 *} |
|
1322 |
|
1323 ML{*Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] @{theory} *} |
|
1324 |
|
1325 text {* |
|
1326 for declaring the constant @{text "BAR"} with type @{typ nat} and |
|
1327 run the code, then you indeed obtain a theory as result. But if you |
|
1328 query the constant on the Isabelle level using the command \isacommand{term} |
|
1329 |
|
1330 \begin{isabelle} |
|
1331 \isacommand{term}~@{text [quotes] "BAR"}\\ |
|
1332 @{text "> \"BAR\" :: \"'a\""} |
|
1333 \end{isabelle} |
|
1334 |
|
1335 you do not obtain a constant of type @{typ nat}, but a free variable (printed in |
|
1336 blue) of polymorphic type. The problem is that the ML-expression above did |
|
1337 not register the declaration with the current theory. This is what the command |
|
1338 \isacommand{setup} is for. The constant is properly declared with |
|
1339 *} |
|
1340 |
|
1341 setup %gray {* Sign.add_consts_i [(@{binding "BAR"}, @{typ "nat"}, NoSyn)] *} |
|
1342 |
|
1343 text {* |
|
1344 Now |
|
1345 |
|
1346 \begin{isabelle} |
|
1347 \isacommand{term}~@{text [quotes] "BAR"}\\ |
|
1348 @{text "> \"BAR\" :: \"nat\""} |
|
1349 \end{isabelle} |
|
1350 |
|
1351 returns a (black) constant with the type @{typ nat}. |
|
1352 |
|
1353 A similar command is \isacommand{local\_setup}, which expects a function |
|
1354 of type @{ML_type "local_theory -> local_theory"}. Later on we will also |
|
1355 use the commands \isacommand{method\_setup} for installing methods in the |
|
1356 current theory and \isacommand{simproc\_setup} for adding new simprocs to |
|
1357 the current simpset. |
|
1358 *} |
1362 |
1359 |
1363 section {* Theories (TBD) *} |
1360 section {* Theories (TBD) *} |
1364 |
1361 |
1365 text {* |
1362 text {* |
1366 There are theories, proof contexts and local theories (in this order, if you |
1363 There are theories, proof contexts and local theories (in this order, if you |