|         |      1 theory Ind_Interface | 
|         |      2 imports "../Base" "../Parsing" Ind_Prelims Simple_Inductive_Package | 
|         |      3 begin | 
|         |      4  | 
|         |      5 section {* Parsing and Typing the Specification *} | 
|         |      6  | 
|         |      7 text {*  | 
|         |      8   To be able to write down the specification in Isabelle, we have to introduce | 
|         |      9   a new command (see Section~\ref{sec:newcommand}).  As the keyword for the | 
|         |     10   new command we chose \simpleinductive{}. In the package we want to support | 
|         |     11   some ``advanced'' features: First, we want that the package can cope with | 
|         |     12   specifications inside locales. For example it should be possible to declare | 
|         |     13 *} | 
|         |     14  | 
|         |     15 locale rel = | 
|         |     16   fixes R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" | 
|         |     17  | 
|         |     18 text {* | 
|         |     19   and then define the transitive closure and the accessible part as follows: | 
|         |     20 *} | 
|         |     21  | 
|         |     22  | 
|         |     23 simple_inductive (in rel)  | 
|         |     24   trcl'  | 
|         |     25 where | 
|         |     26   base: "trcl' x x" | 
|         |     27 | step: "trcl' x y \<Longrightarrow> R y z \<Longrightarrow> trcl' x z" | 
|         |     28  | 
|         |     29 simple_inductive (in rel)  | 
|         |     30   accpart' | 
|         |     31 where | 
|         |     32   accpartI: "(\<And>y. R y x \<Longrightarrow> accpart' y) \<Longrightarrow> accpart' x" | 
|         |     33  | 
|         |     34 text {*  | 
|         |     35   Second, we want that the user can specify fixed parameters. | 
|         |     36   Remember in the previous section we stated that the user can give the  | 
|         |     37   specification for the transitive closure of a relation @{text R} as  | 
|         |     38 *} | 
|         |     39  | 
|         |     40 simple_inductive | 
|         |     41   trcl\<iota>\<iota> :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" | 
|         |     42 where | 
|         |     43   base: "trcl\<iota>\<iota> R x x" | 
|         |     44 | step: "trcl\<iota>\<iota> R x y \<Longrightarrow> R y z \<Longrightarrow> trcl\<iota>\<iota> R x z" | 
|         |     45  | 
|         |     46 text {* | 
|         |     47   Note that there is no locale given in this specification---the parameter | 
|         |     48   @{text "R"} therefore needs to be included explicitly in @{term trcl\<iota>\<iota>}, but | 
|         |     49   stays fixed throughout the specification. The problem with this way of | 
|         |     50   stating the specification for the transitive closure is that it derives the | 
|         |     51   following induction principle. | 
|         |     52  | 
|         |     53   \begin{center}\small | 
|         |     54   \mprset{flushleft} | 
|         |     55   \mbox{\inferrule{ | 
|         |     56              @{thm_style prem1  trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}\\\\ | 
|         |     57              @{thm_style prem2  trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}\\\\ | 
|         |     58              @{thm_style prem3  trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}} | 
|         |     59             {@{thm_style concl  trcl\<iota>\<iota>.induct[where P=P, where z=R, where za=x, where zb=y]}}}   | 
|         |     60   \end{center} | 
|         |     61  | 
|         |     62   But this does not correspond to the induction principle we derived by hand, which | 
|         |     63   was | 
|         |     64    | 
|         |     65   \begin{center}\small | 
|         |     66   \mprset{flushleft} | 
|         |     67   \mbox{\inferrule{ | 
|         |     68              @{thm_style prem1  trcl_induct[no_vars]}\\\\ | 
|         |     69              @{thm_style prem2  trcl_induct[no_vars]}\\\\ | 
|         |     70              @{thm_style prem3  trcl_induct[no_vars]}} | 
|         |     71             {@{thm_style concl  trcl_induct[no_vars]}}}   | 
|         |     72   \end{center} | 
|         |     73  | 
|         |     74   The difference is that in the one derived by hand the relation @{term R} is not | 
|         |     75   a parameter of the proposition @{term P} to be proved and it is also not universally | 
|         |     76   qunatified in the second and third premise. The point is that the parameter @{term R} | 
|         |     77   stays fixed thoughout the definition and we do not want to regard it as an ``ordinary'' | 
|         |     78   argument of the transitive closure, but one that can be freely instantiated.  | 
|         |     79   In order to recognise such parameters, we have to extend the specification | 
|         |     80   to include a mechanism to state fixed parameters. The user should be able | 
|         |     81   to write  | 
|         |     82  | 
|         |     83 *} | 
|         |     84  | 
|         |     85 simple_inductive | 
|         |     86   trcl'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" | 
|         |     87 where | 
|         |     88   base: "trcl'' R x x" | 
|         |     89 | step: "trcl'' R x y \<Longrightarrow> R y z \<Longrightarrow> trcl'' R x z" | 
|         |     90  | 
|         |     91 simple_inductive | 
|         |     92   accpart'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool" | 
|         |     93 where | 
|         |     94   accpartI: "(\<And>y. R y x \<Longrightarrow> accpart'' R y) \<Longrightarrow> accpart'' R x" | 
|         |     95  | 
|         |     96 text {* | 
|         |     97   \begin{figure}[t] | 
|         |     98   \begin{isabelle} | 
|         |     99   \railnontermfont{\rmfamily\itshape} | 
|         |    100   \railterm{simpleinductive,where,for} | 
|         |    101   \railalias{simpleinductive}{\simpleinductive{}} | 
|         |    102   \railalias{where}{\isacommand{where}} | 
|         |    103   \railalias{for}{\isacommand{for}} | 
|         |    104   \begin{rail} | 
|         |    105   simpleinductive target? fixes (for fixes)? \\ | 
|         |    106   (where (thmdecl? prop + '|'))? | 
|         |    107   ; | 
|         |    108   \end{rail} | 
|         |    109   \end{isabelle} | 
|         |    110   \caption{A railroad diagram describing the syntax of \simpleinductive{}.  | 
|         |    111   The \emph{target} indicates an optional locale; the \emph{fixes} are an  | 
|         |    112   \isacommand{and}-separated list of names for the inductive predicates (they | 
|         |    113   can also contain typing- and syntax anotations); similarly the \emph{fixes}  | 
|         |    114   after \isacommand{for} to indicate fixed parameters; \emph{prop} stands for a  | 
|         |    115   introduction rule with an optional theorem declaration (\emph{thmdecl}). | 
|         |    116   \label{fig:railroad}} | 
|         |    117   \end{figure} | 
|         |    118 *} | 
|         |    119  | 
|         |    120 text {* | 
|         |    121   This leads directly to the railroad diagram shown in | 
|         |    122   Figure~\ref{fig:railroad} for the syntax of \simpleinductive{}. This diagram | 
|         |    123   more or less translates directly into the parser: | 
|         |    124  | 
|         |    125   @{ML_chunk [display,gray] parser} | 
|         |    126  | 
|         |    127   which we described in Section~\ref{sec:parsingspecs}. If we feed into the  | 
|         |    128   parser the string (which corresponds to our definition of @{term even} and  | 
|         |    129   @{term odd}): | 
|         |    130  | 
|         |    131   @{ML_response [display,gray] | 
|         |    132 "let | 
|         |    133   val input = filtered_input | 
|         |    134      (\"even and odd \" ^   | 
|         |    135       \"where \" ^ | 
|         |    136       \"  even0[intro]: \\\"even 0\\\" \" ^  | 
|         |    137       \"| evenS[intro]: \\\"odd n \<Longrightarrow> even (Suc n)\\\" \" ^  | 
|         |    138       \"| oddS[intro]:  \\\"even n \<Longrightarrow> odd (Suc n)\\\"\") | 
|         |    139 in | 
|         |    140   parse spec_parser input | 
|         |    141 end" | 
|         |    142 "(([(even, NONE, NoSyn), (odd, NONE, NoSyn)], | 
|         |    143      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"), | 
|         |    144       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^E\\^F\\^E\"), | 
|         |    145       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"} | 
|         |    146 *} | 
|         |    147  | 
|         |    148  | 
|         |    149 text {* | 
|         |    150   then we get back a locale (in this case @{ML NONE}), the predicates (with type | 
|         |    151   and syntax annotations), the parameters (similar as the predicates) and | 
|         |    152   the specifications of the introduction rules.  | 
|         |    153  | 
|         |    154  | 
|         |    155  | 
|         |    156   This is all the information we | 
|         |    157   need for calling the package and setting up the keyword. The latter is | 
|         |    158   done in Lines 6 and 7 in the code below. | 
|         |    159  | 
|         |    160   @{ML_chunk [display,gray,linenos] syntax} | 
|         |    161    | 
|         |    162   We call @{ML OuterSyntax.command} with the kind-indicator @{ML | 
|         |    163   OuterKeyword.thy_decl} since the package does not need to open up any goal | 
|         |    164   state (see Section~\ref{sec:newcommand}). Note that the predicates and | 
|         |    165   parameters are at the moment only some ``naked'' variables: they have no | 
|         |    166   type yet (even if we annotate them with types) and they are also no defined | 
|         |    167   constants yet (which the predicates will eventually be).  In Lines 1 to 4 we | 
|         |    168   gather the information from the parser to be processed further. The locale | 
|         |    169   is passed as argument to the function @{ML | 
|         |    170   Toplevel.local_theory}.\footnote{FIXME Is this already described?} The other | 
|         |    171   arguments, i.e.~the predicates, parameters and intro rule specifications, | 
|         |    172   are passed to the function @{ML add_inductive in SimpleInductivePackage} | 
|         |    173   (Line 4). | 
|         |    174  | 
|         |    175   We now come to the second subtask of the package, namely transforming the  | 
|         |    176   parser output into some internal datastructures that can be processed further.  | 
|         |    177   Remember that at the moment the introduction rules are just strings, and even | 
|         |    178   if the predicates and parameters can contain some typing annotations, they | 
|         |    179   are not yet in any way reflected in the introduction rules. So the task of | 
|         |    180   @{ML add_inductive in SimpleInductivePackage} is to transform the strings | 
|         |    181   into properly typed terms. For this it can use the function  | 
|         |    182   @{ML read_spec in Specification}. This function takes some constants | 
|         |    183   with possible typing annotations and some rule specifications and attempts to | 
|         |    184   find a type according to the given type constraints and the type constraints | 
|         |    185   by the surrounding (local theory). However this function is a bit | 
|         |    186   too general for our purposes: we want that each introduction rule has only  | 
|         |    187   name (for example @{text even0} or @{text evenS}), if a name is given at all. | 
|         |    188   The function @{ML read_spec in Specification} however allows more | 
|         |    189   than one rule. Since it is quite convenient to rely on this function (instead of | 
|         |    190   building your own) we just quick ly write a wrapper function that translates | 
|         |    191   between our specific format and the general format expected by  | 
|         |    192   @{ML read_spec in Specification}. The code of this wrapper is as follows: | 
|         |    193  | 
|         |    194   @{ML_chunk [display,gray,linenos] read_specification} | 
|         |    195  | 
|         |    196   It takes a list of constants, a list of rule specifications and a local theory  | 
|         |    197   as input. Does the transformation of the rule specifications in Line 3; calls | 
|         |    198   the function and transforms the now typed rule specifications back into our | 
|         |    199   format and returns the type parameter and typed rule specifications.  | 
|         |    200  | 
|         |    201  | 
|         |    202    @{ML_chunk [display,gray,linenos] add_inductive} | 
|         |    203  | 
|         |    204  | 
|         |    205   In order to add a new inductive predicate to a theory with the help of our | 
|         |    206   package, the user must \emph{invoke} it. For every package, there are | 
|         |    207   essentially two different ways of invoking it, which we will refer to as | 
|         |    208   \emph{external} and \emph{internal}. By external invocation we mean that the | 
|         |    209   package is called from within a theory document. In this case, the | 
|         |    210   specification of the inductive predicate, including type annotations and | 
|         |    211   introduction rules, are given as strings by the user. Before the package can | 
|         |    212   actually make the definition, the type and introduction rules have to be | 
|         |    213   parsed. In contrast, internal invocation means that the package is called by | 
|         |    214   some other package. For example, the function definition package | 
|         |    215   calls the inductive definition package to define the | 
|         |    216   graph of the function. However, it is not a good idea for the function | 
|         |    217   definition package to pass the introduction rules for the function graph to | 
|         |    218   the inductive definition package as strings. In this case, it is better to | 
|         |    219   directly pass the rules to the package as a list of terms, which is more | 
|         |    220   robust than handling strings that are lacking the additional structure of | 
|         |    221   terms. These two ways of invoking the package are reflected in its ML | 
|         |    222   programming interface, which consists of two functions: | 
|         |    223  | 
|         |    224  | 
|         |    225   @{ML_chunk [display,gray] SIMPLE_INDUCTIVE_PACKAGE} | 
|         |    226 *} | 
|         |    227  | 
|         |    228 text {* | 
|         |    229   (FIXME: explain Binding.binding; Attrib.binding somewhere else) | 
|         |    230  | 
|         |    231  | 
|         |    232   The function for external invocation of the package is called @{ML | 
|         |    233   add_inductive in SimpleInductivePackage}, whereas the one for internal | 
|         |    234   invocation is called @{ML add_inductive_i in SimpleInductivePackage}. Both | 
|         |    235   of these functions take as arguments the names and types of the inductive | 
|         |    236   predicates, the names and types of their parameters, the actual introduction | 
|         |    237   rules and a \emph{local theory}.  They return a local theory containing the | 
|         |    238   definition and the induction principle as well introduction rules.  | 
|         |    239  | 
|         |    240   Note that @{ML add_inductive_i in SimpleInductivePackage} expects | 
|         |    241   the types of the predicates and parameters to be specified using the | 
|         |    242   datatype @{ML_type typ} of Isabelle's logical framework, whereas @{ML | 
|         |    243   add_inductive in SimpleInductivePackage} expects them to be given as | 
|         |    244   optional strings. If no string is given for a particular predicate or | 
|         |    245   parameter, this means that the type should be inferred by the | 
|         |    246   package.  | 
|         |    247  | 
|         |    248  | 
|         |    249   Additional \emph{mixfix syntax} may be associated with the | 
|         |    250   predicates and parameters as well. Note that @{ML add_inductive_i in | 
|         |    251   SimpleInductivePackage} does not allow mixfix syntax to be associated with | 
|         |    252   parameters, since it can only be used for parsing.\footnote{FIXME: why ist it there then?}  | 
|         |    253   The names of the | 
|         |    254   predicates, parameters and rules are represented by the type @{ML_type | 
|         |    255   Binding.binding}. Strings can be turned into elements of the type @{ML_type | 
|         |    256   Binding.binding} using the function @{ML [display] "Binding.name : string -> | 
|         |    257   Binding.binding"} Each introduction rule is given as a tuple containing its | 
|         |    258   name, a list of \emph{attributes} and a logical formula. Note that the type | 
|         |    259   @{ML_type Attrib.binding} used in the list of introduction rules is just a | 
|         |    260   shorthand for the type @{ML_type "Binding.binding * Attrib.src list"}.  The | 
|         |    261   function @{ML add_inductive_i in SimpleInductivePackage} expects the formula | 
|         |    262   to be specified using the datatype @{ML_type term}, whereas @{ML | 
|         |    263   add_inductive in SimpleInductivePackage} expects it to be given as a string. | 
|         |    264   An attribute specifies additional actions and transformations that should be | 
|         |    265   applied to a theorem, such as storing it in the rule databases used by | 
|         |    266   automatic tactics like the simplifier. The code of the package, which will | 
|         |    267   be described in the following section, will mostly treat attributes as a | 
|         |    268   black box and just forward them to other functions for storing theorems in | 
|         |    269   local theories.  The implementation of the function @{ML add_inductive in | 
|         |    270   SimpleInductivePackage} for external invocation of the package is quite | 
|         |    271   simple. Essentially, it just parses the introduction rules and then passes | 
|         |    272   them on to @{ML add_inductive_i in SimpleInductivePackage}: | 
|         |    273  | 
|         |    274   @{ML_chunk [display] add_inductive} | 
|         |    275  | 
|         |    276   For parsing and type checking the introduction rules, we use the function | 
|         |    277    | 
|         |    278   @{ML [display] "Specification.read_specification: | 
|         |    279   (Binding.binding * string option * mixfix) list ->  (*{variables}*) | 
|         |    280   (Attrib.binding * string list) list ->  (*{rules}*) | 
|         |    281   local_theory -> | 
|         |    282   (((Binding.binding * typ) * mixfix) list * | 
|         |    283    (Attrib.binding * term list) list) * | 
|         |    284   local_theory"} | 
|         |    285 *} | 
|         |    286  | 
|         |    287 text {* | 
|         |    288   During parsing, both predicates and parameters are treated as variables, so | 
|         |    289   the lists \verb!preds_syn! and \verb!params_syn! are just appended | 
|         |    290   before being passed to @{ML read_spec in Specification}. Note that the format | 
|         |    291   for rules supported by @{ML read_spec in Specification} is more general than | 
|         |    292   what is required for our package. It allows several rules to be associated | 
|         |    293   with one name, and the list of rules can be partitioned into several | 
|         |    294   sublists. In order for the list \verb!intro_srcs! of introduction rules | 
|         |    295   to be acceptable as an input for @{ML read_spec in Specification}, we first | 
|         |    296   have to turn it into a list of singleton lists. This transformation | 
|         |    297   has to be reversed later on by applying the function | 
|         |    298   @{ML [display] "the_single: 'a list -> 'a"} | 
|         |    299   to the list \verb!specs! containing the parsed introduction rules. | 
|         |    300   The function @{ML read_spec in Specification} also returns the list \verb!vars! | 
|         |    301   of predicates and parameters that contains the inferred types as well. | 
|         |    302   This list has to be chopped into the two lists \verb!preds_syn'! and | 
|         |    303   \verb!params_syn'! for predicates and parameters, respectively. | 
|         |    304   All variables occurring in a rule but not in the list of variables passed to | 
|         |    305   @{ML read_spec in Specification} will be bound by a meta-level universal | 
|         |    306   quantifier. | 
|         |    307 *} | 
|         |    308  | 
|         |    309 text {* | 
|         |    310   Finally, @{ML read_specification in Specification} also returns another local theory, | 
|         |    311   but we can safely discard it. As an example, let us look at how we can use this | 
|         |    312   function to parse the introduction rules of the @{text trcl} predicate: | 
|         |    313  | 
|         |    314   @{ML_response [display] | 
|         |    315 "Specification.read_specification | 
|         |    316   [(Binding.name \"trcl\", NONE, NoSyn), | 
|         |    317    (Binding.name \"r\", SOME \"'a \<Rightarrow> 'a \<Rightarrow> bool\", NoSyn)] | 
|         |    318   [((Binding.name \"base\", []), [\"trcl r x x\"]), | 
|         |    319    ((Binding.name \"step\", []), [\"trcl r x y \<Longrightarrow> r y z \<Longrightarrow> trcl r x z\"])] | 
|         |    320   @{context}" | 
|         |    321 "((\<dots>, | 
|         |    322   [(\<dots>, | 
|         |    323     [Const (\"all\", \<dots>) $ Abs (\"x\", TFree (\"'a\", \<dots>), | 
|         |    324        Const (\"Trueprop\", \<dots>) $ | 
|         |    325          (Free (\"trcl\", \<dots>) $ Free (\"r\", \<dots>) $ Bound 0 $ Bound 0))]), | 
|         |    326    (\<dots>, | 
|         |    327     [Const (\"all\", \<dots>) $ Abs (\"x\", TFree (\"'a\", \<dots>), | 
|         |    328        Const (\"all\", \<dots>) $ Abs (\"y\", TFree (\"'a\", \<dots>), | 
|         |    329          Const (\"all\", \<dots>) $ Abs (\"z\", TFree (\"'a\", \<dots>), | 
|         |    330            Const (\"==>\", \<dots>) $ | 
|         |    331              (Const (\"Trueprop\", \<dots>) $ | 
|         |    332                (Free (\"trcl\", \<dots>) $ Free (\"r\", \<dots>) $ Bound 2 $ Bound 1)) $ | 
|         |    333              (Const (\"==>\", \<dots>) $ \<dots> $ \<dots>))))])]), | 
|         |    334  \<dots>) | 
|         |    335 : (((Binding.binding * typ) * mixfix) list * | 
|         |    336    (Attrib.binding * term list) list) * local_theory"} | 
|         |    337  | 
|         |    338   In the list of variables passed to @{ML read_specification in Specification}, we have | 
|         |    339   used the mixfix annotation @{ML NoSyn} to indicate that we do not want to associate any | 
|         |    340   mixfix syntax with the variable. Moreover, we have only specified the type of \texttt{r}, | 
|         |    341   whereas the type of \texttt{trcl} is computed using type inference. | 
|         |    342   The local variables \texttt{x}, \texttt{y} and \texttt{z} of the introduction rules | 
|         |    343   are turned into bound variables with the de Bruijn indices, | 
|         |    344   whereas \texttt{trcl} and \texttt{r} remain free variables. | 
|         |    345  | 
|         |    346 *} | 
|         |    347  | 
|         |    348 text {* | 
|         |    349  | 
|         |    350   \paragraph{Parsers for theory syntax} | 
|         |    351  | 
|         |    352   Although the function @{ML add_inductive in SimpleInductivePackage} parses terms and types, it still | 
|         |    353   cannot be used to invoke the package directly from within a theory document. | 
|         |    354   In order to do this, we have to write another parser. Before we describe | 
|         |    355   the process of writing parsers for theory syntax in more detail, we first | 
|         |    356   show some examples of how we would like to use the inductive definition | 
|         |    357   package. | 
|         |    358  | 
|         |    359  | 
|         |    360   The definition of the transitive closure should look as follows: | 
|         |    361 *} | 
|         |    362  | 
|         |    363 ML {* SpecParse.opt_thm_name *} | 
|         |    364  | 
|         |    365 text {* | 
|         |    366  | 
|         |    367   A proposition can be parsed using the function @{ML prop in OuterParse}. | 
|         |    368   Essentially, a proposition is just a string or an identifier, but using the | 
|         |    369   specific parser function @{ML prop in OuterParse} leads to more instructive | 
|         |    370   error messages, since the parser will complain that a proposition was expected | 
|         |    371   when something else than a string or identifier is found. | 
|         |    372   An optional locale target specification of the form \isa{(\isacommand{in}\ $\ldots$)} | 
|         |    373   can be parsed using @{ML opt_target in OuterParse}. | 
|         |    374   The lists of names of the predicates and parameters, together with optional | 
|         |    375   types and syntax, are parsed using the functions @{ML "fixes" in OuterParse} | 
|         |    376   and @{ML for_fixes in OuterParse}, respectively. | 
|         |    377   In addition, the following function from @{ML_struct SpecParse} for parsing | 
|         |    378   an optional theorem name and attribute, followed by a delimiter, will be useful: | 
|         |    379    | 
|         |    380   \begin{table} | 
|         |    381   @{ML "opt_thm_name: | 
|         |    382   string -> Attrib.binding parser" in SpecParse} | 
|         |    383   \end{table} | 
|         |    384  | 
|         |    385   We now have all the necessary tools to write the parser for our | 
|         |    386   \isa{\isacommand{simple{\isacharunderscore}inductive}} command: | 
|         |    387    | 
|         |    388   | 
|         |    389   Once all arguments of the command have been parsed, we apply the function | 
|         |    390   @{ML add_inductive in SimpleInductivePackage}, which yields a local theory | 
|         |    391   transformer of type @{ML_type "local_theory -> local_theory"}. Commands in | 
|         |    392   Isabelle/Isar are realized by transition transformers of type | 
|         |    393   @{ML_type [display] "Toplevel.transition -> Toplevel.transition"} | 
|         |    394   We can turn a local theory transformer into a transition transformer by using | 
|         |    395   the function | 
|         |    396  | 
|         |    397   @{ML [display] "Toplevel.local_theory : string option -> | 
|         |    398   (local_theory -> local_theory) -> | 
|         |    399   Toplevel.transition -> Toplevel.transition"} | 
|         |    400   | 
|         |    401   which, apart from the local theory transformer, takes an optional name of a locale | 
|         |    402   to be used as a basis for the local theory.  | 
|         |    403  | 
|         |    404   (FIXME : needs to be adjusted to new parser type) | 
|         |    405  | 
|         |    406   {\it | 
|         |    407   The whole parser for our command has type | 
|         |    408   @{text [display] "OuterLex.token list -> | 
|         |    409   (Toplevel.transition -> Toplevel.transition) * OuterLex.token list"} | 
|         |    410   which is abbreviated by @{text OuterSyntax.parser_fn}. The new command can be added | 
|         |    411   to the system via the function | 
|         |    412   @{text [display] "OuterSyntax.command : | 
|         |    413   string -> string -> OuterKeyword.T -> OuterSyntax.parser_fn -> unit"} | 
|         |    414   which imperatively updates the parser table behind the scenes. } | 
|         |    415  | 
|         |    416   In addition to the parser, this | 
|         |    417   function takes two strings representing the name of the command and a short description, | 
|         |    418   as well as an element of type @{ML_type OuterKeyword.T} describing which \emph{kind} of | 
|         |    419   command we intend to add. Since we want to add a command for declaring new concepts, | 
|         |    420   we choose the kind @{ML "OuterKeyword.thy_decl"}. Other kinds include | 
|         |    421   @{ML "OuterKeyword.thy_goal"}, which is similar to @{ML thy_decl in OuterKeyword}, | 
|         |    422   but requires the user to prove a goal before making the declaration, or | 
|         |    423   @{ML "OuterKeyword.diag"}, which corresponds to a purely diagnostic command that does | 
|         |    424   not change the context. For example, the @{ML thy_goal in OuterKeyword} kind is used | 
|         |    425   by the \isa{\isacommand{function}} command \cite{Krauss-IJCAR06}, which requires the user | 
|         |    426   to prove that a given set of equations is non-overlapping and covers all cases. The kind | 
|         |    427   of the command should be chosen with care, since selecting the wrong one can cause strange | 
|         |    428   behaviour of the user interface, such as failure of the undo mechanism. | 
|         |    429 *} | 
|         |    430  | 
|         |    431 text {* | 
|         |    432   Note that the @{text trcl} predicate has two different kinds of parameters: the | 
|         |    433   first parameter @{text R} stays \emph{fixed} throughout the definition, whereas | 
|         |    434   the second and third parameter changes in the ``recursive call''. This will | 
|         |    435   become important later on when we deal with fixed parameters and locales.  | 
|         |    436  | 
|         |    437  | 
|         |    438   | 
|         |    439   The purpose of the package we show next is that the user just specifies the | 
|         |    440   inductive predicate by stating some introduction rules and then the packages | 
|         |    441   makes the equivalent definition and derives from it the needed properties. | 
|         |    442 *} | 
|         |    443  | 
|         |    444 text {* | 
|         |    445   From a high-level perspective the package consists of 6 subtasks: | 
|         |    446  | 
|         |    447  | 
|         |    448  | 
|         |    449 *} | 
|         |    450  | 
|         |    451  | 
|         |    452 (*<*) | 
|         |    453 end | 
|         |    454 (*>*) |