|    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 |