962 whereby @{ML_ind "thy_decl" in Keyword} indicates the kind of the |
962 whereby @{ML_ind "thy_decl" in Keyword} indicates the kind of the |
963 command. Another possible kind is @{text "thy_goal"}, or you can |
963 command. Another possible kind is @{text "thy_goal"}, or you can |
964 also to omit the kind entirely, in which case you declare a keyword |
964 also to omit the kind entirely, in which case you declare a keyword |
965 (something that is part of a command). |
965 (something that is part of a command). |
966 |
966 |
967 Now you can implement \isacommand{foobar} as: |
967 Now you can implement \isacommand{foobar} as follows. |
968 *} |
968 *} |
969 |
969 |
970 ML %grayML{*let |
970 ML %grayML{*let |
971 val do_nothing = Scan.succeed (Local_Theory.background_theory I) |
971 val do_nothing = Scan.succeed (Local_Theory.background_theory I) |
972 in |
972 in |
981 a parser producing a local theory transition (explained later). For the |
981 a parser producing a local theory transition (explained later). For the |
982 name and the kind, you can use the ML-antiquotation @{text "@{command_spec ...}"}. |
982 name and the kind, you can use the ML-antiquotation @{text "@{command_spec ...}"}. |
983 After this, you can write in your theory |
983 After this, you can write in your theory |
984 *} |
984 *} |
985 |
985 |
986 |
|
987 foobar |
986 foobar |
988 |
987 |
989 |
988 text {* |
990 text {* |
989 but of course you will not see ``anything''. |
991 Remember that this only works in jEdit. In order to let Proof-General |
990 Remember that this only works in jEdit. In order to enable also Proof-General |
992 recognise this command, a keyword file needs to be generated (see next |
991 recognise this command, a keyword file needs to be generated (see next |
993 section). |
992 section). |
994 |
993 |
995 At the moment the command \isacommand{foobar} is not very useful. Let us |
994 At the moment the command \isacommand{foobar} is not very useful. Let us |
996 refine it a bit next by letting it take a proposition as argument and |
995 refine it a bit next by letting it take a proposition as argument and |
997 printing this proposition inside the tracing buffer. We announce the |
996 printing this proposition inside the tracing buffer. We announce the |
998 command as |
997 command in the theory header as |
999 |
998 |
1000 \begin{graybox} |
999 \begin{graybox} |
1001 \isacommand{keywords} @{text [quotes] "foobar_trace"} @{text "::"} @{text "thy_decl"} |
1000 \isacommand{keywords} @{text [quotes] "foobar_trace"} @{text "::"} @{text "thy_decl"} |
1002 \end{graybox} |
1001 \end{graybox} |
1003 |
1002 |
1040 the kind indicator @{ML_ind thy_goal in Keyword} and the function @{ML |
1039 the kind indicator @{ML_ind thy_goal in Keyword} and the function @{ML |
1041 "local_theory_to_proof" in Outer_Syntax} to set up the command. |
1040 "local_theory_to_proof" in Outer_Syntax} to set up the command. |
1042 Below we show the command \isacommand{foobar\_goal} which takes a |
1041 Below we show the command \isacommand{foobar\_goal} which takes a |
1043 proposition as argument and then starts a proof in order to prove |
1042 proposition as argument and then starts a proof in order to prove |
1044 it. Therefore, we need to announce this command in the header |
1043 it. Therefore, we need to announce this command in the header |
1045 as @{text "thy_goal"} |
1044 as @{text "thy_goal"}. |
1046 |
1045 |
1047 \begin{graybox} |
1046 \begin{graybox} |
1048 \isacommand{keywords} @{text [quotes] "foobar_goal"} @{text "::"} @{text "thy_goal"} |
1047 \isacommand{keywords} @{text [quotes] "foobar_goal"} @{text "::"} @{text "thy_goal"} |
1049 \end{graybox} |
1048 \end{graybox} |
1050 |
1049 |
1089 apply(rule conjI) |
1088 apply(rule conjI) |
1090 apply(rule TrueI)+ |
1089 apply(rule TrueI)+ |
1091 done |
1090 done |
1092 |
1091 |
1093 text {* |
1092 text {* |
1094 The final new command we describe is |
1093 The last command we describe here is |
1095 \isacommand{foobar\_proof}. Like \isacommand{lemma}, its purpose is |
1094 \isacommand{foobar\_proof}. Like \isacommand{lemma}, its purpose is |
1096 to take a proposition and open a corresponding proof-state that |
1095 to take a proposition and open a corresponding proof-state that |
1097 allows us to give a proof for it. However, unlike |
1096 allows us to give a proof for it. However, unlike |
1098 \isacommand{lemma}, the proposition will be given as an |
1097 \isacommand{lemma}, the proposition will be given as a |
1099 ML-value. Such a command is quite useful during development |
1098 ML-value. Such a command is quite useful during development |
1100 of a tool that generates a goal on the ML-level and you want to see |
1099 when you generate a goal on the ML-level and want to see |
1101 whether it is provable. In addition you also want that the proved |
1100 whether it is provable. In addition allow the proved |
1102 proposition can be given a lemma name that can be referenced later on. |
1101 proposition to have a name that can be referenced later on. |
1103 |
1102 |
1104 The first problem of this new command is to parse some text as |
1103 The first problem for this command is to parse some text as |
1105 ML-source and then interpret it as a term. For the parsing we can |
1104 ML-source and then interpret it as an Isabelle term. For the parsing we can |
1106 use the function @{ML_ind "ML_source" in Parse} in the structure |
1105 use the function @{ML_ind "ML_source" in Parse} in the structure |
1107 @{ML_struct Parse}. For running the ML-interpreter we need the |
1106 @{ML_struct Parse}. For running the ML-interpreter we need the |
1108 following scaffolding code. |
1107 following scaffolding code. |
1109 *} |
1108 *} |
1110 |
1109 |
1114 fun init thy () = error "Result") |
1113 fun init thy () = error "Result") |
1115 |
1114 |
1116 val result_cookie = (Result.get, Result.put, "Result.put") *} |
1115 val result_cookie = (Result.get, Result.put, "Result.put") *} |
1117 |
1116 |
1118 text {* |
1117 text {* |
1119 With this in place we can write the code for \isacommand{foobar\_prove}. |
1118 With this in place, we can write the code for \isacommand{foobar\_prove}. |
1120 *} |
1119 *} |
1121 |
1120 |
1122 ML %linenosgray{*let |
1121 ML %linenosgray{*let |
1123 fun after_qed thm_name thms lthy = |
1122 fun after_qed thm_name thms lthy = |
1124 Local_Theory.note (thm_name, (flat thms)) lthy |> snd |
1123 Local_Theory.note (thm_name, (flat thms)) lthy |> snd |
1137 (parser >> setup_proof) |
1136 (parser >> setup_proof) |
1138 end*} |
1137 end*} |
1139 |
1138 |
1140 text {* |
1139 text {* |
1141 In Line 12, we implement a parser that first reads in an optional lemma name (terminated |
1140 In Line 12, we implement a parser that first reads in an optional lemma name (terminated |
1142 by ``:'') and then some ML-code. The function in Lines 5 to 10 takes the ML |
1141 by ``:'') and then some ML-code. The function in Lines 5 to 10 takes the ML-text |
1143 text and lets the ML-runtime evaluate it using the function @{ML_ind value in Code_Runtime} |
1142 and lets the ML-runtime evaluate it using the function @{ML_ind value in Code_Runtime} |
1144 in the structure @{ML_struct Code_Runtime}. Once the ML-text has been turned into a term, |
1143 in the structure @{ML_struct Code_Runtime}. Once the ML-text has been turned into a term, |
1145 the function @{ML theorem in Proof} opens a corresponding proof-state. This function takes the |
1144 the function @{ML theorem in Proof} opens a corresponding proof-state. This function takes the |
1146 function @{ML_text "after_qed"} as argument, whose purpose is to store the theorem, |
1145 function @{ML_text "after_qed"} as argument, whose purpose is to store the theorem, |
1147 once it is proven, under the user given name @{text "thm_name"}. |
1146 once it is proven, under the given name @{text "thm_name"}. |
1148 |
1147 |
1149 We can now give take a term, for example |
1148 You can now define a term, for example |
1150 *} |
1149 *} |
1151 |
1150 |
1152 ML %grayML{*val prop_true = @{prop "True"}*} |
1151 ML %grayML{*val prop_true = @{prop "True"}*} |
1153 |
1152 |
1154 text {* |
1153 text {* |
1155 and give a proove for it using \isacommand{foobar\_prove}: |
1154 and give it a proof using \isacommand{foobar\_prove}: |
1156 *} |
1155 *} |
1157 |
1156 |
1158 foobar_prove test: prop_true |
1157 foobar_prove test: prop_true |
1159 apply(rule TrueI) |
1158 apply(rule TrueI) |
1160 done |
1159 done |