ProgTutorial/Package/Ind_Code.thy
changeset 295 24c68350d059
parent 294 ee9d53fbb56b
child 299 d0b81d6e1b28
equal deleted inserted replaced
294:ee9d53fbb56b 295:24c68350d059
    34 end*}
    34 end*}
    35 
    35 
    36 text {*
    36 text {*
    37   It returns the definition (as a theorem) and the local theory in which the
    37   It returns the definition (as a theorem) and the local theory in which the
    38   definition has been made. In Line 4, @{ML [index] internalK in Thm} is a flag
    38   definition has been made. In Line 4, @{ML [index] internalK in Thm} is a flag
    39   attached to the theorem (others possibile flags are @{ML [index] definitionK in Thm}
    39   attached to the theorem (other possibile flags are @{ML [index] definitionK in Thm}
    40   and @{ML [index] axiomK in Thm}). These flags just classify theorems and have no
    40   and @{ML [index] axiomK in Thm}). These flags just classify theorems and have no
    41   significant meaning, except for tools that, for example, find theorems in
    41   significant meaning, except for tools that, for example, find theorems in
    42   the theorem database.\footnote{FIXME: put in the section about theorems.} We
    42   the theorem database.\footnote{FIXME: put in the section about theorems.} We
    43   also use @{ML [index] empty_binding in Attrib} in Line 3, since the definitions for
    43   also use @{ML [index] empty_binding in Attrib} in Line 3, since the definitions for
    44   our inductive predicates are not meant to be seen by the user and therefore
    44   our inductive predicates are not meant to be seen by the user and therefore
   111   Line 13 we quantify over all predicates; and in line 14 we just abstract
   111   Line 13 we quantify over all predicates; and in line 14 we just abstract
   112   over all the @{text "zs"}, i.e., the fresh arguments of the
   112   over all the @{text "zs"}, i.e., the fresh arguments of the
   113   predicate. A testcase for this function is
   113   predicate. A testcase for this function is
   114 *}
   114 *}
   115 
   115 
   116 local_setup %gray{* fn lthy =>
   116 local_setup %gray {* fn lthy =>
   117 let
   117 let
   118   val def = defn_aux lthy eo_orules eo_preds (e_pred, e_arg_tys)
   118   val def = defn_aux lthy eo_orules eo_preds (e_pred, e_arg_tys)
   119 in
   119 in
   120   writeln (Syntax.string_of_term lthy def); lthy
   120   writeln (Syntax.string_of_term lthy def); lthy
   121 end *}
   121 end *}
   130                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   130                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   131 
   131 
   132   If we try out the function with the rules for freshness
   132   If we try out the function with the rules for freshness
   133 *}
   133 *}
   134 
   134 
   135 local_setup %gray{* fn lthy =>
   135 local_setup %gray {* fn lthy =>
   136  (writeln (Syntax.string_of_term lthy
   136 let
   137     (defn_aux lthy fresh_orules [fresh_pred] (fresh_pred, fresh_arg_tys)));
   137   val def = defn_aux lthy fresh_orules 
   138   lthy) *}
   138                              [fresh_pred] (fresh_pred, fresh_arg_tys)
       
   139 in
       
   140   writeln (Syntax.string_of_term lthy def); lthy
       
   141 end *}
       
   142 
   139 
   143 
   140 text {*
   144 text {*
   141   we obtain
   145   we obtain
   142 
   146 
   143   @{term [display] 
   147   @{term [display] 
   167 text {*
   171 text {*
   168   The user will state the introduction rules using meta-implications and
   172   The user will state the introduction rules using meta-implications and
   169   meta-quanti\-fications. In Line 4, we transform these introduction rules
   173   meta-quanti\-fications. In Line 4, we transform these introduction rules
   170   into the object logic (since definitions cannot be stated with
   174   into the object logic (since definitions cannot be stated with
   171   meta-connectives). To do this transformation we have to obtain the theory
   175   meta-connectives). To do this transformation we have to obtain the theory
   172   behind the local theory (Line 3); with this theory we can use the function
   176   behind the local theory using the function @{ML [index] theory_of in ProofContext} 
       
   177   (Line 3); with this theory we can use the function
   173   @{ML [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call
   178   @{ML [index] atomize_term in ObjectLogic} to make the transformation (Line 4). The call
   174   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   179   to @{ML defn_aux} in Line 5 produces all right-hand sides of the
   175   definitions. The actual definitions are then made in Line 7.  The result of
   180   definitions. The actual definitions are then made in Line 7.  The result of
   176   the function is a list of theorems and a local theory (the theorems are
   181   the function is a list of theorems and a local theory (the theorems are
   177   registered with the local theory). A testcase for this function is
   182   registered with the local theory). A testcase for this function is
   185   writeln (string_of_thms_no_vars lthy' defs); lthy
   190   writeln (string_of_thms_no_vars lthy' defs); lthy
   186 end *}
   191 end *}
   187 
   192 
   188 text {*
   193 text {*
   189   where we feed into the function all parameters corresponding to
   194   where we feed into the function all parameters corresponding to
   190   the @{text even}-@{text odd} example. The definitions we obtain
   195   the @{text even}/@{text odd} example. The definitions we obtain
   191   are:
   196   are:
   192 
   197 
   193   @{text [display, break]
   198   @{text [display, break]
   194 "even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n))  
   199 "even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n))  
   195                                 \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z,
   200                                 \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z,
   197                                \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> odd z"}
   202                                \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> odd z"}
   198 
   203 
   199   Note that in the testcase we return the local theory @{text lthy} 
   204   Note that in the testcase we return the local theory @{text lthy} 
   200   (not the modified @{text lthy'}). As a result the test case has no effect
   205   (not the modified @{text lthy'}). As a result the test case has no effect
   201   on the ambient theory. The reason is that if we introduce the
   206   on the ambient theory. The reason is that if we introduce the
   202   definition again, we pollute the name space with two versions of @{text "even"} 
   207   definition again, we pollute the name space with two versions of 
   203   and @{text "odd"}.
   208   @{text "even"} and @{text "odd"}. We want to avoid this here.
   204 
   209 
   205   This completes the code for introducing the definitions. Next we deal with
   210   This completes the code for introducing the definitions. Next we deal with
   206   the induction principles. 
   211   the induction principles. 
   207 *}
   212 *}
   208 
   213 
   232   The tactic will use the following helper function for instantiating universal 
   237   The tactic will use the following helper function for instantiating universal 
   233   quantifiers. 
   238   quantifiers. 
   234 *}
   239 *}
   235 
   240 
   236 ML{*fun inst_spec ctrm = 
   241 ML{*fun inst_spec ctrm = 
   237  Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   242   Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   238 
   243 
   239 text {*
   244 text {*
   240   This helper function instantiates the @{text "?x"} in the theorem 
   245   This helper function instantiates the @{text "?x"} in the theorem 
   241   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   246   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   242   in the following tactic, called @{text inst_spec_tac}\label{fun:instspectac}.
   247   in the following tactic.\label{fun:instspectac}.
   243 *}
   248 *}
   244 
   249 
   245 ML{*fun inst_spec_tac ctrms = 
   250 ML{*fun inst_spec_tac ctrms = 
   246   EVERY' (map (dtac o inst_spec) ctrms)*}
   251   EVERY' (map (dtac o inst_spec) ctrms)*}
   247 
   252 
   276           assume_tac]*}
   281           assume_tac]*}
   277 
   282 
   278 text {*
   283 text {*
   279   We have to give it as arguments the definitions, the premise (a list of
   284   We have to give it as arguments the definitions, the premise (a list of
   280   formulae) and the instantiations. The premise is @{text "even n"} in lemma
   285   formulae) and the instantiations. The premise is @{text "even n"} in lemma
   281   @{thm [source] manual_ind_prin_even}; in our code it will always be a list
   286   @{thm [source] manual_ind_prin_even} shown above; in our code it will always be a list
   282   consisting of a single formula. Compare this tactic with the manual proof
   287   consisting of a single formula. Compare this tactic with the manual proof
   283   for the lemma @{thm [source] manual_ind_prin_even}: as you can see there is
   288   for the lemma @{thm [source] manual_ind_prin_even}: as you can see there is
   284   almost a one-to-one correspondence between the \isacommand{apply}-script and
   289   almost a one-to-one correspondence between the \isacommand{apply}-script and
   285   the @{ML ind_tac}. Two testcases for this tactic are:
   290   the @{ML ind_tac}. We first rewrite the goal to use only object connectives (Line 2),
       
   291   "cut in" the premise (Line 3), unfold the definitions (Line 4), instantiate
       
   292   the assumptions of the goal (Line 5) and then conclude with @{ML assume_tac}.
       
   293 
       
   294   Two testcases for this tactic are:
   286 *}
   295 *}
   287 
   296 
   288 lemma automatic_ind_prin_even:
   297 lemma automatic_ind_prin_even:
   289 assumes prem: "even z"
   298 assumes prem: "even z"
   290 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   299 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   368   case that no introduction rules are given, the conclusion of this 
   377   case that no introduction rules are given, the conclusion of this 
   369   implication needs to be wrapped inside a @{term Trueprop}, otherwise 
   378   implication needs to be wrapped inside a @{term Trueprop}, otherwise 
   370   the Isabelle's goal mechanism will fail.\footnote{FIXME: check with 
   379   the Isabelle's goal mechanism will fail.\footnote{FIXME: check with 
   371   Stefan...is this so?} 
   380   Stefan...is this so?} 
   372 
   381 
   373   In Line 11 we set up the goal to be proved; in the next line we call the
   382   In Line 11 we set up the goal to be proved using the function @{ML [index]
   374   tactic for proving the induction principle. As mentioned before, this tactic
   383   prove in Goal}; in the next line we call the tactic for proving the
   375   expects the definitions, the premise and the (certified) predicates with
   384   induction principle. As mentioned before, this tactic expects the
   376   which the introduction rules have been substituted. The code in these two
   385   definitions, the premise and the (certified) predicates with which the
   377   lines will return a theorem. However, it is a theorem
   386   introduction rules have been substituted. The code in these two lines will
   378   proved inside the local theory @{text "lthy'"}, where the variables @{text
   387   return a theorem. However, it is a theorem proved inside the local theory
   379   "zs"} are free, but fixed (see Line 4). By exporting this theorem from @{text
   388   @{text "lthy'"}, where the variables @{text "zs"} are free, but fixed (see
   380   "lthy'"} (which contains the @{text "zs"} as free variables) to @{text
   389   Line 4). By exporting this theorem from @{text "lthy'"} (which contains the
   381   "lthy"} (which does not), we obtain the desired schematic variables @{text "?zs"}.
   390   @{text "zs"} as free variables) to @{text "lthy"} (which does not), we
   382   A testcase for this function is
   391   obtain the desired schematic variables @{text "?zs"}.  A testcase for this
   383 *}
   392   function is
   384 
   393 *}
   385 local_setup %gray{* fn lthy =>
   394 
       
   395 local_setup %gray {* fn lthy =>
   386 let
   396 let
   387   val newpreds = [@{term "P::nat\<Rightarrow>bool"}, @{term "Q::nat\<Rightarrow>bool"}]
   397   val newpreds = [@{term "P::nat \<Rightarrow> bool"}, @{term "Q::nat \<Rightarrow> bool"}]
   388   val cnewpreds = [@{cterm "P::nat\<Rightarrow>bool"}, @{cterm "Q::nat\<Rightarrow>bool"}]
   398   val cnewpreds = [@{cterm "P::nat \<Rightarrow> bool"}, @{cterm "Q::nat \<Rightarrow> bool"}]
   389   val newpred = @{term "P::nat\<Rightarrow>bool"}
   399   val newpred = @{term "P::nat \<Rightarrow> bool"}
   390   val srules =  map (subst_free (eo_preds ~~ newpreds)) eo_rules
   400   val srules =  map (subst_free (eo_preds ~~ newpreds)) eo_rules
   391   val intro = 
   401   val intro = 
   392       prove_ind lthy eo_defs srules cnewpreds ((e_pred, newpred), e_arg_tys)
   402       prove_ind lthy eo_defs srules cnewpreds ((e_pred, newpred), e_arg_tys)
   393 in
   403 in
   394   writeln (string_of_thm lthy intro); lthy
   404   writeln (string_of_thm lthy intro); lthy
   527   Similarly, the function @{ML imp_elims} eliminates preconditions from implications. 
   537   Similarly, the function @{ML imp_elims} eliminates preconditions from implications. 
   528   For example we can eliminate the preconditions @{text "A"} and @{text "B"} from
   538   For example we can eliminate the preconditions @{text "A"} and @{text "B"} from
   529   @{thm [source] imp_elims_test}:
   539   @{thm [source] imp_elims_test}:
   530 
   540 
   531   @{ML_response_fake [display, gray]
   541   @{ML_response_fake [display, gray]
   532 "writeln (string_of_thm_no_vars @{context} 
   542 "let
   533             (imp_elims @{thms imp_elims_test'} @{thm imp_elims_test}))"
   543   val res = imp_elims @{thms imp_elims_test'} @{thm imp_elims_test}
       
   544 in
       
   545   writeln (string_of_thm_no_vars @{context} res)
       
   546 end"
   534   "C"}
   547   "C"}
   535 
   548 
   536   Now we set up the proof for the introduction rule as follows:
   549   Now we set up the proof for the introduction rule as follows:
   537 *}
   550 *}
   538 
   551 
   550   ObjectLogic.rulify_tac 1
   563   ObjectLogic.rulify_tac 1
   551   THEN rewrite_goals_tac defs
   564   THEN rewrite_goals_tac defs
   552   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   565   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   553 
   566 
   554 text {*
   567 text {*
   555   The function in Line 2 ``rulifies'' the lemma. This will turn out to 
   568   The function in Line 2 ``rulifies'' the lemma.\footnote{FIXME: explain this better} 
       
   569   This will turn out to 
   556   be important later on. Applying this tactic in our proof of @{text "fresh_Lem"}
   570   be important later on. Applying this tactic in our proof of @{text "fresh_Lem"}
   557 *}
   571 *}
   558 
   572 
   559 (*<*)
   573 (*<*)
   560 lemma fresh_Lam:
   574 lemma fresh_Lam:
   579   differently. In the code below we will therefore separate them into @{text
   593   differently. In the code below we will therefore separate them into @{text
   580   "params1"} and @{text params2}, respectively @{text "prems1"} and @{text
   594   "params1"} and @{text params2}, respectively @{text "prems1"} and @{text
   581   "prems2"}. To do this separation, it is best to open a subproof with the
   595   "prems2"}. To do this separation, it is best to open a subproof with the
   582   tactic @{ML [index] SUBPROOF}, since this tactic provides us with the parameters (as
   596   tactic @{ML [index] SUBPROOF}, since this tactic provides us with the parameters (as
   583   list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). 
   597   list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). 
   584   The problem we have to overcome with @{ML SUBPROOF}
   598   The problem with @{ML SUBPROOF}, however, is that it always expects us to 
   585   is, however, that this tactic always expects us to completely discharge the
   599   completely discharge the goal (see Section~\ref{sec:simpletacs}). This is 
   586   goal (see Section~\ref{sec:simpletacs}). This is inconvenient for our
   600   a bit inconvenient for our gradual explanation of the proof here. Therefore
   587   gradual explanation of the proof here. To circumvent this inconvenience we
   601   we use first the function @{ML [index] FOCUS}, which does same as @{ML SUBPROOF} 
   588   use the following modified tactic:
   602   but does not require us to completely discharge the goal. 
   589 *}
   603 *}
   590 (*<*)oops(*>*)
   604 (*<*)oops(*>*)
   591 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
       
   592 
       
   593 text {*
       
   594   If the tactic inside @{ML SUBPROOF} fails, then the overall tactic will
       
   595   still succeed. With this testing tactic, we can gradually implement
       
   596   all necessary proof steps inside a subproof. Once we are finished, we
       
   597   just have to replace it with @{ML SUBPROOF}.
       
   598 *}
       
   599 
       
   600 text_raw {*
   605 text_raw {*
   601 \begin{figure}[t]
   606 \begin{figure}[t]
   602 \begin{minipage}{\textwidth}
   607 \begin{minipage}{\textwidth}
   603 \begin{isabelle}
   608 \begin{isabelle}
   604 *}
   609 *}
   609         @ ["Prems1 from the rule:"] @ (map (string_of_thm ctxt) prems1) 
   614         @ ["Prems1 from the rule:"] @ (map (string_of_thm ctxt) prems1) 
   610         @ ["Prems2 from the predicate:"] @ (map (string_of_thm ctxt) prems2) 
   615         @ ["Prems2 from the predicate:"] @ (map (string_of_thm ctxt) prems2) 
   611 in 
   616 in 
   612   s |> separate "\n"
   617   s |> separate "\n"
   613     |> implode
   618     |> implode
   614     |> writeln
   619     |> tracing
   615 end*}
   620 end*}
   616 text_raw{*
   621 text_raw{*
   617 \end{isabelle}
   622 \end{isabelle}
   618 \end{minipage}
   623 \end{minipage}
   619 \caption{A helper function that prints out the parameters and premises that
   624 \caption{A helper function that prints out the parameters and premises that
   623 
   628 
   624 text {*
   629 text {*
   625   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   630   First we calculate the values for @{text "params1/2"} and @{text "prems1/2"}
   626   from @{text "params"} and @{text "prems"}, respectively. To better see what is
   631   from @{text "params"} and @{text "prems"}, respectively. To better see what is
   627   going in our example, we will print out these values using the printing
   632   going in our example, we will print out these values using the printing
   628   function in Figure~\ref{fig:chopprint}. Since the tactic @{ML SUBPROOF} will
   633   function in Figure~\ref{fig:chopprint}. Since @{ML FOCUS} will
   629   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   634   supply us the @{text "params"} and @{text "prems"} as lists, we can 
   630   separate them using the function @{ML [index] chop}. 
   635   separate them using the function @{ML [index] chop}. 
   631 *}
   636 *}
   632 
   637 
   633 ML{*fun chop_test_tac preds rules =
   638 ML %linenosgray{*fun chop_test_tac preds rules =
   634   SUBPROOF_test (fn {params, prems, context, ...} =>
   639   FOCUS (fn {params, prems, context, ...} =>
   635   let
   640   let
   636     val (params1, params2) = chop (length params - length preds) (map snd params)
   641     val cparams = map snd params
       
   642     val (params1, params2) = chop (length cparams - length preds) cparams
   637     val (prems1, prems2) = chop (length prems - length rules) prems
   643     val (prems1, prems2) = chop (length prems - length rules) prems
   638   in
   644   in
   639     chop_print params1 params2 prems1 prems2 context; no_tac
   645     chop_print params1 params2 prems1 prems2 context; all_tac
   640   end) *}
   646   end) *}
   641 
   647 
   642 text {* 
   648 text {* 
   643   For the separation we can rely on the fact that Isabelle deterministically 
   649   For the separation we can rely on the fact that Isabelle deterministically 
   644   produces parameters and premises in a goal state. The last parameters
   650   produces parameters and premises in a goal state. The last parameters
   645   that were introduced come from the quantifications in the definitions
   651   that were introduced come from the quantifications in the definitions
   646   (see the tactic @{ML expand_tac}).
   652   (see the tactic @{ML expand_tac}).
   647   Therefore we only have to subtract the number of predicates (in this
   653   Therefore we only have to subtract in Line 5 the number of predicates (in this
   648   case only @{text "1"}) from the lenghts of all parameters. Similarly
   654   case only @{text "1"}) from the lenghts of all parameters. Similarly
   649   with the @{text "prems"}: the last premises in the goal state come from 
   655   with the @{text "prems"} in line 6: the last premises in the goal state come from 
   650   unfolding the definition of the predicate in the conclusion. So we can 
   656   unfolding the definition of the predicate in the conclusion. So we can 
   651   just subtract the number of rules from the number of all premises. 
   657   just subtract the number of rules from the number of all premises. 
   652   Applying this tactic in our example 
   658   To check our calculations we print them out in Line 8 using the
       
   659   function @{ML chop_print} from Figure~\ref{fig:chopprint} and then 
       
   660   just do nothing, that is @{ML all_tac}. Applying this tactic in our example 
   653 *}
   661 *}
   654 
   662 
   655 (*<*)
   663 (*<*)
   656 lemma fresh_Lam:
   664 lemma fresh_Lam:
   657 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   665 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   658 apply(tactic {* expand_tac @{thms fresh_def} *})
   666 apply(tactic {* expand_tac @{thms fresh_def} *})
   659 (*>*)
   667 (*>*)
   660 apply(tactic {* chop_test_tac [fresh_pred] fresh_rules @{context} *})
   668 apply(tactic {* chop_test_tac [fresh_pred] fresh_rules @{context} 1 *})
   661 (*<*)oops(*>*)
   669 (*<*)oops(*>*)
   662 
   670 
   663 text {*
   671 text {*
   664   gives
   672   gives
   665 
   673 
   689 
   697 
   690   @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"}
   698   @{term [display] "\<forall>a b t. a \<noteq> b \<longrightarrow> fresh a t \<longrightarrow> fresh a (Lam a t)"}
   691 
   699 
   692   To use this premise with @{ML rtac}, we need to instantiate its 
   700   To use this premise with @{ML rtac}, we need to instantiate its 
   693   quantifiers (with @{text params1}) and transform it into rule 
   701   quantifiers (with @{text params1}) and transform it into rule 
   694   format (using @{ML [index] rulify in ObjectLogic}. So we can modify the 
   702   format (using @{ML [index] rulify in ObjectLogic}). So we can modify the 
   695   subproof as follows:
   703   code as follows:
   696 *}
   704 *}
   697 
   705 
   698 ML %linenosgray{*fun apply_prem_tac i preds rules =
   706 ML %linenosgray{*fun apply_prem_tac i preds rules =
   699   SUBPROOF_test (fn {params, prems, context, ...} =>
   707   FOCUS (fn {params, prems, context, ...} =>
   700   let
   708   let
   701     val (params1, params2) = chop (length params - length preds) (map snd params)
   709     val cparams = map snd params
       
   710     val (params1, params2) = chop (length cparams - length preds) cparams
   702     val (prems1, prems2) = chop (length prems - length rules) prems
   711     val (prems1, prems2) = chop (length prems - length rules) prems
   703   in
   712   in
   704     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   713     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   705     THEN print_tac ""
       
   706     THEN no_tac
       
   707   end) *}
   714   end) *}
   708 
   715 
   709 text {* 
   716 text {* 
   710   The argument @{text i} corresponds to the number of the 
   717   The argument @{text i} corresponds to the number of the 
   711   introduction we want to prove. We will later on let it range
   718   introduction we want to prove. We will later on let it range
   717 (*<*)
   724 (*<*)
   718 lemma fresh_Lam:
   725 lemma fresh_Lam:
   719 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   726 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   720 apply(tactic {* expand_tac @{thms fresh_def} *})
   727 apply(tactic {* expand_tac @{thms fresh_def} *})
   721 (*>*)
   728 (*>*)
   722 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} *})
   729 apply(tactic {* apply_prem_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   723 (*<*)oops(*>*)
   730 (*<*)oops(*>*)
   724 
   731 
   725 text {*
   732 text {*
   726   Since we print out the goal state just after the application of 
   733   The goal state we obtain is: 
   727   @{ML rtac} (Line 8), we can see the goal state we obtain: 
       
   728 
   734 
   729   \begin{isabelle}
   735   \begin{isabelle}
   730   @{text "1."}~@{prop "a \<noteq> b"}\\
   736   @{text "1."}~@{text "\<dots> \<Longrightarrow> "}~@{prop "a \<noteq> b"}\\
   731   @{text "2."}~@{prop "fresh a t"}
   737   @{text "2."}~@{text "\<dots> \<Longrightarrow> "}~@{prop "fresh a t"}
   732   \end{isabelle}
   738   \end{isabelle}
   733 
   739 
   734   As expected there are two subgoals, where the first comes from the
   740   As expected there are two subgoals, where the first comes from the
   735   non-recursive premise of the introduction rule and the second comes 
   741   non-recursive premise of the introduction rule and the second comes 
   736   from the recursive one. The first goal can be solved immediately 
   742   from the recursive one. The first goal can be solved immediately 
   771 *}
   777 *}
   772 
   778 
   773 ML{*fun prove_intro_tac i preds rules =
   779 ML{*fun prove_intro_tac i preds rules =
   774   SUBPROOF (fn {params, prems, ...} =>
   780   SUBPROOF (fn {params, prems, ...} =>
   775   let
   781   let
   776     val (params1, params2) = chop (length params - length preds) (map snd params)
   782     val cparams = map snd params
       
   783     val (params1, params2) = chop (length cparams - length preds) cparams
   777     val (prems1, prems2) = chop (length prems - length rules) prems
   784     val (prems1, prems2) = chop (length prems - length rules) prems
   778   in
   785   in
   779     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   786     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   780     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   787     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   781   end) *}
   788   end) *}
   782 
   789 
   783 text {*
   790 text {*
   784   Note that the tactic is now @{ML SUBPROOF}, not @{ML SUBPROOF_test}. 
   791   Note that the tactic is now @{ML SUBPROOF}, not @{ML FOCUS} anymore. 
   785   The full proof of the introduction rule is as follows:
   792   The full proof of the introduction rule is as follows:
   786 *}
   793 *}
   787 
   794 
   788 lemma fresh_Lam:
   795 lemma fresh_Lam:
   789 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   796 shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   790 apply(tactic {* expand_tac @{thms fresh_def} *})
   797 apply(tactic {* expand_tac @{thms fresh_def} *})
   791 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   798 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   792 done
   799 done
   793 
   800 
   794 text {* 
   801 text {* 
   795   Phew!  ...Unfortunately, not everything is done yet. If you look closely
   802   Phew!\ldots  
       
   803 
       
   804   Unfortunately, not everything is done yet. If you look closely
   796   at the general principle outlined for the introduction rules in 
   805   at the general principle outlined for the introduction rules in 
   797   Section~\ref{sec:nutshell}, we have  not yet dealt with the case where 
   806   Section~\ref{sec:nutshell}, we have  not yet dealt with the case where 
   798   recursive premises have preconditions. The introduction rule
   807   recursive premises have preconditions. The introduction rule
   799   of the accessible part is such a rule. 
   808   of the accessible part is such a rule. 
   800 *}
   809 *}
   801 
   810 
   802 lemma accpartI:
   811 lemma accpartI:
   803 shows "\<And>R x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   812 shows "\<And>R x. (\<And>y. R y x \<Longrightarrow> accpart R y) \<Longrightarrow> accpart R x"
   804 apply(tactic {* expand_tac @{thms accpart_def} *})
   813 apply(tactic {* expand_tac @{thms accpart_def} *})
   805 apply(tactic {* chop_test_tac [acc_pred] acc_rules @{context} *})
   814 apply(tactic {* chop_test_tac [acc_pred] acc_rules @{context} 1 *})
   806 apply(tactic {* apply_prem_tac 0 [acc_pred] acc_rules @{context} *})
   815 apply(tactic {* apply_prem_tac 0 [acc_pred] acc_rules @{context} 1 *})
   807 
   816 
   808 txt {*
   817 txt {*
   809   Here @{ML chop_test_tac} prints out the following
   818   Here @{ML chop_test_tac} prints out the following
   810   values for @{text "params1/2"} and @{text "prems1/2"}
   819   values for @{text "params1/2"} and @{text "prems1/2"}
   811 
   820 
   866 *}
   875 *}
   867 
   876 
   868 ML %linenosgray{*fun prove_intro_tac i preds rules =
   877 ML %linenosgray{*fun prove_intro_tac i preds rules =
   869   SUBPROOF (fn {params, prems, context, ...} =>
   878   SUBPROOF (fn {params, prems, context, ...} =>
   870   let
   879   let
   871     val (params1, params2) = chop (length params - length preds) (map snd params)
   880     val cparams = map snd params
       
   881     val (params1, params2) = chop (length cparams - length preds) cparams
   872     val (prems1, prems2) = chop (length prems - length rules) prems
   882     val (prems1, prems2) = chop (length prems - length rules) prems
   873   in
   883   in
   874     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   884     rtac (ObjectLogic.rulify (all_elims params1 (nth prems2 i))) 1
   875     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   885     THEN EVERY1 (map (prepare_prem params2 prems2 context) prems1)
   876   end) *}
   886   end) *}
   950 
   960 
   951   For convenience, we use the following 
   961   For convenience, we use the following 
   952   three wrappers this function:
   962   three wrappers this function:
   953 *}
   963 *}
   954 
   964 
   955 ML{*fun reg_many qname ((name, attrs), thms) = 
   965 ML{*fun note_many qname ((name, attrs), thms) = 
   956   LocalTheory.note Thm.theoremK 
   966   LocalTheory.note Thm.theoremK 
   957     ((Binding.qualify false qname name, attrs), thms) 
   967     ((Binding.qualify false qname name, attrs), thms) 
   958 
   968 
   959 fun reg_single1 qname ((name, attrs), thm) = 
   969 fun note_single1 qname ((name, attrs), thm) = 
   960   reg_many qname ((name, attrs), [thm]) 
   970   note_many qname ((name, attrs), [thm]) 
   961 
   971 
   962 fun reg_single2 name attrs (qname, thm) = 
   972 fun note_single2 name attrs (qname, thm) = 
   963   reg_many (Binding.name_of qname) ((name, attrs), [thm]) *}
   973   note_many (Binding.name_of qname) ((name, attrs), [thm]) *}
   964 
   974 
   965 text {*
   975 text {*
   966   The function that ``holds everything together'' is @{text "add_inductive"}. 
   976   The function that ``holds everything together'' is @{text "add_inductive"}. 
   967   Its arguments are the specification of the predicates @{text "pred_specs"} 
   977   Its arguments are the specification of the predicates @{text "pred_specs"} 
   968   and the introduction rules @{text "rule_spec"}.   
   978   and the introduction rules @{text "rule_spec"}.   
   983   val intro_rules = intros rules preds defs lthy'
   993   val intro_rules = intros rules preds defs lthy'
   984 
   994 
   985   val mut_name = space_implode "_" (map Binding.name_of prednames)
   995   val mut_name = space_implode "_" (map Binding.name_of prednames)
   986   val case_names = map (Binding.name_of o fst) namesattrs
   996   val case_names = map (Binding.name_of o fst) namesattrs
   987 in
   997 in
   988   lthy' |> reg_many mut_name ((@{binding "intros"}, []), intro_rules) 
   998   lthy' |> note_many mut_name ((@{binding "intros"}, []), intro_rules) 
   989         ||>> reg_many mut_name ((@{binding "inducts"}, []), ind_prins)
   999         ||>> note_many mut_name ((@{binding "inducts"}, []), ind_prins)
   990         ||>> fold_map (reg_single1 mut_name) (namesattrs ~~ intro_rules)  
  1000         ||>> fold_map (note_single1 mut_name) (namesattrs ~~ intro_rules)  
   991         ||>> fold_map (reg_single2 @{binding "induct"} 
  1001         ||>> fold_map (note_single2 @{binding "induct"} 
   992               [Attrib.internal (K (RuleCases.case_names case_names)),
  1002               [Attrib.internal (K (RuleCases.case_names case_names)),
   993                Attrib.internal (K (RuleCases.consumes 1)),
  1003                Attrib.internal (K (RuleCases.consumes 1)),
   994                Attrib.internal (K (Induct.induct_pred ""))]) 
  1004                Attrib.internal (K (Induct.induct_pred ""))]) 
   995              (prednames ~~ ind_prins) 
  1005              (prednames ~~ ind_prins) 
   996         |> snd
  1006         |> snd