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  | 
   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"  | 
   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 {* | 
   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   | 
   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} | 
   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  |