ProgTutorial/Package/Ind_Code.thy
changeset 212 ac01ddb285f6
parent 211 d5accbc67e1b
child 215 8d1a344a621e
equal deleted inserted replaced
211:d5accbc67e1b 212:ac01ddb285f6
     3 begin
     3 begin
     4 
     4 
     5 section {* The Gory Details\label{sec:code} *} 
     5 section {* The Gory Details\label{sec:code} *} 
     6 
     6 
     7 text {*
     7 text {*
     8   As mentioned before the code falls roughly into three parts: the definitions,
     8   As mentioned before the code falls roughly into three parts: code that deals 
     9   the induction principles and the introduction rules. In addition there is an 
     9   with the definitions, the induction principles and the introduction rules, respectively. 
    10   administrative function that strings everything together. 
    10   In addition there are some administrative functions that string everything together. 
    11 *}
    11 *}
    12 
    12 
    13 subsection {* Definitions *}
    13 subsection {* Definitions *}
    14 
    14 
    15 text {*
    15 text {*
   234  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}*}
   235 
   235 
   236 text {*
   236 text {*
   237   This helper function instantiates the @{text "?x"} in the theorem 
   237   This helper function instantiates the @{text "?x"} in the theorem 
   238   @{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
   239   in the next tactic, called @{text inst_spec_tac}.
   239   in the following tactic, called @{text inst_spec_tac}.
   240 *}
   240 *}
   241 
   241 
   242 ML{*fun inst_spec_tac ctrms = 
   242 ML{*fun inst_spec_tac ctrms = 
   243   EVERY' (map (dtac o inst_spec) ctrms)*}
   243   EVERY' (map (dtac o inst_spec) ctrms)*}
   244 
   244 
   245 text {*
   245 text {*
   246   This tactic expects a list of @{ML_type cterm}s. It allows us in the following 
   246   This tactic expects a list of @{ML_type cterm}s. It allows us in the 
   247   proof to instantiate the three quantifiers in the assumption. 
   247   proof below to instantiate the three quantifiers in the assumption. 
   248 *}
   248 *}
   249 
   249 
   250 lemma 
   250 lemma 
   251   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   251   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   252   shows "\<forall>x y z. P x y z \<Longrightarrow> True"
   252   shows "\<forall>x y z. P x y z \<Longrightarrow> True"
   253 apply (tactic {* 
   253 apply (tactic {* 
   254   inst_spec_tac  [@{cterm "a::nat"},@{cterm "b::nat"},@{cterm "c::nat"}] 1 *})
   254   inst_spec_tac [@{cterm "a::nat"},@{cterm "b::nat"},@{cterm "c::nat"}] 1 *})
   255 txt {* 
   255 txt {* 
   256   We obtain the goal state
   256   We obtain the goal state
   257 
   257 
   258   \begin{minipage}{\textwidth}
   258   \begin{minipage}{\textwidth}
   259   @{subgoals} 
   259   @{subgoals} 
   309   \end{isabelle}
   309   \end{isabelle}
   310 
   310 
   311   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   311   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   312   variables (since they are not quantified in the lemma). These schematic
   312   variables (since they are not quantified in the lemma). These schematic
   313   variables are needed so that they can be instantiated by the user. 
   313   variables are needed so that they can be instantiated by the user. 
   314   We have to take care to also generate these schematic variables when
   314   It will take a bit of work to generate these schematic variables when
   315   generating the goals for the induction principles.  In general we have 
   315   constructing the goals for the induction principles.  In general we have 
   316   to construct for each predicate @{text "pred"} a goal of the form
   316   to construct for each predicate @{text "pred"} a goal of the form
   317 
   317 
   318   @{text [display] 
   318   @{text [display] 
   319   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   319   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   320 
   320 
   321   where the predicates @{text preds} are replaced in @{text rules} by new 
   321   where the predicates @{text preds} are replaced in @{text rules} by new 
   322   distinct variables @{text "?Ps"}. We also need to generate fresh arguments 
   322   distinct variables @{text "?Ps"}. We also need to generate fresh arguments 
   323   @{text "?zs"} for the predicate  @{text "pred"} and the @{text "?P"} in 
   323   @{text "?zs"} for the predicate  @{text "pred"} and the @{text "?P"} in 
   324   the conclusion. The crucial point is that the  @{text "?Ps"} and 
   324   the conclusion. As just mentioned, the crucial point is that the  
   325   @{text "?zs"} need to be schematic variables that can be instantiated 
   325   @{text "?Ps"} and @{text "?zs"} need to be schematic variables that can 
   326   by the user.
   326   be instantiated by the user.
   327 
   327 
   328   We generate these goals in two steps. The first function, named @{text prove_ind}, 
   328   We generate these goals in two steps. The first function, named @{text prove_ind}, 
   329   expects that the introduction rules are already appropriately substituted. The argument
   329   expects that the introduction rules are already appropriately substituted. The argument
   330   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   330   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   331   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   331   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   350 end *}
   350 end *}
   351 
   351 
   352 text {* 
   352 text {* 
   353   In Line 3 we produce names @{text "zs"} for each type in the 
   353   In Line 3 we produce names @{text "zs"} for each type in the 
   354   argument type list. Line 4 makes these names unique and declares them as 
   354   argument type list. Line 4 makes these names unique and declares them as 
   355   \emph{free} (but fixed) variables in the local theory @{text "lthy'"}. 
   355   \emph{free but fixed} variables in the local theory @{text "lthy'"}. 
   356   That means they are not (yet) schematic variables.
   356   That means they are not schematic variables (yet).
   357   In Line 5 we construct the terms corresponding to these variables. 
   357   In Line 5 we construct the terms corresponding to these variables. 
   358   The variables are applied to the predicate in Line 7 (this corresponds
   358   The variables are applied to the predicate in Line 7 (this corresponds
   359   to the first premise @{text "pred zs"} of the induction principle). 
   359   to the first premise @{text "pred zs"} of the induction principle). 
   360   In Line 8 and 9, we first construct the term  @{text "P zs"} 
   360   In Line 8 and 9, we first construct the term  @{text "P zs"} 
   361   and then add the (substituted) introduction rules as premises. In case that
   361   and then add the (substituted) introduction rules as preconditions. In 
   362   no introduction rules are given, the conclusion of this implication needs
   362   case that no introduction rules are given, the conclusion of this 
   363   to be wrapped inside a @{term Trueprop}, otherwise the Isabelle's goal
   363   implication needs to be wrapped inside a @{term Trueprop}, otherwise 
   364   mechanism will fail. 
   364   the Isabelle's goal mechanism will fail.\footnote{FIXME: check with 
       
   365   Stefan...is this so?} 
   365 
   366 
   366   In Line 11 we set up the goal to be proved; in the next line we call the
   367   In Line 11 we set up the goal to be proved; in the next line we call the
   367   tactic for proving the induction principle. As mentioned before, this tactic
   368   tactic for proving the induction principle. As mentioned before, this tactic
   368   expects the definitions, the premise and the (certified) predicates with
   369   expects the definitions, the premise and the (certified) predicates with
   369   which the introduction rules have been substituted. The code in these two
   370   which the introduction rules have been substituted. The code in these two
   465 *}
   466 *}
   466 
   467 
   467 subsection {* Introduction Rules *}
   468 subsection {* Introduction Rules *}
   468 
   469 
   469 text {*
   470 text {*
   470   The proofs of the introduction rules are quite a bit
   471   Constructing the goals for the introduction rules is easy: they
   471   more involved than the ones for the induction principles. 
   472   are just the rules given by the user. However, their proofs are 
   472   To ease somewhat our work here, we use the following two helper
   473   quite a bit more involved than the ones for the induction principles. 
   473   functions.
   474   To explain the general method, our running example will be
   474 
   475   the introduction rule
       
   476 
       
   477   \begin{isabelle}
       
   478   @{prop "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"}
       
   479   \end{isabelle}
       
   480   
       
   481   about freshness for lambdas. In order to ease somewhat 
       
   482   our work here, we use the following two helper functions.
   475 *}
   483 *}
   476 
   484 
   477 ML{*val all_elims = fold (fn ct => fn th => th RS inst_spec ct)
   485 ML{*val all_elims = fold (fn ct => fn th => th RS inst_spec ct)
   478 val imp_elims = fold (fn th => fn th' => [th', th] MRS @{thm mp})*}
   486 val imp_elims = fold (fn th => fn th' => [th', th] MRS @{thm mp})*}
   479 
   487 
   480 text {* 
   488 text {* 
   481   To see what these functions do, let us suppose whe have the following three
   489   To see what these functions do, let us suppose we have the following three
   482   theorems. 
   490   theorems. 
   483 *}
   491 *}
   484 
   492 
   485 lemma all_elims_test:
   493 lemma all_elims_test:
   486   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   494   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
   513   @{ML_response_fake [display, gray]
   521   @{ML_response_fake [display, gray]
   514 "warning (str_of_thm_no_vars @{context} 
   522 "warning (str_of_thm_no_vars @{context} 
   515             (imp_elims @{thms imp_elims_test'} @{thm imp_elims_test}))"
   523             (imp_elims @{thms imp_elims_test'} @{thm imp_elims_test}))"
   516   "C"}
   524   "C"}
   517 
   525 
   518   To explain the proof for the introduction rule, our running example will be
   526   Now we set up the proof for the introduction rule as follows:
   519   the rule:
       
   520 
       
   521   \begin{isabelle}
       
   522   @{prop "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"}
       
   523   \end{isabelle}
       
   524   
       
   525   for freshness of applications. We set up the proof as follows:
       
   526 *}
   527 *}
   527 
   528 
   528 lemma fresh_Lam:
   529 lemma fresh_Lam:
   529   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   530   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   530 (*<*)oops(*>*)
   531 (*<*)oops(*>*)
   531 
   532 
   532 text {*
   533 text {*
   533   The first step will be to expand the definitions of freshness
   534   The first step in the proof will be to expand the definitions of freshness
   534   and then introduce quantifiers and implications. For this we
   535   and then introduce quantifiers and implications. For this we
   535   will use the tactic
   536   will use the tactic
   536 *}
   537 *}
   537 
   538 
   538 ML{*fun expand_tac defs =
   539 ML %linenosgray{*fun expand_tac defs =
   539   ObjectLogic.rulify_tac 1
   540   ObjectLogic.rulify_tac 1
   540   THEN rewrite_goals_tac defs
   541   THEN rewrite_goals_tac defs
   541   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   542   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   542 
   543 
   543 text {*
   544 text {*
   544   The first step of ``rulifying'' the lemma will turn out to be important
   545   The function in Line 2 ``rulifies'' the lemma. This will turn out to 
   545   later on. Applying this tactic 
   546   be important later on. Applying this tactic 
   546 *}
   547 *}
   547 
   548 
   548 (*<*)
   549 (*<*)
   549 lemma fresh_Lam:
   550 lemma fresh_Lam:
   550   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   551   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   560 
   561 
   561   As you can see, there are parameters (namely @{text "a"}, @{text "b"} 
   562   As you can see, there are parameters (namely @{text "a"}, @{text "b"} 
   562   and @{text "t"}) which come from the introduction rule and parameters
   563   and @{text "t"}) which come from the introduction rule and parameters
   563   (in the case above only @{text "fresh"}) which come from the universal
   564   (in the case above only @{text "fresh"}) which come from the universal
   564   quantification in the definition @{term "fresh a (App t s)"}.
   565   quantification in the definition @{term "fresh a (App t s)"}.
   565   Similarly, there are preconditions
   566   Similarly, there are assumptions
   566   that come from the premises of the rule and premises from the
   567   that come from the premises of the rule and assumptions from the
   567   definition. We need to treat these 
   568   definition of the predicate. We need to treat these 
   568   parameters and preconditions differently. In the code below
   569   parameters and assumptions differently. In the code below
   569   we will therefore separate them into @{text "params1"} and @{text params2},
   570   we will therefore separate them into @{text "params1"} and @{text params2},
   570   respectively @{text "prems1"} and @{text "prems2"}. To do this 
   571   respectively @{text "prems1"} and @{text "prems2"}. To do this 
   571   separation, it is best to open a subproof with the tactic 
   572   separation, it is best to open a subproof with the tactic 
   572   @{ML SUBPROOF}, since this tactic provides us
   573   @{ML SUBPROOF}, since this tactic provides us
   573   with the parameters (as list of @{ML_type cterm}s) and the premises
   574   with the parameters (as list of @{ML_type cterm}s) and the assumptions
   574   (as list of @{ML_type thm}s). The problem we have to overcome 
   575   (as list of @{ML_type thm}s called @{text prems}). The problem we have 
   575   with @{ML SUBPROOF} is, however, that this tactic always expects us to completely 
   576   to overcome with @{ML SUBPROOF} is, however, that this tactic always 
   576   discharge the goal (see Section~\ref{sec:simpletacs}). This is inconvenient for
   577   expects us to completely discharge the goal (see Section~\ref{sec:simpletacs}). 
   577   our gradual explanation of the proof here. To circumvent this inconvenience
   578   This is inconvenient for our gradual explanation of the proof here. To 
   578   we use the following modified tactic: 
   579   circumvent this inconvenience we use the following modified tactic: 
   579 *}
   580 *}
   580 (*<*)oops(*>*)
   581 (*<*)oops(*>*)
   581 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   582 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   582 
   583 
   583 text {*
   584 text {*
   584   If the tactic inside @{ML SUBPROOF} fails, then the overall tactic will
   585   If the tactic inside @{ML SUBPROOF} fails, then the overall tactic will
   585   still succeed. With this testing tactic, we can gradually implement
   586   still succeed. With this testing tactic, we can gradually implement
   586   all necessary proof steps inside a subproof.
   587   all necessary proof steps inside a subproof. Once we are finished, we
       
   588   just have to replace it with @{ML SUBPROOF}.
   587 *}
   589 *}
   588 
   590 
   589 text_raw {*
   591 text_raw {*
   590 \begin{figure}[t]
   592 \begin{figure}[t]
   591 \begin{minipage}{\textwidth}
   593 \begin{minipage}{\textwidth}
   610 \end{figure}
   612 \end{figure}
   611 *}
   613 *}
   612 
   614 
   613 text {*
   615 text {*
   614   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   616   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   615   from @{text "params"} and @{text "prems"}, respectively. To see what is
   617   from @{text "params"} and @{text "prems"}, respectively. To better see what is
   616   going in our example, we will print out the values using the printing
   618   going in our example, we will print out these values using the printing
   617   function in Figure~\ref{fig:chopprint}. Since the tactic @{ML SUBPROOF} will
   619   function in Figure~\ref{fig:chopprint}. Since the tactic @{ML SUBPROOF} will
   618   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   620   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   619   separate them using the function @{ML chop}. 
   621   separate them using the function @{ML chop}. 
   620 *}
   622 *}
   621 
   623 
   627   in
   629   in
   628     chop_print params1 params2 prems1 prems2 context; no_tac
   630     chop_print params1 params2 prems1 prems2 context; no_tac
   629   end) *}
   631   end) *}
   630 
   632 
   631 text {* 
   633 text {* 
   632   For the separation we can rely on that Isabelle deterministically 
   634   For the separation we can rely on the fact that Isabelle deterministically 
   633   produces parameter and premises in a goal state. The last parameters
   635   produces parameters and premises in a goal state. The last parameters
   634   that were introduced come from the quantifications in the definitions.
   636   that were introduced come from the quantifications in the definitions
       
   637   (see the tactic @{ML expand_tac}).
   635   Therefore we only have to subtract the number of predicates (in this
   638   Therefore we only have to subtract the number of predicates (in this
   636   case only @{text "1"}) from the lenghts of all parameters. Similarly
   639   case only @{text "1"}) from the lenghts of all parameters. Similarly
   637   with the @{text "prems"}: the last premises in the goal state come from 
   640   with the @{text "prems"}: the last premises in the goal state come from 
   638   unfolding the definition of the predicate in the conclusion. So we can 
   641   unfolding the definition of the predicate in the conclusion. So we can 
   639   just subtract the number of rules from the number of all premises. 
   642   just subtract the number of rules from the number of all premises. 
   673 
   676 
   674 
   677 
   675   We now have to select from @{text prems2} the premise 
   678   We now have to select from @{text prems2} the premise 
   676   that corresponds to the introduction rule we prove, namely:
   679   that corresponds to the introduction rule we prove, namely:
   677 
   680 
   678   @{term [display] "\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)"}
   681   @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"}
   679 
   682 
   680   To use this premise with @{ML rtac}, we need to instantiate its 
   683   To use this premise with @{ML rtac}, we need to instantiate its 
   681   quantifiers (with @{text params1}) and transform it into rule 
   684   quantifiers (with @{text params1}) and transform it into rule 
   682   format (using @{ML "ObjectLogic.rulify"}. So we can modify the 
   685   format (using @{ML "ObjectLogic.rulify"}. So we can modify the 
   683   subproof as follows:
   686   subproof as follows:
   684 *}
   687 *}
   685 
   688 
   686 ML{*fun apply_prem_tac i preds rules =
   689 ML %linenosgray{*fun apply_prem_tac i preds rules =
   687   SUBPROOF_test (fn {params, prems, context, ...} =>
   690   SUBPROOF_test (fn {params, prems, context, ...} =>
   688   let
   691   let
   689     val (params1, params2) = chop (length params - length preds) params
   692     val (params1, params2) = chop (length params - length preds) params
   690     val (prems1, prems2) = chop (length prems - length rules) prems
   693     val (prems1, prems2) = chop (length prems - length rules) prems
   691   in
   694   in
   694     THEN no_tac
   697     THEN no_tac
   695   end) *}
   698   end) *}
   696 
   699 
   697 text {* 
   700 text {* 
   698   The argument @{text i} corresponds to the number of the 
   701   The argument @{text i} corresponds to the number of the 
   699   introduction we want to analyse. We will later on lat it range
   702   introduction we want to prove. We will later on lat it range
   700   from @{text 0} to the number of introduction rules.
   703   from @{text 0} to the number of @{text "rules - 1"}.
   701   Below we applying this function with @{text 3}, since 
   704   Below we apply this function with @{text 3}, since 
   702   we are proving the fourth introduction rule. 
   705   we are proving the fourth introduction rule. 
   703 *}
   706 *}
   704 
   707 
   705 (*<*)
   708 (*<*)
   706 lemma fresh_Lam:
   709 lemma fresh_Lam:
   710 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} *})
   713 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} *})
   711 (*<*)oops(*>*)
   714 (*<*)oops(*>*)
   712 
   715 
   713 text {*
   716 text {*
   714   Since we print out the goal state just after the application of 
   717   Since we print out the goal state just after the application of 
   715   @{ML rtac}, we can see the goal state we obtain: as expected it has 
   718   @{ML rtac} (Line 8), we can see the goal state we obtain: 
   716   the two subgoals
       
   717 
   719 
   718   \begin{isabelle}
   720   \begin{isabelle}
   719   @{text "1."}~@{prop "a \<noteq> b"}\\
   721   @{text "1."}~@{prop "a \<noteq> b"}\\
   720   @{text "2."}~@{prop "fresh a t"}
   722   @{text "2."}~@{prop "fresh a t"}
   721   \end{isabelle}
   723   \end{isabelle}
   722 
   724 
   723   where the first comes from a non-recursive premise of the rule
   725   As expected there are two subgoals, where the first comes from a
   724   and the second comes from a recursive premise. The first goal
   726   non-recursive premise of the introduction rule and the second comes 
   725   can be solved immediately by @{text "prems1"}. The second
   727   from a recursive premise. The first goal can be solved immediately 
   726   needs more work. It can be solved with the other premise 
   728   by @{text "prems1"}. The second needs more work. It can be solved 
   727   in @{text "prems1"}, namely
   729   with the other premise in @{text "prems1"}, namely
       
   730 
   728 
   731 
   729   @{term [break,display]
   732   @{term [break,display]
   730   "\<forall>fresh.
   733   "\<forall>fresh.
   731       (\<forall>a b. a \<noteq> b \<longrightarrow> fresh a (Var b)) \<longrightarrow>
   734       (\<forall>a b. a \<noteq> b \<longrightarrow> fresh a (Var b)) \<longrightarrow>
   732       (\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   735       (\<forall>a t s. fresh a t \<longrightarrow> fresh a s \<longrightarrow> fresh a (App t s)) \<longrightarrow>
   735 
   738 
   736   but we have to instantiate it appropriately. These instantiations
   739   but we have to instantiate it appropriately. These instantiations
   737   come from @{text "params1"} and @{text "prems2"}. We can determine
   740   come from @{text "params1"} and @{text "prems2"}. We can determine
   738   whether we are in the simple or complicated case by checking whether
   741   whether we are in the simple or complicated case by checking whether
   739   the topmost connective is an @{text "\<forall>"}. The premises in the simple
   742   the topmost connective is an @{text "\<forall>"}. The premises in the simple
   740   case cannot have such a quantification, since in the first step 
   743   case cannot have such a quantification, since the first step 
   741   of @{ML "expand_tac"} was the ``rulification'' of the lemma. 
   744   of @{ML "expand_tac"} was to ``rulify'' the lemma. 
   742   The premise of the complicated case must have at least one  @{text "\<forall>"}
   745   The premise of the complicated case must have at least one  @{text "\<forall>"}
   743   coming from the quantification over the @{text preds}. So 
   746   coming from the quantification over the @{text preds}. So 
   744   we can implement the following function
   747   we can implement the following function
   745 *}
   748 *}
   746 
   749 
   767     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   770     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   768     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   771     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   769   end) *}
   772   end) *}
   770 
   773 
   771 text {*
   774 text {*
       
   775   Note that the tactic is now @{ML SUBPROOF}, not @{ML SUBPROOF_test}. 
   772   The full proof of the introduction rule now as follows:
   776   The full proof of the introduction rule now as follows:
   773 *}
   777 *}
   774 
   778 
   775 lemma fresh_Lam:
   779 lemma fresh_Lam:
   776   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   780   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   777 apply(tactic {* expand_tac @{thms fresh_def} *})
   781 apply(tactic {* expand_tac @{thms fresh_def} *})
   778 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   782 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   779 done
   783 done
   780 
   784 
   781 text {* 
   785 text {* 
   782   Unfortunately, not everything is done yet. If you look closely
   786   Phew!  Unfortunately, not everything is done yet. If you look closely
   783   at the general principle outlined in Section~\ref{sec:nutshell}, 
   787   at the general principle outlined for the introduction rules in 
   784   we have  not yet dealt with the case when recursive premises 
   788   Section~\ref{sec:nutshell}, we have  not yet dealt with the case where 
   785   in a rule have preconditions @{text Bs}. The introduction rule
   789   recursive premises have preconditions. The introduction rule
   786   of the accessible part is such a rule. 
   790   of the accessible part is such a rule. 
   787 *}
   791 *}
   788 
   792 
   789 lemma accpartI:
   793 lemma accpartI:
   790   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   794   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   816   
   820   
   817   
   821   
   818 *}(*<*)oops(*>*)
   822 *}(*<*)oops(*>*)
   819 
   823 
   820 text {*
   824 text {*
   821   In order to make progress as before, we have to use the precondition
   825   In order to make progress, we have to use the precondition
   822   @{text "R y x"} (in general there can be many of them). The best way
   826   @{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,
   827   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
   828   since the preconditions will then be bound to @{text prems}. Therfore we
   825   modify the function @{ML prepare_prem} as follows
   829   modify the function @{ML prepare_prem} as follows
   826 *}
   830 *}
   827 
   831 
   828 ML %linenosgray{*fun prepare_prem params2 prems2 ctxt prem =  
   832 ML %linenosgray{*fun prepare_prem params2 prems2 ctxt prem =  
   829   SUBPROOF (fn {prems, ...} =>
   833   SUBPROOF (fn {prems, ...} =>
   837          | _ => prem') 1
   841          | _ => prem') 1
   838   end) ctxt *}
   842   end) ctxt *}
   839 
   843 
   840 text {*
   844 text {*
   841   In Line 4 we use the @{text prems} from the @{ML SUBPROOF} and resolve 
   845   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} 
   846   them with @{text prem}. In the simple cases, that is where the @{text prem} 
   843   comes from a non-recursive premise of the rule, @{text prems} will be 
   847   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 
   848   just the empty list and the function @{ML MRS} does nothing. Similarly, in the 
   845   cases where the recursive premises of the rule do not have preconditions. 
   849   cases where the recursive premises of the rule do not have preconditions. 
       
   850   In case there are preconditions, then Line 4 discharges them. After
       
   851   that we can proceed as before, i.e., check whether the outermost
       
   852   connective is @{text "\<forall>"}.
   846   
   853   
   847   The function @{ML prove_intro_tac} only needs to give the context to
   854   The function @{ML prove_intro_tac} only needs to be changed so that it
   848   @{ML prepare_prem} (Line 8) and is as follows.
   855   gives the context to @{ML prepare_prem} (Line 8). The modified version
       
   856   is below.
   849 *}
   857 *}
   850 
   858 
   851 ML %linenosgray{*fun prove_intro_tac i preds rules =
   859 ML %linenosgray{*fun prove_intro_tac i preds rules =
   852   SUBPROOF (fn {params, prems, context, ...} =>
   860   SUBPROOF (fn {params, prems, context, ...} =>
   853   let
   861   let
   857     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   865     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   858     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   866     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   859   end) *}
   867   end) *}
   860 
   868 
   861 text {*
   869 text {*
   862   With these extended function we can also prove the introduction
   870   With these two functions we can now also prove the introduction
   863   rule for the accessible part. 
   871   rule for the accessible part. 
   864 *}
   872 *}
   865 
   873 
   866 lemma accpartI:
   874 lemma accpartI:
   867   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   875   shows "\<And>x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   880           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   888           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   881           prove_intro_tac i preds rules ctxt]*}
   889           prove_intro_tac i preds rules ctxt]*}
   882 
   890 
   883 text {*
   891 text {*
   884   Lines 2 to 4 correspond to the function @{ML expand_tac}. Some testcases
   892   Lines 2 to 4 correspond to the function @{ML expand_tac}. Some testcases
   885   dor this tactic are:
   893   for this tactic are:
   886 *}
   894 *}
   887 
   895 
   888 lemma even0_intro:
   896 lemma even0_intro:
   889   shows "even 0"
   897   shows "even 0"
   890 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *})
   898 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *})
   891 
       
   892 
   899 
   893 lemma evenS_intro:
   900 lemma evenS_intro:
   894   shows "\<And>m. odd m \<Longrightarrow> even (Suc m)"
   901   shows "\<And>m. odd m \<Longrightarrow> even (Suc m)"
   895 by (tactic {* intro_tac eo_defs eo_rules eo_preds 1 @{context} *})
   902 by (tactic {* intro_tac eo_defs eo_rules eo_preds 1 @{context} *})
   896 
   903 
   898   shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
   905   shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
   899 by (tactic {* 
   906 by (tactic {* 
   900   intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *})
   907   intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *})
   901 
   908 
   902 text {*
   909 text {*
   903   The second function sets up in Line 4 the goals (in this case this is easy
   910   The second function sets up in Line 4 the goals (this is easy
   904   since they are exactly the introduction rules the user gives)
   911   for the introduction rules since they are exactly the rules 
   905   and iterates @{ML intro_tac} over all introduction rules.
   912   given by the user) and iterates @{ML intro_tac} over all 
       
   913   introduction rules.
   906 *}
   914 *}
   907 
   915 
   908 ML %linenosgray{*fun intros rules preds defs lthy = 
   916 ML %linenosgray{*fun intros rules preds defs lthy = 
   909 let
   917 let
   910   fun intros_aux (i, goal) =
   918   fun intros_aux (i, goal) =
   911     Goal.prove lthy [] [] goal
   919     Goal.prove lthy [] [] goal
   912       (fn {context, ...} => intro_tac defs rules preds i context)
   920       (fn {context, ...} => intro_tac defs rules preds i context)
   913 in
   921 in
   914   map_index intros_aux rules
   922   map_index intros_aux rules
   915 end*}
   923 end*}
       
   924 
       
   925 text {*
       
   926   The iteration is done with the function @{ML map_index} since we
       
   927   need the introduction rule together with its number (counted from
       
   928   @{text 0}). This completes the code for the functions deriving the
       
   929   reasoning infrastructure. It remains to implement some administrative
       
   930   code that strings everything together.
       
   931 *}
   916 
   932 
   917 subsection {* Main Function *}
   933 subsection {* Main Function *}
   918 
   934 
   919 text {* main internal function *}
   935 text {* main internal function *}
   920 
   936