ProgTutorial/Package/Ind_Interface.thy
changeset 222 1dc03eaa7cb9
parent 219 98d43270024f
child 224 647cab4a72c2
equal deleted inserted replaced
221:a9eb69749c93 222:1dc03eaa7cb9
     1 theory Ind_Interface
     1 theory Ind_Interface
     2 imports "../Base" "../Parsing" Ind_Prelims Simple_Inductive_Package
     2 imports "../Base" "../Parsing" Simple_Inductive_Package
     3 begin
     3 begin
     4 
     4 
     5 section {* Parsing and Typing the Specification *}
     5 section {* Parsing and Typing the Specification\label{sec:interface} *}
     6 
     6 
     7 text {* 
     7 text_raw {*
     8   To be able to write down the specification in Isabelle, we have to introduce
     8 \begin{figure}[p]
     9   a new command (see Section~\ref{sec:newcommand}).  As the keyword for the
     9 \begin{boxedminipage}{\textwidth}
    10   new command we chose \simpleinductive{}. In the package we want to support
    10 \begin{isabelle}
    11   some ``advanced'' features: First, we want that the package can cope with
    11 *}
    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
    12 simple_inductive
    41   trcl\<iota>\<iota> :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
    13   trcl :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"
    42 where
    14 where
    43   base: "trcl\<iota>\<iota> R x x"
    15   base: "trcl R x x"
    44 | step: "trcl\<iota>\<iota> R x y \<Longrightarrow> R y z \<Longrightarrow> trcl\<iota>\<iota> R x z"
    16 | step: "trcl R x y \<Longrightarrow> R y z \<Longrightarrow> trcl 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 
    17 
    85 simple_inductive
    18 simple_inductive
    86   trcl'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    19   even and odd
    87 where
    20 where
    88   base: "trcl'' R x x"
    21   even0: "even 0"
    89 | step: "trcl'' R x y \<Longrightarrow> R y z \<Longrightarrow> trcl'' R x z"
    22 | evenS: "odd n \<Longrightarrow> even (Suc n)"
       
    23 | oddS: "even n \<Longrightarrow> odd (Suc n)"
    90 
    24 
    91 simple_inductive
    25 simple_inductive
    92   accpart'' for R :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
    26   accpart :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> bool"
    93 where
    27 where
    94   accpartI: "(\<And>y. R y x \<Longrightarrow> accpart'' R y) \<Longrightarrow> accpart'' R x"
    28   accpartI: "(\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
    95 
    29 
    96 text {*
    30 (*<*)
    97   \begin{figure}[t]
    31 datatype trm =
       
    32   Var "string"
       
    33 | App "trm" "trm"
       
    34 | Lam "string" "trm"
       
    35 (*>*)
       
    36 
       
    37 simple_inductive 
       
    38   fresh :: "string \<Rightarrow> trm \<Rightarrow> bool" 
       
    39 where
       
    40   fresh_var: "a\<noteq>b \<Longrightarrow> fresh a (Var b)"
       
    41 | fresh_app: "\<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
       
    42 | fresh_lam1: "fresh a (Lam a t)"
       
    43 | fresh_lam2: "\<lbrakk>a\<noteq>b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
       
    44 text_raw {*
       
    45 \end{isabelle}
       
    46 \end{boxedminipage}
       
    47 \caption{Specification given by the user for the inductive predicates
       
    48 @{term "trcl"}, @{term "even"} and @{term "odd"}, @{term "accpart"} and 
       
    49 @{text "fresh"}.\label{fig:specs}}
       
    50 \end{figure}  
       
    51 *}
       
    52 
       
    53 text {*
       
    54   \begin{figure}[p]
       
    55   \begin{boxedminipage}{\textwidth}
    98   \begin{isabelle}
    56   \begin{isabelle}
    99   \railnontermfont{\rmfamily\itshape}
    57   \railnontermfont{\rmfamily\itshape}
   100   \railterm{simpleinductive,where,for}
    58   \railterm{simpleinductive,where,for}
   101   \railalias{simpleinductive}{\simpleinductive{}}
    59   \railalias{simpleinductive}{\simpleinductive{}}
   102   \railalias{where}{\isacommand{where}}
    60   \railalias{where}{\isacommand{where}}
   103   \railalias{for}{\isacommand{for}}
    61   \railalias{for}{\isacommand{for}}
   104   \begin{rail}
    62   \begin{rail}
   105   simpleinductive target? fixes (for fixes)? \\
    63   simpleinductive target?\\ fixes
   106   (where (thmdecl? prop + '|'))?
    64   (where (thmdecl? prop + '|'))?
   107   ;
    65   ;
   108   \end{rail}
    66   \end{rail}
   109   \end{isabelle}
    67   \end{isabelle}
       
    68   \end{boxedminipage}
   110   \caption{A railroad diagram describing the syntax of \simpleinductive{}. 
    69   \caption{A railroad diagram describing the syntax of \simpleinductive{}. 
   111   The \emph{target} indicates an optional locale; the \emph{fixes} are an 
    70   The \emph{target} indicates an optional locale; the \emph{fixes} are an 
   112   \isacommand{and}-separated list of names for the inductive predicates (they
    71   \isacommand{and}-separated list of names for the inductive predicates (they
   113   can also contain typing- and syntax anotations); similarly the \emph{fixes} 
    72   can also contain typing- and syntax anotations); \emph{prop} stands for a 
   114   after \isacommand{for} to indicate fixed parameters; \emph{prop} stands for a 
       
   115   introduction rule with an optional theorem declaration (\emph{thmdecl}).
    73   introduction rule with an optional theorem declaration (\emph{thmdecl}).
   116   \label{fig:railroad}}
    74   \label{fig:railroad}}
   117   \end{figure}
    75   \end{figure}
   118 *}
    76 *}
   119 
    77 
   120 text {*
    78 text {* 
   121   This leads directly to the railroad diagram shown in
    79   To be able to write down the specification in Isabelle, we have to introduce
   122   Figure~\ref{fig:railroad} for the syntax of \simpleinductive{}. This diagram
    80   a new command (see Section~\ref{sec:newcommand}).  As the keyword for the
   123   more or less translates directly into the parser:
    81   new command we chose \simpleinductive{}. Examples of specifications we expect
   124 
    82   the user gives for the inductive predicates from the previous section are
   125   @{ML_chunk [display,gray] parser}
    83   shown in Figure~ref{fig:specs}. The general syntax we will parse is specified
   126 
    84   in the railroad diagram shown in Figure~\ref{fig:railroad} for the syntax of 
   127   which we described in Section~\ref{sec:parsingspecs}. If we feed into the 
    85   \simpleinductive{}. This diagram more or less translates directly into 
       
    86   the parser:
       
    87 *}
       
    88 
       
    89 ML{*val spec_parser = 
       
    90    OuterParse.fixes -- 
       
    91    Scan.optional 
       
    92      (OuterParse.$$$ "where" |--
       
    93         OuterParse.!!! 
       
    94           (OuterParse.enum1 "|" 
       
    95              (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*}
       
    96 
       
    97 text {*
       
    98   which we explaind in Section~\ref{sec:parsingspecs}.
       
    99   If you look closely, there is no code for parsing the optional
       
   100   target in Figure~\ref{fig:railroad}. This is an ``advanced'' feature
       
   101   which we will inherit for ``free'' from the infrastructure on which
       
   102   we build the package. The target stands for a locale and allows us 
       
   103   to specify
       
   104 *}
       
   105 
       
   106 locale rel =
       
   107   fixes R :: "'a \<Rightarrow> 'a \<Rightarrow> bool"
       
   108 
       
   109 text {*
       
   110   and then define the transitive closure and the accessible part of this 
       
   111   locale as follows:
       
   112 *}
       
   113 
       
   114 simple_inductive (in rel) 
       
   115   trcl' 
       
   116 where
       
   117   base: "trcl' x x"
       
   118 | step: "trcl' x y \<Longrightarrow> R y z \<Longrightarrow> trcl' x z"
       
   119 
       
   120 simple_inductive (in rel) 
       
   121   accpart'
       
   122 where
       
   123   accpartI: "(\<And>y. R y x \<Longrightarrow> accpart' y) \<Longrightarrow> accpart' x"
       
   124 
       
   125 text {*
       
   126   Note that in these definitions the parameter @{text R} for the
       
   127   relation is left implicit.  If we feed into the 
   128   parser the string (which corresponds to our definition of @{term even} and 
   128   parser the string (which corresponds to our definition of @{term even} and 
   129   @{term odd}):
   129   @{term odd}):
   130 
   130 
   131   @{ML_response [display,gray]
   131   @{ML_response [display,gray]
   132 "let
   132 "let
   141 end"
   141 end"
   142 "(([(even, NONE, NoSyn), (odd, NONE, NoSyn)],
   142 "(([(even, NONE, NoSyn), (odd, NONE, NoSyn)],
   143      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   143      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   144       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^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\")]), [])"}
   145       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"}
   146 *}
   146 
   147 
   147   then we get back the predicates (with type
   148 
   148   and syntax annotations), and the specifications of the introduction 
   149 text {*
   149   rules. This is all the information we
   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
   150   need for calling the package and setting up the keyword. The latter is
   158   done in Lines 6 and 7 in the code below.
   151   done in Lines 6 and 7 in the code below.
   159 
   152 *}
   160   @{ML_chunk [display,gray,linenos] syntax}
   153 
   161   
   154 (*<*)
       
   155 ML{* fun add_inductive pred_specs rule_specs lthy = lthy *}
       
   156 (*>*)
       
   157 
       
   158 ML{*fun add_inductive_cmd pred_specs rule_specs lthy =
       
   159 let
       
   160   val ((pred_specs', rule_specs'), _) = 
       
   161          Specification.read_spec pred_specs rule_specs lthy
       
   162 in
       
   163   add_inductive pred_specs' rule_specs' lthy
       
   164 end*} 
       
   165 
       
   166 
       
   167 ML{*val specification =
       
   168   spec_parser >>
       
   169     (fn (pred_specs, rule_specs) => add_inductive_cmd pred_specs rule_specs)*}
       
   170 
       
   171 ML{*val _ = OuterSyntax.local_theory "simple_inductive" 
       
   172               "definition of simple inductive predicates"
       
   173                  OuterKeyword.thy_decl specification*}
       
   174 
       
   175 
       
   176 text {*
   162   We call @{ML OuterSyntax.command} with the kind-indicator @{ML
   177   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
   178   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
   179   state (see Section~\ref{sec:newcommand}). Note that the predicates and
   165   parameters are at the moment only some ``naked'' variables: they have no
   180   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
   181   type yet (even if we annotate them with types) and they are also no defined
   446 
   461 
   447   The point of these examples is to get a feeling what the automatic proofs 
   462   The point of these examples is to get a feeling what the automatic proofs 
   448   should do in order to solve all inductive definitions we throw at them. For this 
   463   should do in order to solve all inductive definitions we throw at them. For this 
   449   it is instructive to look at the general construction principle 
   464   it is instructive to look at the general construction principle 
   450   of inductive definitions, which we shall do in the next section.
   465   of inductive definitions, which we shall do in the next section.
   451 *}
   466 
   452 
   467   The code of the inductive package falls roughly in tree parts: the first
   453 
   468   deals with the definitions, the second with the induction principles and 
   454 (*<*)
   469   the third with the introduction rules. 
   455 end
   470   
   456 (*>*)
   471 *}
       
   472 (*<*)end(*>*)