ProgTutorial/Package/Ind_Code.thy
changeset 211 d5accbc67e1b
parent 210 db8e302f44c8
child 212 ac01ddb285f6
equal deleted inserted replaced
210:db8e302f44c8 211:d5accbc67e1b
     1 theory Ind_Code
     1 theory Ind_Code
     2 imports "../Base" "../FirstSteps" Ind_General_Scheme 
     2 imports "../Base" "../FirstSteps" Ind_General_Scheme 
     3 begin
     3 begin
     4 
     4 
     5 section {* The Gory Details *} 
     5 section {* The Gory Details\label{sec:code} *} 
       
     6 
       
     7 text {*
       
     8   As mentioned before the code falls roughly into three parts: the definitions,
       
     9   the induction principles and the introduction rules. In addition there is an 
       
    10   administrative function that strings everything together. 
       
    11 *}
     6 
    12 
     7 subsection {* Definitions *}
    13 subsection {* Definitions *}
     8 
    14 
     9 text {*
    15 text {*
    10   We first have to produce for each predicate the definition, whose general form is
    16   We first have to produce for each predicate the definition, whose general form is
    45 end *}
    51 end *}
    46 
    52 
    47 text {*
    53 text {*
    48   which introduces the definition @{prop "MyTrue \<equiv> True"} and then prints it out. 
    54   which introduces the definition @{prop "MyTrue \<equiv> True"} and then prints it out. 
    49   Since we are testing the function inside \isacommand{local\_setup}, i.e., make
    55   Since we are testing the function inside \isacommand{local\_setup}, i.e., make
    50   changes to the ambient theory, we can query the definition with the usual
    56   actual changes to the ambient theory, we can query the definition with the usual
    51   command \isacommand{thm}:
    57   command \isacommand{thm}:
    52 
    58 
    53   \begin{isabelle}
    59   \begin{isabelle}
    54   \isacommand{thm}~@{text "MyTrue_def"}\\
    60   \isacommand{thm}~@{text "MyTrue_def"}\\
    55   @{text "> MyTrue \<equiv> True"}
    61   @{text "> MyTrue \<equiv> True"}
    63   When constructing them, the variables @{text "zs"} need to be chosen so that
    69   When constructing them, the variables @{text "zs"} need to be chosen so that
    64   they do not occur in the @{text orules} and also be distinct from the @{text
    70   they do not occur in the @{text orules} and also be distinct from the @{text
    65   "preds"}.
    71   "preds"}.
    66 
    72 
    67 
    73 
    68   The first function constructs the term for one particular predicate (the
    74   The first function, named @{text defn_aux}, constructs the term for one
    69   argument @{text "pred"} in the code belo). The number of arguments of this predicate is
    75   particular predicate (the argument @{text "pred"} in the code below). The
    70   determined by the number of argument types given in @{text "arg_tys"}. 
    76   number of arguments of this predicate is determined by the number of
    71   The other arguments are all the @{text "preds"} and the @{text "orules"}.
    77   argument types given in @{text "arg_tys"}. The other arguments of the
       
    78   function are the @{text orules} and all the @{text "preds"}.
    72 *}
    79 *}
    73 
    80 
    74 ML %linenosgray{*fun defn_aux lthy orules preds (pred, arg_tys) =
    81 ML %linenosgray{*fun defn_aux lthy orules preds (pred, arg_tys) =
    75 let 
    82 let 
    76   fun mk_all x P = HOLogic.all_const (fastype_of x) $ lambda x P
    83   fun mk_all x P = HOLogic.all_const (fastype_of x) $ lambda x P
    86   |> fold_rev mk_all preds
    93   |> fold_rev mk_all preds
    87   |> fold_rev lambda fresh_args 
    94   |> fold_rev lambda fresh_args 
    88 end*}
    95 end*}
    89 
    96 
    90 text {*
    97 text {*
    91   The function in Line 3 is just a helper function for constructing universal
    98   The function @{text mk_all} in Line 3 is just a helper function for constructing 
    92   quantifications. The code in Lines 5 to 9 produces the fresh @{text
    99   universal quantifications. The code in Lines 5 to 9 produces the fresh @{text
    93   "zs"}. For this it pairs every argument type with the string
   100   "zs"}. For this it pairs every argument type with the string
    94   @{text [quotes] "z"} (Line 7); then generates variants for all these strings
   101   @{text [quotes] "z"} (Line 7); then generates variants for all these strings
    95   so that they are unique w.r.t.~to the predicates and @{text "orules"} (Line 8);
   102   so that they are unique w.r.t.~to the predicates and @{text "orules"} (Line 8);
    96   in Line 9 it generates the corresponding variable terms for the unique
   103   in Line 9 it generates the corresponding variable terms for the unique
    97   strings.
   104   strings.
    98 
   105 
    99   The unique free variables are applied to the predicate (Line 11) using the
   106   The unique variables are applied to the predicate in Line 11 using the
   100   function @{ML list_comb}; then the @{text orules} are prefixed (Line 12); in
   107   function @{ML list_comb}; then the @{text orules} are prefixed (Line 12); in
   101   Line 13 we quantify over all predicates; and in line 14 we just abstract
   108   Line 13 we quantify over all predicates; and in line 14 we just abstract
   102   over all the @{text "zs"}, i.e., the fresh arguments of the
   109   over all the @{text "zs"}, i.e., the fresh arguments of the
   103   predicate. A testcase for this function is
   110   predicate. A testcase for this function is
   104 *}
   111 *}
   105 
   112 
   106 local_setup %gray{* fn lthy =>
   113 local_setup %gray{* fn lthy =>
   107 let
   114 let
   108   val pred = @{term "even::nat\<Rightarrow>bool"}
   115   val def = defn_aux lthy eo_orules eo_preds (e_pred, e_arg_tys)
   109   val arg_tys = [@{typ "nat"}]
       
   110   val def = defn_aux lthy eo_orules eo_preds (pred, arg_tys)
       
   111 in
   116 in
   112   warning (Syntax.string_of_term lthy def); lthy
   117   warning (Syntax.string_of_term lthy def); lthy
   113 end *}
   118 end *}
   114 
   119 
   115 text {*
   120 text {*
   116   The testcase  calls @{ML defn_aux} for the predicate @{text "even"} and prints
   121   where we use the shorthands defined in Figure~\ref{fig:shorthands}.
       
   122   The testcase calls @{ML defn_aux} for the predicate @{text "even"} and prints
   117   out the generated definition. So we obtain as printout 
   123   out the generated definition. So we obtain as printout 
   118 
   124 
   119   @{text [display] 
   125   @{text [display] 
   120 "\<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   126 "\<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   121                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   127                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   122 
   128 
   123   If we try out the function for the definition of freshness
   129   If we try out the function with the rules for freshness
   124 *}
   130 *}
   125 
   131 
   126 local_setup %gray{* fn lthy =>
   132 local_setup %gray{* fn lthy =>
   127  (warning (Syntax.string_of_term lthy
   133  (warning (Syntax.string_of_term lthy
   128     (defn_aux lthy fresh_orules [fresh_pred] (fresh_pred, fresh_arg_tys)));
   134     (defn_aux lthy fresh_orules [fresh_pred] (fresh_pred, fresh_arg_tys)));
   136                (\<forall>a s t. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   142                (\<forall>a s t. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   137                 (\<forall>a t. fresh a (Lam a t)) \<longrightarrow>
   143                 (\<forall>a t. fresh a (Lam a t)) \<longrightarrow>
   138                 (\<forall>a b t. \<not> a = b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh z za"}
   144                 (\<forall>a b t. \<not> a = b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh z za"}
   139 
   145 
   140 
   146 
   141   The second function for the definitions has to just iterate the function
   147   The second function, named @{text defns}, has to just iterate the function
   142   @{ML defn_aux} over all predicates. The argument @{text "preds"} is again
   148   @{ML defn_aux} over all predicates. The argument @{text "preds"} is again
   143   the the list of predicates as @{ML_type term}s; the argument @{text
   149   the the list of predicates as @{ML_type term}s; the argument @{text
   144   "prednames"} is the list of names of the predicates; @{text syns} are the
   150   "prednames"} is the list of binding names of the predicates; @{text syns} 
   145   syntax annotations for each predicate; @{text "arg_tyss"} is
   151   are the list of syntax annotations for the predicates; @{text "arg_tyss"} is
   146   the list of argument-type-lists for each predicate.
   152   the list of argument-type-lists.
   147 *}
   153 *}
   148 
   154 
   149 ML %linenosgray{*fun defns rules preds prednames syns arg_typss lthy =
   155 ML %linenosgray{*fun defns rules preds prednames syns arg_typss lthy =
   150 let
   156 let
   151   val thy = ProofContext.theory_of lthy
   157   val thy = ProofContext.theory_of lthy
   175 in
   181 in
   176   warning (str_of_thms_no_vars lthy' defs); lthy
   182   warning (str_of_thms_no_vars lthy' defs); lthy
   177 end *}
   183 end *}
   178 
   184 
   179 text {*
   185 text {*
   180   where we feed into the functions all parameters corresponding to
   186   where we feed into the function all parameters corresponding to
   181   the @{text even}-@{text odd} example. The definitions we obtain
   187   the @{text even}-@{text odd} example. The definitions we obtain
   182   are:
   188   are:
   183 
   189 
   184   @{text [display, break]
   190   @{text [display, break]
   185 "even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n))  
   191 "even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n))  
   228  Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   234  Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   229 
   235 
   230 text {*
   236 text {*
   231   This helper function instantiates the @{text "?x"} in the theorem 
   237   This helper function instantiates the @{text "?x"} in the theorem 
   232   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   238   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   233   in the tactic:
   239   in the next tactic, called @{text inst_spec_tac}.
   234 *}
   240 *}
   235 
   241 
   236 ML{*fun inst_spec_tac ctrms = 
   242 ML{*fun inst_spec_tac ctrms = 
   237   EVERY' (map (dtac o inst_spec) ctrms)*}
   243   EVERY' (map (dtac o inst_spec) ctrms)*}
   238 
   244 
   239 text {*
   245 text {*
   240   This tactic allows us to instantiate in the following proof the 
   246   This tactic expects a list of @{ML_type cterm}s. It allows us in the following 
   241   three quantifiers in the assumption. 
   247   proof to instantiate the three quantifiers in the assumption. 
   242 *}
   248 *}
   243 
   249 
   244 lemma 
   250 lemma 
   245   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   251   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   246   shows "\<forall>x y z. P x y z \<Longrightarrow> True"
   252   shows "\<forall>x y z. P x y z \<Longrightarrow> True"
   253   @{subgoals} 
   259   @{subgoals} 
   254   \end{minipage}*}
   260   \end{minipage}*}
   255 (*<*)oops(*>*)
   261 (*<*)oops(*>*)
   256 
   262 
   257 text {*
   263 text {*
   258   Now the complete tactic for proving the induction principles can 
   264   The complete tactic for proving the induction principles can now
   259   be implemented as follows:
   265   be implemented as follows:
   260 *}
   266 *}
   261 
   267 
   262 ML %linenosgray{*fun ind_tac defs prem insts =
   268 ML %linenosgray{*fun ind_tac defs prem insts =
   263   EVERY1 [ObjectLogic.full_atomize_tac,
   269   EVERY1 [ObjectLogic.full_atomize_tac,
   267           assume_tac]*}
   273           assume_tac]*}
   268 
   274 
   269 text {*
   275 text {*
   270   We have to give it as arguments the definitions, the premise (this premise
   276   We have to give it as arguments the definitions, the premise (this premise
   271   is @{text "even n"} in lemma @{thm [source] manual_ind_prin_even}) and the
   277   is @{text "even n"} in lemma @{thm [source] manual_ind_prin_even}) and the
   272   instantiations. Compare this tactic with the manual for the lemma @{thm
   278   instantiations. Compare this tactic with the manual proof for the lemma @{thm
   273   [source] manual_ind_prin_even}: as you can see there is almost a one-to-one
   279   [source] manual_ind_prin_even}: as you can see there is almost a one-to-one
   274   correspondence between the \isacommand{apply}-script and the @{ML
   280   correspondence between the \isacommand{apply}-script and the @{ML
   275   ind_tac}. Two testcases for this tactic are:
   281   ind_tac}. Two testcases for this tactic are:
   276 *}
   282 *}
   277 
   283 
   286 shows "(\<And>a b. a \<noteq> b \<Longrightarrow> P a (Var b)) \<Longrightarrow> 
   292 shows "(\<And>a b. a \<noteq> b \<Longrightarrow> P a (Var b)) \<Longrightarrow> 
   287         (\<And>a t s. \<lbrakk>P a t; P a s\<rbrakk> \<Longrightarrow> P a (App t s)) \<Longrightarrow>
   293         (\<And>a t s. \<lbrakk>P a t; P a s\<rbrakk> \<Longrightarrow> P a (App t s)) \<Longrightarrow>
   288         (\<And>a t. P a (Lam a t)) \<Longrightarrow> 
   294         (\<And>a t. P a (Lam a t)) \<Longrightarrow> 
   289         (\<And>a b t. \<lbrakk>a \<noteq> b; P a t\<rbrakk> \<Longrightarrow> P a (Lam b t)) \<Longrightarrow> P z za"
   295         (\<And>a b t. \<lbrakk>a \<noteq> b; P a t\<rbrakk> \<Longrightarrow> P a (Lam b t)) \<Longrightarrow> P z za"
   290 by (tactic {* ind_tac @{thms fresh_def} @{thms prem} 
   296 by (tactic {* ind_tac @{thms fresh_def} @{thms prem} 
   291                     [@{cterm "P::string\<Rightarrow>trm\<Rightarrow>bool"}] *})
   297                           [@{cterm "P::string\<Rightarrow>trm\<Rightarrow>bool"}] *})
   292 
   298 
   293 
   299 
   294 text {*
   300 text {*
   295   Let us have a closer look at the first proved theorem:
   301   While the tactic for proving the induction principles is relatively simple,
       
   302   it will be a bit of work to construct the goals from the introduction rules
       
   303   the user provides.  Therefore let us have a closer look at the first 
       
   304   proved theorem:
   296 
   305 
   297   \begin{isabelle}
   306   \begin{isabelle}
   298   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   307   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   299   @{text "> "}~@{thm automatic_ind_prin_even}
   308   @{text "> "}~@{thm automatic_ind_prin_even}
   300   \end{isabelle}
   309   \end{isabelle}
   301 
   310 
   302   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   311   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   303   variables (since they are not quantified in the lemma). These schematic
   312   variables (since they are not quantified in the lemma). These schematic
   304   variables are needed so that they can be instantiated by the user later
   313   variables are needed so that they can be instantiated by the user. 
   305   on. We have to take care to also generate these schematic variables when
   314   We have to take care to also generate these schematic variables when
   306   generating the goals for the induction principles. While the tactic for
   315   generating the goals for the induction principles.  In general we have 
   307   proving the induction principles is relatively simple, it will be a bit
   316   to construct for each predicate @{text "pred"} a goal of the form
   308   of work to construct the goals from the introduction rules the user
       
   309   provides. In general we have to construct for each predicate @{text "pred"}
       
   310   a goal of the form
       
   311 
   317 
   312   @{text [display] 
   318   @{text [display] 
   313   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   319   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   314 
   320 
   315   where the predicates @{text preds} are replaced in the introduction 
   321   where the predicates @{text preds} are replaced in @{text rules} by new 
   316   rules by new distinct variables @{text "?Ps"}.
   322   distinct variables @{text "?Ps"}. We also need to generate fresh arguments 
   317   We also need to generate fresh arguments @{text "?zs"} for the predicate 
   323   @{text "?zs"} for the predicate  @{text "pred"} and the @{text "?P"} in 
   318   @{text "pred"} and the @{text "?P"} in the conclusion. Note 
   324   the conclusion. The crucial point is that the  @{text "?Ps"} and 
   319   that the  @{text "?Ps"}  and @{text "?zs"} need to be
   325   @{text "?zs"} need to be schematic variables that can be instantiated 
   320   schematic variables that can be instantiated by the user.
   326   by the user.
   321 
   327 
   322   We generate these goals in two steps. The first function expects that the
   328   We generate these goals in two steps. The first function, named @{text prove_ind}, 
   323   introduction rules are already appropriately substituted. The argument
   329   expects that the introduction rules are already appropriately substituted. The argument
   324   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   330   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   325   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   331   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   326   "pred"} is the predicate for which we prove the induction principle;
   332   "pred"} is the predicate for which we prove the induction principle;
   327   @{text "newpred"} is its replacement and @{text "arg_tys"} are the argument
   333   @{text "newpred"} is its replacement and @{text "arg_tys"} are the argument
   328   types of this predicate.
   334   types of this predicate.
   361   tactic for proving the induction principle. As mentioned before, this tactic
   367   tactic for proving the induction principle. As mentioned before, this tactic
   362   expects the definitions, the premise and the (certified) predicates with
   368   expects the definitions, the premise and the (certified) predicates with
   363   which the introduction rules have been substituted. The code in these two
   369   which the introduction rules have been substituted. The code in these two
   364   lines will return a theorem. However, it is a theorem
   370   lines will return a theorem. However, it is a theorem
   365   proved inside the local theory @{text "lthy'"}, where the variables @{text
   371   proved inside the local theory @{text "lthy'"}, where the variables @{text
   366   "zs"} are fixed, but free (see Line 4). By exporting this theorem from @{text
   372   "zs"} are free, but fixed (see Line 4). By exporting this theorem from @{text
   367   "lthy'"} (which contains the @{text "zs"} as free variables) to @{text
   373   "lthy'"} (which contains the @{text "zs"} as free variables) to @{text
   368   "lthy"} (which does not), we obtain the desired schematic variables @{text "?zs"}.
   374   "lthy"} (which does not), we obtain the desired schematic variables @{text "?zs"}.
   369   A testcase for this function is
   375   A testcase for this function is
   370 *}
   376 *}
   371 
   377 
   372 local_setup %gray{* fn lthy =>
   378 local_setup %gray{* fn lthy =>
   373 let
   379 let
   374   val newpreds = [@{term "P::nat\<Rightarrow>bool"}, @{term "Q::nat\<Rightarrow>bool"}]
   380   val newpreds = [@{term "P::nat\<Rightarrow>bool"}, @{term "Q::nat\<Rightarrow>bool"}]
   375   val cnewpreds = [@{cterm "P::nat\<Rightarrow>bool"}, @{cterm "Q::nat\<Rightarrow>bool"}]
   381   val cnewpreds = [@{cterm "P::nat\<Rightarrow>bool"}, @{cterm "Q::nat\<Rightarrow>bool"}]
       
   382   val newpred = @{term "P::nat\<Rightarrow>bool"}
   376   val srules =  map (subst_free (eo_preds ~~ newpreds)) eo_rules
   383   val srules =  map (subst_free (eo_preds ~~ newpreds)) eo_rules
   377   val newpred = @{term "P::nat\<Rightarrow>bool"}
       
   378   val intro = 
   384   val intro = 
   379        prove_ind lthy eo_defs srules cnewpreds ((e_pred, newpred), e_arg_tys)
   385       prove_ind lthy eo_defs srules cnewpreds ((e_pred, newpred), e_arg_tys)
   380 in
   386 in
   381   warning (str_of_thm lthy intro); lthy
   387   warning (str_of_thm lthy intro); lthy
   382 end *}
   388 end *}
   383 
   389 
   384 text {*
   390 text {*
   392   variable @{text "?z"}; the variables @{text "P"} and @{text "Q"} are not yet
   398   variable @{text "?z"}; the variables @{text "P"} and @{text "Q"} are not yet
   393   schematic. 
   399   schematic. 
   394 
   400 
   395   We still have to produce the new predicates with which the introduction
   401   We still have to produce the new predicates with which the introduction
   396   rules are substituted and iterate @{ML prove_ind} over all
   402   rules are substituted and iterate @{ML prove_ind} over all
   397   predicates. This is what the second function does: 
   403   predicates. This is what the second function, named @{text inds} does. 
   398 *}
   404 *}
   399 
   405 
   400 ML %linenosgray{*fun inds rules defs preds arg_tyss lthy  =
   406 ML %linenosgray{*fun inds rules defs preds arg_tyss lthy  =
   401 let
   407 let
   402   val Ps = replicate (length preds) "P"
   408   val Ps = replicate (length preds) "P"
   416 end*}
   422 end*}
   417 
   423 
   418 text {*
   424 text {*
   419   In Line 3, we generate a string @{text [quotes] "P"} for each predicate. 
   425   In Line 3, we generate a string @{text [quotes] "P"} for each predicate. 
   420   In Line 4, we use the same trick as in the previous function, that is making the 
   426   In Line 4, we use the same trick as in the previous function, that is making the 
   421   @{text "Ps"} fresh and declaring them as fixed, but free, in
   427   @{text "Ps"} fresh and declaring them as free, but fixed, in
   422   the new local theory @{text "lthy'"}. From the local theory we extract
   428   the new local theory @{text "lthy'"}. From the local theory we extract
   423   the ambient theory in Line 6. We need this theory in order to certify 
   429   the ambient theory in Line 6. We need this theory in order to certify 
   424   the new predicates. In Line 8, we construct the types of these new predicates
   430   the new predicates. In Line 8, we construct the types of these new predicates
   425   using the given argument types. Next we turn them into terms and subsequently
   431   using the given argument types. Next we turn them into terms and subsequently
   426   certify them (Line 9 and 10). We can now produce the substituted introduction rules 
   432   certify them (Line 9 and 10). We can now produce the substituted introduction rules 
   517   \end{isabelle}
   523   \end{isabelle}
   518   
   524   
   519   for freshness of applications. We set up the proof as follows:
   525   for freshness of applications. We set up the proof as follows:
   520 *}
   526 *}
   521 
   527 
   522 lemma fresh_App:
   528 lemma fresh_Lam:
   523   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   529   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   524 (*<*)oops(*>*)
   530 (*<*)oops(*>*)
   525 
   531 
   526 text {*
   532 text {*
   527   The first step will be to expand the definitions of freshness
   533   The first step will be to expand the definitions of freshness
   533   ObjectLogic.rulify_tac 1
   539   ObjectLogic.rulify_tac 1
   534   THEN rewrite_goals_tac defs
   540   THEN rewrite_goals_tac defs
   535   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   541   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   536 
   542 
   537 text {*
   543 text {*
   538   The first step of ``rulifying'' the lemma will turn out important
   544   The first step of ``rulifying'' the lemma will turn out to be important
   539   later on. Applying this tactic 
   545   later on. Applying this tactic 
   540 *}
   546 *}
   541 
   547 
   542 (*<*)
   548 (*<*)
   543 lemma fresh_App:
   549 lemma fresh_Lam:
   544   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   550   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   545 (*>*)
   551 (*>*)
   546 apply(tactic {* expand_tac @{thms fresh_def} *})
   552 apply(tactic {* expand_tac @{thms fresh_def} *})
   547 
   553 
   548 txt {*
   554 txt {*
   564   respectively @{text "prems1"} and @{text "prems2"}. To do this 
   570   respectively @{text "prems1"} and @{text "prems2"}. To do this 
   565   separation, it is best to open a subproof with the tactic 
   571   separation, it is best to open a subproof with the tactic 
   566   @{ML SUBPROOF}, since this tactic provides us
   572   @{ML SUBPROOF}, since this tactic provides us
   567   with the parameters (as list of @{ML_type cterm}s) and the premises
   573   with the parameters (as list of @{ML_type cterm}s) and the premises
   568   (as list of @{ML_type thm}s). The problem we have to overcome 
   574   (as list of @{ML_type thm}s). The problem we have to overcome 
   569   with @{ML SUBPROOF} is that this tactic always expects us to completely 
   575   with @{ML SUBPROOF} is, however, that this tactic always expects us to completely 
   570   discharge with the goal (see Section ???). This is inconvenient for
   576   discharge the goal (see Section~\ref{sec:simpletacs}). This is inconvenient for
   571   our gradual explanation of the proof. To circumvent this inconvenience
   577   our gradual explanation of the proof here. To circumvent this inconvenience
   572   we use the following modified tactic: 
   578   we use the following modified tactic: 
   573 *}
   579 *}
   574 (*<*)oops(*>*)
   580 (*<*)oops(*>*)
   575 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   581 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   576 
   582 
   577 text {*
   583 text {*
   578   If the tactic inside @{ML SUBPROOF} fails, then the overall tactic will
   584   If the tactic inside @{ML SUBPROOF} fails, then the overall tactic will
   579   still succeed. With this testing tactic, we can gradually implement
   585   still succeed. With this testing tactic, we can gradually implement
   580   all necessary proof steps.
   586   all necessary proof steps inside a subproof.
   581 *}
   587 *}
   582 
   588 
   583 text_raw {*
   589 text_raw {*
   584 \begin{figure}[t]
   590 \begin{figure}[t]
   585 \begin{minipage}{\textwidth}
   591 \begin{minipage}{\textwidth}
   597     |> warning
   603     |> warning
   598 end*}
   604 end*}
   599 text_raw{*
   605 text_raw{*
   600 \end{isabelle}
   606 \end{isabelle}
   601 \end{minipage}
   607 \end{minipage}
   602 \caption{FIXME\label{fig:chopprint}}
   608 \caption{A helper function that prints out the parameters and premises that
       
   609   need to be treated differently.\label{fig:chopprint}}
   603 \end{figure}
   610 \end{figure}
   604 *}
   611 *}
   605 
   612 
   606 text {*
   613 text {*
   607   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   614   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   622   end) *}
   629   end) *}
   623 
   630 
   624 text {* 
   631 text {* 
   625   For the separation we can rely on that Isabelle deterministically 
   632   For the separation we can rely on that Isabelle deterministically 
   626   produces parameter and premises in a goal state. The last parameters
   633   produces parameter and premises in a goal state. The last parameters
   627   that were introduced, come from the quantifications in the definitions.
   634   that were introduced come from the quantifications in the definitions.
   628   Therefore we only have to subtract the number of predicates (in this
   635   Therefore we only have to subtract the number of predicates (in this
   629   case only @{text "1"} from the lenghts of all parameters. Similarly
   636   case only @{text "1"}) from the lenghts of all parameters. Similarly
   630   with the @{text "prems"}. The last premises in the goal state must
   637   with the @{text "prems"}: the last premises in the goal state come from 
   631   come from unfolding of the conclusion. So we can just subtract
   638   unfolding the definition of the predicate in the conclusion. So we can 
   632   the number of rules from the number of all premises. Applying
   639   just subtract the number of rules from the number of all premises. 
   633   this tactic in our example 
   640   Applying this tactic in our example 
   634 *}
   641 *}
   635 
   642 
   636 (*<*)
   643 (*<*)
   637 lemma fresh_App:
   644 lemma fresh_Lam:
   638   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   645   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   639 apply(tactic {* expand_tac @{thms fresh_def} *})
   646 apply(tactic {* expand_tac @{thms fresh_def} *})
   640 (*>*)
   647 (*>*)
   641 apply(tactic {* chop_test_tac [fresh_pred] fresh_rules @{context} *})
   648 apply(tactic {* chop_test_tac [fresh_pred] fresh_rules @{context} *})
   642 (*<*)oops(*>*)
   649 (*<*)oops(*>*)
   669   that corresponds to the introduction rule we prove, namely:
   676   that corresponds to the introduction rule we prove, namely:
   670 
   677 
   671   @{term [display] "\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)"}
   678   @{term [display] "\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)"}
   672 
   679 
   673   To use this premise with @{ML rtac}, we need to instantiate its 
   680   To use this premise with @{ML rtac}, we need to instantiate its 
   674   quantifiers (with @{text params1}) and transform it into a 
   681   quantifiers (with @{text params1}) and transform it into rule 
   675   introduction rule (using @{ML "ObjectLogic.rulify"}. 
   682   format (using @{ML "ObjectLogic.rulify"}. So we can modify the 
   676   So we can modify the subproof as follows:
   683   subproof as follows:
   677 *}
   684 *}
   678 
   685 
   679 ML{*fun apply_prem_tac i preds rules =
   686 ML{*fun apply_prem_tac i preds rules =
   680   SUBPROOF_test (fn {params, prems, context, ...} =>
   687   SUBPROOF_test (fn {params, prems, context, ...} =>
   681   let
   688   let
   685     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   692     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   686     THEN print_tac ""
   693     THEN print_tac ""
   687     THEN no_tac
   694     THEN no_tac
   688   end) *}
   695   end) *}
   689 
   696 
   690 text {* and apply it with *}
   697 text {* 
       
   698   The argument @{text i} corresponds to the number of the 
       
   699   introduction we want to analyse. We will later on lat it range
       
   700   from @{text 0} to the number of introduction rules.
       
   701   Below we applying this function with @{text 3}, since 
       
   702   we are proving the fourth introduction rule. 
       
   703 *}
   691 
   704 
   692 (*<*)
   705 (*<*)
   693 lemma fresh_App:
   706 lemma fresh_Lam:
   694   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   707   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   695 apply(tactic {* expand_tac @{thms fresh_def} *})
   708 apply(tactic {* expand_tac @{thms fresh_def} *})
   696 (*>*)
   709 (*>*)
   697 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} *})
   710 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} *})
   698 (*<*)oops(*>*)
   711 (*<*)oops(*>*)
   699 
   712 
   700 text {*
   713 text {*
   701   Since we print out the goal state after the @{ML rtac} we can see
   714   Since we print out the goal state just after the application of 
   702   the goal state has the two subgoals
   715   @{ML rtac}, we can see the goal state we obtain: as expected it has 
       
   716   the two subgoals
   703 
   717 
   704   \begin{isabelle}
   718   \begin{isabelle}
   705   @{text "1."}~@{prop "a \<noteq> b"}\\
   719   @{text "1."}~@{prop "a \<noteq> b"}\\
   706   @{text "2."}~@{prop "fresh a t"}
   720   @{text "2."}~@{prop "fresh a t"}
   707   \end{isabelle}
   721   \end{isabelle}
   708 
   722 
   709   where the first comes from a non-recursive precondition of the rule
   723   where the first comes from a non-recursive premise of the rule
   710   and the second comes from a recursive precondition. The first kind
   724   and the second comes from a recursive premise. The first goal
   711   can be solved immediately by @{text "prems1"}. The second kind
   725   can be solved immediately by @{text "prems1"}. The second
   712   needs more work. It can be solved with the other premise in @{text "prems1"},
   726   needs more work. It can be solved with the other premise 
   713   namely
   727   in @{text "prems1"}, namely
   714 
   728 
   715   @{term [break,display]
   729   @{term [break,display]
   716   "\<forall>fresh.
   730   "\<forall>fresh.
   717       (\<forall>a b. a \<noteq> b \<longrightarrow> fresh a (Var b)) \<longrightarrow>
   731       (\<forall>a b. a \<noteq> b \<longrightarrow> fresh a (Var b)) \<longrightarrow>
   718       (\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   732       (\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   720       (\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh a t"}
   734       (\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam b t)) \<longrightarrow> fresh a t"}
   721 
   735 
   722   but we have to instantiate it appropriately. These instantiations
   736   but we have to instantiate it appropriately. These instantiations
   723   come from @{text "params1"} and @{text "prems2"}. We can determine
   737   come from @{text "params1"} and @{text "prems2"}. We can determine
   724   whether we are in the simple or complicated case by checking whether
   738   whether we are in the simple or complicated case by checking whether
   725   the topmost connective is @{text "\<forall>"}. The premises in the simple
   739   the topmost connective is an @{text "\<forall>"}. The premises in the simple
   726   case cannot have such a quantification, since in the first step 
   740   case cannot have such a quantification, since in the first step 
   727   of @{ML "expand_tac"} was the ``rulification'' of the lemma. So 
   741   of @{ML "expand_tac"} was the ``rulification'' of the lemma. 
       
   742   The premise of the complicated case must have at least one  @{text "\<forall>"}
       
   743   coming from the quantification over the @{text preds}. So 
   728   we can implement the following function
   744   we can implement the following function
   729 *}
   745 *}
   730 
   746 
   731 ML{*fun prepare_prem params2 prems2 prem =  
   747 ML{*fun prepare_prem params2 prems2 prem =  
   732   rtac (case prop_of prem of
   748   rtac (case prop_of prem of
   734                  prem |> all_elims params2 
   750                  prem |> all_elims params2 
   735                       |> imp_elims prems2
   751                       |> imp_elims prems2
   736          | _ => prem) *}
   752          | _ => prem) *}
   737 
   753 
   738 text {* 
   754 text {* 
   739   which either applies the premise outright or if it had an
   755   which either applies the premise outright (the default case) or if 
   740   outermost universial quantification, instantiates it first with 
   756   it has an outermost universial quantification, instantiates it first 
   741   @{text "params1"} and then @{text "prems1"}. The following tactic 
   757   with  @{text "params1"} and then @{text "prems1"}. The following 
   742   will therefore prove the lemma.
   758   tactic will therefore prove the lemma completely.
   743 *}
   759 *}
   744 
   760 
   745 ML{*fun prove_intro_tac i preds rules =
   761 ML{*fun prove_intro_tac i preds rules =
   746   SUBPROOF (fn {params, prems, context, ...} =>
   762   SUBPROOF (fn {params, prems, ...} =>
   747   let
   763   let
   748     val (params1, params2) = chop (length params - length preds) params
   764     val (params1, params2) = chop (length params - length preds) params
   749     val (prems1, prems2) = chop (length prems - length rules) prems
   765     val (prems1, prems2) = chop (length prems - length rules) prems
   750   in
   766   in
   751     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   767     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   752     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   768     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   753   end) *}
   769   end) *}
   754 
   770 
   755 text {*
   771 text {*
   756   We can complete the proof of the introduction rule now as follows:
   772   The full proof of the introduction rule now as follows:
   757 *}
   773 *}
   758 
   774 
   759 (*<*)
   775 lemma fresh_Lam:
   760 lemma fresh_App:
       
   761   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   776   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   762 apply(tactic {* expand_tac @{thms fresh_def} *})
   777 apply(tactic {* expand_tac @{thms fresh_def} *})
   763 (*>*)
       
   764 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   778 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   765 done
   779 done
   766 
   780 
   767 text {* 
   781 text {* 
   768   Unfortunately, not everything is done yet.
   782   Unfortunately, not everything is done yet. If you look closely
       
   783   at the general principle outlined in Section~\ref{sec:nutshell}, 
       
   784   we have  not yet dealt with the case when recursive premises 
       
   785   in a rule have preconditions @{text Bs}. The introduction rule
       
   786   of the accessible part is such a rule. 
   769 *}
   787 *}
   770 
   788 
   771 lemma accpartI:
   789 lemma accpartI:
   772   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   790   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   773 apply(tactic {* expand_tac @{thms accpart_def} *})
   791 apply(tactic {* expand_tac @{thms accpart_def} *})
   774 apply(tactic {* chop_test_tac [acc_pred] acc_rules @{context} *})
   792 apply(tactic {* chop_test_tac [acc_pred] acc_rules @{context} *})
   775 apply(tactic {* apply_prem_tac 0 [acc_pred] acc_rules @{context} *})
   793 apply(tactic {* apply_prem_tac 0 [acc_pred] acc_rules @{context} *})
   776 
   794 
   777 txt {*
   795 txt {*
   778   
   796   Here @{ML chop_test_tac} prints out the following
   779   @{subgoals [display]}
   797   values for @{text "params1/2"} and @{text "prems1/2"}
   780 
   798 
   781   \begin{isabelle}
   799   \begin{isabelle}
   782   @{text "Params1 from the rule:"}\\
   800   @{text "Params1 from the rule:"}\\
   783   @{text "x"}\\
   801   @{text "x"}\\
   784   @{text "Params2 from the predicate:"}\\
   802   @{text "Params2 from the predicate:"}\\
   787   @{text "R ?y x \<Longrightarrow> \<forall>P. (\<forall>x. (\<forall>y. R y x \<longrightarrow> P y) \<longrightarrow> P x) \<longrightarrow> P ?y"}\\
   805   @{text "R ?y x \<Longrightarrow> \<forall>P. (\<forall>x. (\<forall>y. R y x \<longrightarrow> P y) \<longrightarrow> P x) \<longrightarrow> P ?y"}\\
   788   @{text "Prems2 from the predicate:"}\\
   806   @{text "Prems2 from the predicate:"}\\
   789   @{term "\<forall>x. (\<forall>y. R y x \<longrightarrow> P y) \<longrightarrow> P x"}\\
   807   @{term "\<forall>x. (\<forall>y. R y x \<longrightarrow> P y) \<longrightarrow> P x"}\\
   790   \end{isabelle}
   808   \end{isabelle}
   791 
   809 
   792 *}
   810   and after application of the introduction rule 
   793 (*<*)oops(*>*)
   811   using @{ML apply_prem_tac}, we are in the goal state
   794 
   812 
   795 
   813   \begin{isabelle}
   796 ML{*fun prepare_prem params2 prems2 ctxt prem =  
   814   @{text "1."}~@{term "\<And>y. R y x \<Longrightarrow> P y"}
       
   815   \end{isabelle}
       
   816   
       
   817   
       
   818 *}(*<*)oops(*>*)
       
   819 
       
   820 text {*
       
   821   In order to make progress as before, we have to use the precondition
       
   822   @{text "R y x"} (in general there can be many of them). The best way
       
   823   to get a handle on these preconditions is to open up another subproof,
       
   824   since the preconditions will be bound to @{text prems}. Therfore we
       
   825   modify the function @{ML prepare_prem} as follows
       
   826 *}
       
   827 
       
   828 ML %linenosgray{*fun prepare_prem params2 prems2 ctxt prem =  
   797   SUBPROOF (fn {prems, ...} =>
   829   SUBPROOF (fn {prems, ...} =>
   798   let
   830   let
   799     val prem' = prems MRS prem
   831     val prem' = prems MRS prem
   800   in 
   832   in 
   801     rtac (case prop_of prem' of
   833     rtac (case prop_of prem' of
   803                  prem' |> all_elims params2 
   835                  prem' |> all_elims params2 
   804                        |> imp_elims prems2
   836                        |> imp_elims prems2
   805          | _ => prem') 1
   837          | _ => prem') 1
   806   end) ctxt *}
   838   end) ctxt *}
   807 
   839 
   808 ML{*fun prove_intro_tac i preds rules =
   840 text {*
       
   841   In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve 
       
   842   them with @{text prem}. In the simple case, that is where the @{text prem} 
       
   843   comes from a non-recursive premise of the rule, @{text prems} will be 
       
   844   just the empty list and the @{ML MRS} does nothing. Similarly, in the 
       
   845   cases where the recursive premises of the rule do not have preconditions. 
       
   846   
       
   847   The function @{ML prove_intro_tac} only needs to give the context to
       
   848   @{ML prepare_prem} (Line 8) and is as follows.
       
   849 *}
       
   850 
       
   851 ML %linenosgray{*fun prove_intro_tac i preds rules =
   809   SUBPROOF (fn {params, prems, context, ...} =>
   852   SUBPROOF (fn {params, prems, context, ...} =>
   810   let
   853   let
   811     val (params1, params2) = chop (length params - length preds) params
   854     val (params1, params2) = chop (length params - length preds) params
   812     val (prems1, prems2) = chop (length prems - length rules) prems
   855     val (prems1, prems2) = chop (length prems - length rules) prems
   813   in
   856   in
   814     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   857     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   815     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   858     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   816   end) *}
   859   end) *}
   817 
   860 
       
   861 text {*
       
   862   With these extended function we can also prove the introduction
       
   863   rule for the accessible part. 
       
   864 *}
       
   865 
   818 lemma accpartI:
   866 lemma accpartI:
   819   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   867   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   820 apply(tactic {* expand_tac @{thms accpart_def} *})
   868 apply(tactic {* expand_tac @{thms accpart_def} *})
   821 apply(tactic {* prove_intro_tac 0 [acc_pred] acc_rules @{context} 1 *})
   869 apply(tactic {* prove_intro_tac 0 [acc_pred] acc_rules @{context} 1 *})
   822 done
   870 done
   823 
   871 
   824 
   872 text {*
   825 
   873   Finally we need two functions that string everything together. The first
   826 text {*
   874   function is the tactic that performs the proofs.
   827 
   875 *}
   828 *}
   876 
   829 
   877 ML %linenosgray{*fun intro_tac defs rules preds i ctxt =
   830 ML{*
       
   831 fun intros_tac defs rules preds i ctxt =
       
   832   EVERY1 [ObjectLogic.rulify_tac,
   878   EVERY1 [ObjectLogic.rulify_tac,
   833           K (rewrite_goals_tac defs),
   879           K (rewrite_goals_tac defs),
   834           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   880           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   835           prove_intro_tac i preds rules ctxt]*}
   881           prove_intro_tac i preds rules ctxt]*}
   836 
   882 
   837 text {*
   883 text {*
   838   A test case
   884   Lines 2 to 4 correspond to the function @{ML expand_tac}. Some testcases
   839 *}
   885   dor this tactic are:
   840 
   886 *}
   841 ML{*fun intros_tac_test ctxt i =
   887 
   842   intros_tac eo_defs eo_rules eo_preds i ctxt *}
   888 lemma even0_intro:
   843 
       
   844 lemma intro0:
       
   845   shows "even 0"
   889   shows "even 0"
   846 apply(tactic {* intros_tac_test @{context} 0 *})
   890 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *})
   847 done
   891 
   848 
   892 
   849 lemma intro1:
   893 lemma evenS_intro:
   850   shows "\<And>m. odd m \<Longrightarrow> even (Suc m)"
   894   shows "\<And>m. odd m \<Longrightarrow> even (Suc m)"
   851 apply(tactic {* intros_tac_test @{context} 1 *})
   895 by (tactic {* intro_tac eo_defs eo_rules eo_preds 1 @{context} *})
   852 done
   896 
   853 
   897 lemma fresh_App:
   854 lemma intro2:
   898   shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
   855   shows "\<And>m. even m \<Longrightarrow> odd (Suc m)"
   899 by (tactic {* 
   856 apply(tactic {* intros_tac_test @{context} 2 *})
   900   intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *})
   857 done
   901 
   858 
   902 text {*
   859 ML{*fun intros rules preds defs lthy = 
   903   The second function sets up in Line 4 the goals (in this case this is easy
       
   904   since they are exactly the introduction rules the user gives)
       
   905   and iterates @{ML intro_tac} over all introduction rules.
       
   906 *}
       
   907 
       
   908 ML %linenosgray{*fun intros rules preds defs lthy = 
   860 let
   909 let
   861   fun prove_intro (i, goal) =
   910   fun intros_aux (i, goal) =
   862     Goal.prove lthy [] [] goal
   911     Goal.prove lthy [] [] goal
   863       (fn {context, ...} => intros_tac defs rules preds i context)
   912       (fn {context, ...} => intro_tac defs rules preds i context)
   864 in
   913 in
   865   map_index prove_intro rules
   914   map_index intros_aux rules
   866 end*}
   915 end*}
   867 
   916 
       
   917 subsection {* Main Function *}
       
   918 
   868 text {* main internal function *}
   919 text {* main internal function *}
       
   920 
       
   921 ML {* LocalTheory.notes *}
       
   922 
   869 
   923 
   870 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   924 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   871 let
   925 let
   872   val syns = map snd pred_specs
   926   val syns = map snd pred_specs
   873   val pred_specs' = map fst pred_specs
   927   val pred_specs' = map fst pred_specs
   925 
   979 
   926 text {*
   980 text {*
   927   Things to include at the end:
   981   Things to include at the end:
   928 
   982 
   929   \begin{itemize}
   983   \begin{itemize}
       
   984   \item include the code for the parameters
   930   \item say something about add-inductive-i to return
   985   \item say something about add-inductive-i to return
   931   the rules
   986   the rules
   932   \item say that the induction principle is weaker (weaker than
   987   \item say that the induction principle is weaker (weaker than
   933   what the standard inductive package generates)
   988   what the standard inductive package generates)
   934   \item say that no conformity test is done
   989   \item say that no conformity test is done