934 @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. |
954 @{ML_file "Pure/thm.ML"}, @{ML_file "Pure/more_thm.ML"} and @{ML_file "Pure/drule.ML"}. |
935 \end{readmore} |
955 \end{readmore} |
936 |
956 |
937 The simplifier can be used to unfold definition in theorms. To show |
957 The simplifier can be used to unfold definition in theorms. To show |
938 this we build the theorem @{term "True \<equiv> True"} (Line 1) and then |
958 this we build the theorem @{term "True \<equiv> True"} (Line 1) and then |
939 unfold the constant according to its definition (Line 2). |
959 unfold the constant @{term "True"} according to its definition (Line 2). |
940 |
960 |
941 @{ML_response_fake [display,gray,linenos] |
961 @{ML_response_fake [display,gray,linenos] |
942 "Thm.reflexive @{cterm \"True\"} |
962 "Thm.reflexive @{cterm \"True\"} |
943 |> Simplifier.rewrite_rule [@{thm True_def}] |
963 |> Simplifier.rewrite_rule [@{thm True_def}] |
944 |> string_of_thm @{context} |
964 |> string_of_thm @{context} |
945 |> tracing" |
965 |> tracing" |
946 "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"} |
966 "(\<lambda>x. x) = (\<lambda>x. x) \<equiv> (\<lambda>x. x) = (\<lambda>x. x)"} |
947 |
967 |
948 Often it is necessary to transform theorems to and from the object |
968 Often it is necessary to transform theorems to and from the object |
949 logic. For example, the function @{ML_ind rulify in ObjectLogic} |
969 logic, that is eplacing all @{text "\<longrightarrow>"} and @{text "\<forall>"} with @{text "\<Longrightarrow>"} |
950 replaces all @{text "\<longrightarrow>"} and @{text "\<forall>"} into the equivalents of the |
970 and @{text "\<And>"}, respectively. A reason for such transformations is |
951 meta logic. For example |
971 that definitions can only be stated using object logic connectives, while |
|
972 theorems using the connectives from the meta logic are more convenient for |
|
973 reasoning. The function @{ML_ind rulify in ObjectLogic} replaces all |
|
974 object connectives by equivalents in the meta logic. For example |
952 |
975 |
953 @{ML_response_fake [display, gray] |
976 @{ML_response_fake [display, gray] |
954 "ObjectLogic.rulify @{thm foo_test2}" |
977 "ObjectLogic.rulify @{thm foo_test2}" |
955 "\<lbrakk>?A; ?B\<rbrakk> \<Longrightarrow> ?C"} |
978 "\<lbrakk>?A; ?B\<rbrakk> \<Longrightarrow> ?C"} |
956 |
979 |
986 in |
1010 in |
987 MetaSimplifier.rewrite_rule [thm''] thm' |
1011 MetaSimplifier.rewrite_rule [thm''] thm' |
988 end*} |
1012 end*} |
989 |
1013 |
990 text {* |
1014 text {* |
991 For the theorem @{thm [source] list.induct}, this function produces: |
1015 This function produces for the theorem @{thm [source] list.induct} |
992 |
1016 |
993 @{ML_response_fake [display, gray] |
1017 @{ML_response_fake [display, gray] |
994 "atomize_thm @{thm list.induct}" |
1018 "atomize_thm @{thm list.induct}" |
995 "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"} |
1019 "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"} |
996 |
1020 |
997 Theorems can also be produced from terms by giving an explicit proof. |
1021 Theorems can also be produced from terms by giving an explicit proof. |
998 One way to achive this is by using the function @{ML_ind prove in Goal}. |
1022 One way to achive this is by using the function @{ML_ind prove in Goal} |
999 For example below we prove the term @{term "P \<Longrightarrow> P"}. |
1023 in the structure @{ML_struct Goal}. For example below we prove the term |
|
1024 @{term "P \<Longrightarrow> P"}. |
1000 |
1025 |
1001 @{ML_response_fake [display,gray] |
1026 @{ML_response_fake [display,gray] |
1002 "let |
1027 "let |
1003 val trm = @{term \"P \<Longrightarrow> P::bool\"} |
1028 val trm = @{term \"P \<Longrightarrow> P::bool\"} |
1004 val tac = K (atac 1) |
1029 val tac = K (atac 1) |
1005 in |
1030 in |
1006 Goal.prove @{context} [\"P\"] [] trm tac |
1031 Goal.prove @{context} [\"P\"] [] trm tac |
1007 end" |
1032 end" |
1008 "?P \<Longrightarrow> ?P"} |
1033 "?P \<Longrightarrow> ?P"} |
1009 |
1034 |
1010 This function takes as second argument a list of strings. This list specifies |
1035 This function takes first a context and second a list of strings. This list |
1011 which variables should be turned into meta-variables once the term is proved. |
1036 specifies which variables should be turned into meta-variables once the term |
1012 The proof is given in form of a tactic as last argument. We explain tactics in |
1037 is proved. The fourth argument is the term to be proved. The fifth is a |
1013 Chapter~\ref{chp:tactical}. In the code above the tactic proved the theorem |
1038 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 |
1014 by assumption. |
1040 by assumption. |
1015 |
1041 |
1016 Theorems also contain auxiliary data, such their names and kind, but also |
1042 Theorems also contain auxiliary data, such as the name of the theorem, its |
1017 names for cases etc. This data is stored in a string-string list and can |
1043 kind, the names for cases and so on. This data is stored in a string-string |
1018 be retrieved with the function @{ML_ind get_tags in Thm}. Assume the |
1044 list and can be retrieved with the function @{ML_ind get_tags in |
1019 following lemma. |
1045 Thm}. Assume the following lemma. |
1020 *} |
1046 *} |
1021 |
1047 |
1022 lemma foo_data: "P \<Longrightarrow> P \<Longrightarrow> P" by assumption |
1048 lemma foo_data: "P \<Longrightarrow> P \<Longrightarrow> P" by assumption |
1023 |
1049 |
1024 text {* |
1050 text {* |
1025 The auxiliary data of this lemma is as follows. |
1051 So far the the auxiliary data of this lemma is: |
1026 |
1052 |
1027 @{ML_response_fake [display,gray] |
1053 @{ML_response_fake [display,gray] |
1028 "Thm.get_tags @{thm foo_data}" |
1054 "Thm.get_tags @{thm foo_data}" |
1029 "[(\"name\", \"General.foo_data\"), (\"kind\", \"lemma\")]"} |
1055 "[(\"name\", \"General.foo_data\"), (\"kind\", \"lemma\")]"} |
1030 |
1056 |
1031 When we store lemmas in the theorem database, we can explicitly extend the data |
1057 When we store lemmas in the theorem database, we may want to explicitly extend |
1032 associated with this lemma by attaching case names. |
1058 this data by attaching case names to the two premises of the lemma. This can |
|
1059 be achieved with the function @{ML_ind name in RuleCases}. |
1033 *} |
1060 *} |
1034 |
1061 |
1035 local_setup %gray {* |
1062 local_setup %gray {* |
1036 LocalTheory.note Thm.lemmaK |
1063 LocalTheory.note Thm.lemmaK |
1037 ((@{binding "foo_data'"}, []), |
1064 ((@{binding "foo_data'"}, []), |
1038 [(RuleCases.name ["foo_case1", "foo_case2"] |
1065 [(RuleCases.name ["foo_case_one", "foo_case_two"] |
1039 @{thm foo_data})]) #> snd *} |
1066 @{thm foo_data})]) #> snd *} |
1040 |
1067 |
1041 text {* |
1068 text {* |
1042 The data of the theorem @{thm [source] foo_data'} is then as follows: |
1069 The data of the theorem @{thm [source] foo_data'} is then as follows: |
1043 |
1070 |
1044 @{ML_response_fake [display,gray] |
1071 @{ML_response_fake [display,gray] |
1045 "Thm.get_tags @{thm foo_data'}" |
1072 "Thm.get_tags @{thm foo_data'}" |
1046 "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), |
1073 "[(\"name\", \"General.foo_data'\"), (\"kind\", \"lemma\"), |
1047 (\"case_names\", \"foo_case1;foo_case2\")]"} |
1074 (\"case_names\", \"foo_case_one;foo_case_two\")]"} |
1048 |
1075 |
1049 You notice the difference when using the proof methods @{ML_text cases} |
1076 You can notice the case names on the user level when using the proof |
1050 or @{ML_text induct}. In the proof below |
1077 methods @{ML_text cases} and @{ML_text induct}. In the proof below |
1051 *} |
1078 *} |
1052 |
1079 |
1053 lemma |
1080 lemma |
1054 "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1081 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1055 proof (cases rule: foo_data') |
1082 proof (cases rule: foo_data') |
1056 print_cases |
1083 |
1057 (*<*)oops(*>*) |
1084 (*<*)oops(*>*) |
1058 |
1085 text_raw{* |
1059 text {* |
1086 \begin{tabular}{@ {}l} |
1060 we can proceed by analysing the cases @{ML_text "foo_case1"} and |
1087 \isacommand{print\_cases}\\ |
1061 @{ML_text "foo_case2"}. While if the theorem has no names, then |
1088 @{text "> cases:"}\\ |
1062 the cases have standard names @{ML_text 1}, @{ML_text 2} and so |
1089 @{text "> foo_case_one:"}\\ |
|
1090 @{text "> let \"?case\" = \"?P\""}\\ |
|
1091 @{text "> foo_case_two:"}\\ |
|
1092 @{text "> let \"?case\" = \"?P\""} |
|
1093 \end{tabular}*} |
|
1094 |
|
1095 text {* |
|
1096 we can proceed by analysing the cases @{text "foo_case1"} and |
|
1097 @{text "foo_case2"}. While if the theorem has no names, then |
|
1098 the cases have standard names @{text 1}, @{text 2} and so |
1063 on. This can be seen in the proof below. |
1099 on. This can be seen in the proof below. |
1064 *} |
1100 *} |
1065 |
1101 |
1066 lemma |
1102 lemma |
1067 "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1103 shows "Q \<Longrightarrow> Q \<Longrightarrow> Q" |
1068 proof (cases rule: foo_data) |
1104 proof (cases rule: foo_data) |
1069 print_cases |
1105 |
1070 (*<*)oops(*>*) |
1106 (*<*)oops(*>*) |
1071 |
1107 text_raw{* |
1072 text {* |
1108 \begin{tabular}{@ {}l} |
1073 TBD below |
1109 \isacommand{print\_cases}\\ |
1074 |
1110 @{text "> cases:"}\\ |
1075 One great feature of Isabelle is its document preparation system where |
1111 @{text "> 1:"}\\ |
|
1112 @{text "> let \"?case\" = \"?P\""}\\ |
|
1113 @{text "> 2:"}\\ |
|
1114 @{text "> let \"?case\" = \"?P\""} |
|
1115 \end{tabular}*} |
|
1116 |
|
1117 |
|
1118 text {* |
|
1119 One great feature of Isabelle is its document preparation system, where |
1076 proved theorems can be quoted in the text directly from the formalisation. |
1120 proved theorems can be quoted in the text directly from the formalisation. |
1077 |
1121 This helps minimises cut-and-paste errors. However, sometimes the verbatim |
1078 (FIXME: example for how to add theorem styles) |
1122 quoting is not what is wanted. For such situations Isabelle allows the |
1079 *} |
1123 installation of \emph{styles}. These are, roughly speaking, functions from |
1080 |
1124 terms to terms. The input term stands for the theorem to be presented. |
1081 ML {* |
1125 Let us assume we want to display theorems without leading quantifiers. |
1082 fun strip_assums_all (params, Const("all",_) $ Abs(a, T, t)) = |
1126 For this we can implement the following function that strips off |
1083 strip_assums_all ((a, T)::params, t) |
1127 meta-quantifiers. |
1084 | strip_assums_all (params, B) = (params, B) |
1128 *} |
1085 |
1129 |
1086 fun style_parm_premise i ctxt t = |
1130 ML {*fun strip_all (Const (@{const_name "All"}, _) $ Abs body) = |
1087 let val prems = Logic.strip_imp_prems t in |
1131 Term.dest_abs body |> snd |> strip_all |
1088 if i <= length prems |
1132 | strip_all (Const (@{const_name "Trueprop"}, _) $ t) = strip_all t |
1089 then let val (params,t) = strip_assums_all([], nth prems (i - 1)) |
1133 | strip_all t = t*} |
1090 in subst_bounds(map Free params, t) end |
1134 |
1091 else error ("Not enough premises for prem" ^ string_of_int i ^ |
1135 ML {* strip_all @{term "\<forall>x y z. P x y z"}*} |
1092 " in propositon: " ^ string_of_term ctxt t) |
1136 |
1093 end; |
1137 text {* |
1094 *} |
1138 Now we can install this function as the theorem style named |
1095 |
1139 @{text "strip_all"}. |
1096 ML {* |
1140 *} |
1097 strip_assums_all ([], @{term "\<And>x y. A x y"}) |
1141 |
1098 *} |
|
1099 |
|
1100 (* |
|
1101 setup %gray {* |
1142 setup %gray {* |
1102 TermStyle.add_style "no_all_prem1" (style_parm_premise 1) #> |
1143 Term_Style.setup "strip_all" (Scan.succeed (K strip_all)) |
1103 TermStyle.add_style "no_all_prem2" (style_parm_premise 2) |
1144 *} |
1104 *} |
1145 |
1105 *) |
1146 text {* |
1106 lemma |
1147 We can test the theorem style with the following theorem |
1107 shows "A \<Longrightarrow> B" |
1148 *} |
1108 and "C \<Longrightarrow> D" |
1149 |
1109 oops |
1150 theorem style_test: |
|
1151 shows "\<forall>x y z. (x, x) = (y, z)" sorry |
|
1152 |
|
1153 text {* |
|
1154 Now printing out the theorem @{thm [source] style_test} normally |
|
1155 in a document produces |
|
1156 |
|
1157 @{thm [display] style_test} |
|
1158 |
|
1159 as expected. But with the theorem style @{text "@{thm (strip_all) \<dots>}"} |
|
1160 we obtain |
|
1161 |
|
1162 @{thm [display] (strip_all) style_test} |
|
1163 |
|
1164 without the leading quantifiers. Such theorem styles allow one to |
|
1165 print out theorems in documents formatted in any way wanted. Next we |
|
1166 explain theorem attributes, which is another mechanism for treating |
|
1167 theorems. |
|
1168 *} |
1110 |
1169 |
1111 |
1170 |
1112 section {* Theorem Attributes\label{sec:attributes} *} |
1171 section {* Theorem Attributes\label{sec:attributes} *} |
1113 |
1172 |
1114 text {* |
1173 text {* |