ProgTutorial/Parsing.thy
changeset 521 9728b0432fb2
parent 520 615762b8d8cb
child 522 0ed6f49277c4
equal deleted inserted replaced
520:615762b8d8cb 521:9728b0432fb2
   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 
  1020     "traces a proposition" 
  1019     "traces a proposition" 
  1021       (Parse.prop >> trace_prop)
  1020       (Parse.prop >> trace_prop)
  1022 end *}
  1021 end *}
  1023 
  1022 
  1024 text {*
  1023 text {*
  1025   The command is now \isacommand{foobar\_trace} and can be used to 
  1024   This command can now be used to 
  1026   see the proposition in the tracing buffer.
  1025   see the proposition in the tracing buffer.
  1027 *}
  1026 *}
  1028 
  1027 
  1029 foobar_trace "True \<and> False"
  1028 foobar_trace "True \<and> False"
  1030 
  1029 
  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