CookBook/Package/Ind_Code.thy
changeset 184 c7f04a008c9c
parent 183 8bb4eaa2ec92
child 185 043ef82000b4
equal deleted inserted replaced
183:8bb4eaa2ec92 184:c7f04a008c9c
    53   (thm, lthy') 
    53   (thm, lthy') 
    54 end*}
    54 end*}
    55 
    55 
    56 text {*
    56 text {*
    57   It returns the definition (as a theorem) and the local theory in which this definition has 
    57   It returns the definition (as a theorem) and the local theory in which this definition has 
    58   been made. In Line 4 @{ML internalK in Thm} is just a flag attached to the 
    58   been made. In Line 4, @{ML internalK in Thm} is a flag attached to the 
    59   theorem (others possibilities are @{ML definitionK in Thm} and @{ML axiomK in Thm}). 
    59   theorem (others possibilities are @{ML definitionK in Thm} and @{ML axiomK in Thm}). 
    60   These flags just classify theorems and have no significant meaning, except 
    60   These flags just classify theorems and have no significant meaning, except 
    61   for tools that, for example, find theorems in the theorem database. We also
    61   for tools that, for example, find theorems in the theorem database. We also
    62   use @{ML empty_binding in Attrib} in Line 3, since the definition does 
    62   use @{ML empty_binding in Attrib} in Line 3, since the definition does 
    63   not need to have any theorem attributes. A testcase for this function is
    63   not need to have any theorem attributes. A testcase for this function is
    70 in
    70 in
    71   warning (str_of_thm lthy' def); lthy'
    71   warning (str_of_thm lthy' def); lthy'
    72 end *}
    72 end *}
    73 
    73 
    74 text {*
    74 text {*
    75   which makes the difinition @{prop "MyTrue \<equiv> True"} and then prints it out. 
    75   which makes the definition @{prop "MyTrue \<equiv> True"} and then prints it out. 
    76   Since we are testing the function inside \isacommand{local\_setup}, i.e.~make
    76   Since we are testing the function inside \isacommand{local\_setup}, i.e.~make
    77   changes to the ambient theory, we can query the definition using the usual
    77   changes to the ambient theory, we can query the definition using the usual
    78   command \isacommand{thm}:
    78   command \isacommand{thm}:
    79 
    79 
    80   \begin{isabelle}
    80   \begin{isabelle}
    81   \isacommand{thm}~@{text "MyTrue_def"}\\
    81   \isacommand{thm}~@{text "MyTrue_def"}\\
    82   @{text "> MyTrue \<equiv> True"}
    82   @{text "> MyTrue \<equiv> True"}
    83   \end{isabelle}
    83   \end{isabelle}
    84 
    84 
    85   The next two functions construct the terms we need for the definitions, namely 
    85   The next two functions construct the terms we need for the definitions for
    86   terms of the form 
    86   our \isacommand{simple\_inductive} command. These 
       
    87   terms are of the form 
    87 
    88 
    88   @{text [display] "\<lambda>\<^raw:$zs$>. \<forall>preds. orules \<longrightarrow> pred \<^raw:$zs$>"}
    89   @{text [display] "\<lambda>\<^raw:$zs$>. \<forall>preds. orules \<longrightarrow> pred \<^raw:$zs$>"}
    89 
    90 
    90   The variables @{text "\<^raw:$zs$>"} need to be chosen so that they do not occur
    91   The variables @{text "\<^raw:$zs$>"} need to be chosen so that they do not occur
    91   in the @{text orules} and also be distinct from @{text "preds"}. 
    92   in the @{text orules} and also be distinct from the @{text "preds"}. 
    92 
    93 
    93   The first function constructs the term for one particular predicate @{text
    94   The first function constructs the term for one particular predicate, say
    94   "pred"}; the number of arguments @{text "\<^raw:$zs$>"} of this predicate is
    95   @{text "pred"}; the number of arguments of this predicate is
    95   determined by the number of argument types of @{text "arg_tys"}.
    96   determined by the number of argument types of @{text "arg_tys"}. 
       
    97   So it takes these two parameters as arguments. The other arguments are
       
    98   all the @{text "preds"} and the @{text "orules"}.
    96 *}
    99 *}
    97 
   100 
    98 ML %linenosgray{*fun defs_aux lthy orules preds (pred, arg_tys) =
   101 ML %linenosgray{*fun defs_aux lthy orules preds (pred, arg_tys) =
    99 let 
   102 let 
   100   fun mk_all x P = HOLogic.all_const (fastype_of x) $ lambda x P
   103   fun mk_all x P = HOLogic.all_const (fastype_of x) $ lambda x P
   110   |> fold_rev mk_all preds
   113   |> fold_rev mk_all preds
   111   |> fold_rev lambda fresh_args 
   114   |> fold_rev lambda fresh_args 
   112 end*}
   115 end*}
   113 
   116 
   114 text {*
   117 text {*
   115   The code in Lines 5 to 9 produce the fresh @{text "\<^raw:$zs$>"}. For this
   118   The function in Line 3 is just a helper function for constructing universal
   116   it pairs every argument type with the string @{text [quotes] "z"} (Line 7);
   119   quantifications. The code in Lines 5 to 9 produces the fresh @{text
   117   then generates variants for all these strings so that they are unique
   120   "\<^raw:$zs$>"}. For this it pairs every argument type with the string
   118   w.r.t.~to the @{text "orules"} and the predicates; in Line 9 it generates the
   121   @{text [quotes] "z"} (Line 7); then generates variants for all these strings
   119   corresponding variable terms for the unique strings.
   122   so that they are unique w.r.t.~to the @{text "orules"} and the predicates;
       
   123   in Line 9 it generates the corresponding variable terms for the unique
       
   124   strings.
   120 
   125 
   121   The unique free variables are applied to the predicate (Line 11) using the
   126   The unique free variables are applied to the predicate (Line 11) using the
   122   function @{ML list_comb}; then the @{text orules} are prefixed (Line 12); in
   127   function @{ML list_comb}; then the @{text orules} are prefixed (Line 12); in
   123   Line 13 we quantify over all predicates; and in line 14 we just abstract
   128   Line 13 we quantify over all predicates; and in line 14 we just abstract
   124   over all the @{text "\<^raw:$zs$>"}, i.e.~the fresh arguments of the
   129   over all the @{text "\<^raw:$zs$>"}, i.e.~the fresh arguments of the
   130 local_setup %gray{* fn lthy =>
   135 local_setup %gray{* fn lthy =>
   131 let
   136 let
   132   val orules = [@{prop "even 0"},
   137   val orules = [@{prop "even 0"},
   133                 @{prop "\<forall>n::nat. odd n \<longrightarrow> even (Suc n)"},
   138                 @{prop "\<forall>n::nat. odd n \<longrightarrow> even (Suc n)"},
   134                 @{prop "\<forall>n::nat. even n \<longrightarrow> odd (Suc n)"}] 
   139                 @{prop "\<forall>n::nat. even n \<longrightarrow> odd (Suc n)"}] 
   135   val preds = [@{term "even::nat\<Rightarrow>bool"}, @{term "odd::nat\<Rightarrow>bool"}]
   140   val preds = [@{term "even::nat\<Rightarrow>bool"}, @{term "odd::nat\<Rightarrow>bool"}, @{term "z::nat"}]
   136   val pred = @{term "even::nat\<Rightarrow>bool"}
   141   val pred = @{term "even::nat\<Rightarrow>bool"}
   137   val arg_tys = [@{typ "nat"}]
   142   val arg_tys = [@{typ "nat"}]
   138   val def = defs_aux lthy orules preds (pred, arg_tys)
   143   val def = defs_aux lthy orules preds (pred, arg_tys)
   139 in
   144 in
   140   warning (Syntax.string_of_term lthy def); lthy
   145   warning (Syntax.string_of_term lthy def); lthy
   141 end *}
   146 end *}
   142 
   147 
   143 text {*
   148 text {*
   144   It constructs the left-hand side for the definition of @{term "even"}. So we obtain 
   149   It constructs the left-hand side for the definition of @{text "even"}. So we obtain 
   145   as printout the term
   150   as printout the term
   146 
   151 
   147   @{text [display] 
   152   @{text [display] 
   148 "\<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   153 "\<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   149                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   154                          \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z"}
   150 
   155 
   151   The main function for the definitions now has to just iterate
   156   The main function for the definitions now has to just iterate the function
   152   the function @{ML defs_aux} over all predicates. 
   157   @{ML defs_aux} over all predicates. The argument @{text "preds"} is again
       
   158   the the list of predicates as @{ML_type term}s; the argument @{text
       
   159   "prednames"} is the list of names of the predicates; @{text "arg_tyss"} is
       
   160   the list of argument-type-lists for each predicate.
   153 *}
   161 *}
   154 
   162 
   155 ML %linenosgray{*fun definitions rules preds prednames syns arg_typss lthy =
   163 ML %linenosgray{*fun definitions rules preds prednames syns arg_typss lthy =
   156 let
   164 let
   157   val thy = ProofContext.theory_of lthy
   165   val thy = ProofContext.theory_of lthy
   160 in
   168 in
   161   fold_map make_defs (prednames ~~ syns ~~ defs) lthy
   169   fold_map make_defs (prednames ~~ syns ~~ defs) lthy
   162 end*}
   170 end*}
   163 
   171 
   164 text {*
   172 text {*
   165   The argument @{text "preds"} is again the the list of predicates as 
   173   The user will state the introduction rules using meta-implications and
   166   @{ML_type term}s;
   174   meta-quanti\-fications. In Line 4, we transform these introduction rules into
   167   the argument @{text "prednames"} is the list of names of the predicates;
   175   the object logic (since definitions cannot be stated with
   168   @{text "arg_tyss"} is the list of argument-type-lists for each predicate. 
   176   meta-connectives). To do this transformation we have to obtain the theory
   169   
   177   behind the local theory (Line 3); with this theory we can use the function
   170   The user give the introduction rules using meta-implications and meta-quantifications.
   178   @{ML ObjectLogic.atomize_term} to make the transformation (Line 4). The call
   171   In line 4 we transform the introduction rules into the object logic (definitions
   179   to @{ML defs_aux} in Line 5 produces all left-hand sides of the
   172   cannot use them). To do the transformation we have to 
   180   definitions. The actual definitions are then made in Line 7.  The result
   173   obtain the theory behind the local theory (Line 3); with this theory 
   181   of the function is a list of theorems and a local theory.
   174   we can use the function @{ML ObjectLogic.atomize_term} to make the
   182 
   175   transformation (Line 4). The call to @{ML defs_aux} in Line 5 produces all
       
   176   left-hand sides of the definitions. The actual definitions are then made in Line 7.
       
   177   As the result we obtain a list of theorems and a local theory. 
       
   178 
   183 
   179   A testcase for this function is 
   184   A testcase for this function is 
   180 *}
   185 *}
   181 
   186 
   182 local_setup %gray {* fn lthy =>
   187 local_setup %gray {* fn lthy =>
   192 in
   197 in
   193   warning (str_of_thms lthy' defs); lthy'
   198   warning (str_of_thms lthy' defs); lthy'
   194 end *}
   199 end *}
   195 
   200 
   196 text {*
   201 text {*
       
   202   where we feed into the functions all parameters corresponding to
       
   203   the @{text even}-@{text odd} example. The definitions we obtain
       
   204   are:
   197 
   205 
   198   \begin{isabelle}
   206   \begin{isabelle}
   199   \isacommand{thm}~@{text "even_def odd_def"}\\
   207   \isacommand{thm}~@{text "even_def odd_def"}\\
   200   @{text [break]
   208   @{text [break]
   201 "> even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   209 "> even \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   202 >                                 \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z,
   210 >                                 \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> even z,
   203 > odd \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   211 > odd \<equiv> \<lambda>z. \<forall>even odd. (even 0) \<longrightarrow> (\<forall>n. odd n \<longrightarrow> even (Suc n)) 
   204 >                                 \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> odd z"}
   212 >                                \<longrightarrow> (\<forall>n. even n \<longrightarrow> odd (Suc n)) \<longrightarrow> odd z"}
   205   \end{isabelle}
   213   \end{isabelle}
   206 
   214 
   207 
   215 
   208   This completes the code concerning the definitions. Next comes the code for
   216   This completes the code for making the definitions. Next we deal with
   209   the induction principles. 
   217   the induction principles. Recall that the proof of the induction principle 
   210 
   218   for @{text "even"} was:
   211   Let us now turn to the induction principles. Recall that the proof of the 
   219 *}
   212   induction principle for @{term "even"} was:
   220 
   213 *}
   221 lemma man_ind_principle: 
   214 
       
   215 lemma 
       
   216 assumes prems: "even n"
   222 assumes prems: "even n"
   217 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P n"
   223 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P n"
   218 apply(atomize (full))
   224 apply(atomize (full))
   219 apply(cut_tac prems)
   225 apply(cut_tac prems)
   220 apply(unfold even_def)
   226 apply(unfold even_def)
   222 apply(drule spec[where x=Q])
   228 apply(drule spec[where x=Q])
   223 apply(assumption)
   229 apply(assumption)
   224 done
   230 done
   225 
   231 
   226 text {* 
   232 text {* 
   227   We have to implement code that constructs the induction principle and then
   233   The code for such induction principles has to accomplish two tasks: 
   228   a tactic that automatically proves it. 
   234   constructing the induction principles from the given introduction
       
   235   rules and then automatically generating a proof of them using a tactic. 
   229   
   236   
   230   The tactic will use the following helper function for instantiating universal 
   237   The tactic will use the following helper function for instantiating universal 
   231   quantifiers. This function instantiates the @{text "?x"} in the theorem 
   238   quantifiers. 
   232   @{thm spec} with a given @{ML_type cterm}.
       
   233 *}
   239 *}
   234 
   240 
   235 ML{*fun inst_spec ctrm = 
   241 ML{*fun inst_spec ctrm = 
   236  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}*}
   237 
   243 
   238 text {*
   244 text {*
   239   For example we can use it in the following proof to instantiate the 
   245   This helper function instantiates the @{text "?x"} in the theorem 
   240   three quantifiers in the assumption. We use the tactic
   246   @{thm spec} with a given @{ML_type cterm}. Together with the tactic
   241 *}
   247 *}
   242 
   248 
   243 ML{*fun inst_spec_tac ctrms = 
   249 ML{*fun inst_spec_tac ctrms = 
   244   EVERY' (map (dtac o inst_spec) ctrms)*}
   250   EVERY' (map (dtac o inst_spec) ctrms)*}
   245 
   251 
   246 text {*
   252 text {*
   247   and then apply use it with the @{ML_type cterm}s @{text "y1\<dots>y3"}. 
   253   we can use @{ML inst_spec} in the following proof to instantiate the 
   248   *}
   254   three quantifiers in the assumption. 
   249 
   255 *}
   250 lemma "\<forall>(x1::nat) (x2::nat) (x3::nat). P x1 x2 x3 \<Longrightarrow> True"
   256 
       
   257 lemma 
       
   258   fixes P::"nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
       
   259   shows "\<forall>x y z. P x y z \<Longrightarrow> True"
   251 apply (tactic {* 
   260 apply (tactic {* 
   252   inst_spec_tac  [@{cterm "y1::nat"},@{cterm "y2::nat"},@{cterm "y3::nat"}] 1 *})
   261   inst_spec_tac  [@{cterm "a::nat"},@{cterm "b::nat"},@{cterm "c::nat"}] 1 *})
   253 txt {* 
   262 txt {* 
   254   We obtain the goal state
   263   We obtain the goal state
   255 
   264 
   256   \begin{minipage}{\textwidth}
   265   \begin{minipage}{\textwidth}
   257   @{subgoals} 
   266   @{subgoals} 
   269           K (rewrite_goals_tac defs),
   278           K (rewrite_goals_tac defs),
   270           inst_spec_tac insts,
   279           inst_spec_tac insts,
   271           assume_tac]*}
   280           assume_tac]*}
   272 
   281 
   273 text {*
   282 text {*
   274   We only have to give it as arguments the premises and the instantiations.
   283   We only have to give it as arguments the definitions, the premise 
   275   A testcase for the tactic is
   284   (like @{text "even n"}) 
       
   285   and the instantiations. Compare this with the manual proof given for the
       
   286   lemma @{thm [source] man_ind_principle}.  
       
   287   A testcase for this tactic is the function
   276 *}
   288 *}
   277 
   289 
   278 ML{*fun test_tac prems = 
   290 ML{*fun test_tac prems = 
   279 let
   291 let
   280   val defs = [@{thm even_def}, @{thm odd_def}]
   292   val defs = [@{thm even_def}, @{thm odd_def}]
   282 in 
   294 in 
   283   induction_tac defs prems insts 
   295   induction_tac defs prems insts 
   284 end*}
   296 end*}
   285 
   297 
   286 text {*
   298 text {*
   287   which indeed proves the induction principle. 
   299   which indeed proves the induction principle: 
   288 *}
   300 *}
   289 
   301 
   290 lemma 
   302 lemma 
   291 assumes prems: "even n"
   303 assumes prems: "even n"
   292 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P n"
   304 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P n"
   293 apply(tactic {* test_tac @{thms prems} *})
   305 apply(tactic {* test_tac @{thms prems} *})
   294 done
   306 done
   295 
   307 
   296 text {*
   308 text {*
   297   While the generic proof for the induction principle is relatively simple, 
   309   While the tactic for the induction principle is relatively simple, 
   298   it is a bit harder to construct the goals from just the introduction 
   310   it is a bit harder to construct the goals from the introduction 
   299   rules the user states. In general we have to construct for each predicate 
   311   rules the user provides. In general we have to construct for each predicate 
   300   @{text "pred"} a goal of the form
   312   @{text "pred"} a goal of the form
   301 
   313 
   302   @{text [display] 
   314   @{text [display] 
   303   "\<And>\<^raw:$zs$>. pred \<^raw:$zs$> \<Longrightarrow> rules[preds := \<^raw:$Ps$>] \<Longrightarrow> \<^raw:$P$>\<^raw:$zs$>"}
   315   "\<And>\<^raw:$zs$>. pred \<^raw:$zs$> \<Longrightarrow> rules[preds := \<^raw:$Ps$>] \<Longrightarrow> \<^raw:$P$> \<^raw:$zs$>"}
   304 
   316 
   305   where the given predicates @{text preds} are replaced in the introduction 
   317   where the given predicates @{text preds} are replaced in the introduction 
   306   rule @{text "rules"} by new distinct variables written as @{text "\<^raw:$Ps$>"}. 
   318   rules by new distinct variables written @{text "\<^raw:$Ps$>"}. 
   307   We also need to generate fresh arguments for the predicate @{text "pred"} and
   319   We also need to generate fresh arguments for the predicate @{text "pred"} in
   308   the @{text "\<^raw:$P$>"} in the conclusion of the induction principle.
   320   the premise and the @{text "\<^raw:$P$>"} in the conclusion. We achieve
   309 
   321   that in two steps. 
   310   The function below expects that the rules are already appropriately
   322 
   311   substitued. The argument @{text "srules"} stands for these substituted
   323   The function below expects that the introduction rules are already appropriately
   312   introduction rules; @{text cnewpreds} are the certified terms coresponding
   324   substituted. The argument @{text "srules"} stands for these substituted
       
   325    rules; @{text cnewpreds} are the certified terms coresponding
   313   to the variables @{text "\<^raw:$Ps$>"}; @{text "pred"} is the predicate for
   326   to the variables @{text "\<^raw:$Ps$>"}; @{text "pred"} is the predicate for
   314   which we prove the introduction principle; @{text "newpred"} is its
   327   which we prove the introduction principle; @{text "newpred"} is its
   315   replacement and @{text "tys"} are the argument types of this predicate.
   328   replacement and @{text "tys"} are the argument types of this predicate.
   316 *}
   329 *}
   317 
   330 
   329   (fn {prems, ...} => induction_tac defs prems cnewpreds)
   342   (fn {prems, ...} => induction_tac defs prems cnewpreds)
   330   |> singleton (ProofContext.export lthy' lthy)
   343   |> singleton (ProofContext.export lthy' lthy)
   331 end *}
   344 end *}
   332 
   345 
   333 text {* 
   346 text {* 
   334   In Line 3 we produce a name @{text "\<^raw:$zs$>"} for each type in the 
   347   In Line 3 we produce names @{text "\<^raw:$zs$>"} for each type in the 
   335   argument type list. Line 4 makes these names unique and declares them as 
   348   argument type list. Line 4 makes these names unique and declares them as 
   336   \emph{free} (but fixed) variables in the local theory @{text "lthy'"}. In 
   349   \emph{free} (but fixed) variables in the local theory @{text "lthy'"}. In 
   337   Line 5 we just construct the terms corresponding to these variables. 
   350   Line 5 we just construct the terms corresponding to these variables. 
   338   The term variables are applied to the predicate in Line 7 (this corresponds
   351   The term variables are applied to the predicate in Line 7 (this corresponds
   339   to the first premise @{text "pred \<^raw:$zs$>"} of the induction principle). 
   352   to the first premise @{text "pred \<^raw:$zs$>"} of the induction principle). 
   340   In Line 8 and 9, we first construct the term  @{text "\<^raw:$P$>\<^raw:$zs$>"} 
   353   In Line 8 and 9, we first construct the term  @{text "\<^raw:$P$>\<^raw:$zs$>"} 
   341   and then add the (modified) introduction rules as premises. In case that
   354   and then add the (substituded) introduction rules as premises. In case that
   342   no introduction rules are given, the conclusion of this implications needs
   355   no introduction rules are given, the conclusion of this implication needs
   343   to be wrapped inside a @{term Trueprop}, otherwise the Isabelle's goal
   356   to be wrapped inside a @{term Trueprop}, otherwise the Isabelle's goal
   344   mechanism will fail. 
   357   mechanism will fail. 
   345 
   358 
   346   In Line 11 we set up the goal to be proved; then call the tactic for proving the 
   359   In Line 11 we set up the goal to be proved; in the next line call the tactic
   347   induction principle. This tactic expects the (certified) predicates with which
   360   for proving the induction principle. This tactic expects definitions, the
   348   the introduction rules have been substituted. This will return a theorem. 
   361   premise and the (certified) predicates with which the introduction rules
   349   However, it is a theorem proved inside the local theory @{text "lthy'"} where 
   362   have been substituted. This will return a theorem. However, it is a theorem
   350   the variables @{text "\<^raw:$zs$>"} are fixed, but free. By exporting this 
   363   proved inside the local theory @{text "lthy'"}, where the variables @{text
   351   theorem from @{text "lthy'"} (which contains the  @{text "\<^raw:$zs$>"} 
   364   "\<^raw:$zs$>"} are fixed, but free. By exporting this theorem from @{text
   352   as free) to @{text "lthy"} (which does not), we obtain the desired quantifications 
   365   "lthy'"} (which contains the @{text "\<^raw:$zs$>"} as free) to @{text
   353   @{text "\<And>\<^raw:$zs$>"}.
   366   "lthy"} (which does not), we obtain the desired quantifications @{text
   354 
   367   "\<And>\<^raw:$zs$>"}.
   355   Now it is left to produce the new predicated with which the introduction
   368 
       
   369   (FIXME testcase)
       
   370 
       
   371 
       
   372   Now it is left to produce the new predicates with which the introduction
   356   rules are substituted. 
   373   rules are substituted. 
   357 *}
   374 *}
   358 
   375 
   359 ML %linenosgray{*fun inductions rules defs preds tyss lthy  =
   376 ML %linenosgray{*fun inductions rules defs preds arg_tyss lthy  =
   360 let
   377 let
   361   val Ps = replicate (length preds) "P"
   378   val Ps = replicate (length preds) "P"
   362   val (newprednames, lthy') = Variable.variant_fixes Ps lthy
   379   val (newprednames, lthy') = Variable.variant_fixes Ps lthy
   363   
   380   
   364   val thy = ProofContext.theory_of lthy'
   381   val thy = ProofContext.theory_of lthy'
   365 
   382 
   366   val tyss' = map (fn tys => tys ---> HOLogic.boolT) tyss
   383   val tyss' = map (fn tys => tys ---> HOLogic.boolT) arg_tyss
   367   val newpreds = map Free (newprednames ~~ tyss')
   384   val newpreds = map Free (newprednames ~~ tyss')
   368   val cnewpreds = map (cterm_of thy) newpreds
   385   val cnewpreds = map (cterm_of thy) newpreds
   369   val rules' = map (subst_free (preds ~~ newpreds)) rules
   386   val srules = map (subst_free (preds ~~ newpreds)) rules
   370 
   387 
   371 in
   388 in
   372   map (prove_induction lthy' defs rules' cnewpreds) 
   389   map (prove_induction lthy' defs srules cnewpreds) 
   373         (preds ~~ newpreds ~~ tyss)
   390         (preds ~~ newpreds ~~ arg_tyss)
   374           |> ProofContext.export lthy' lthy
   391           |> ProofContext.export lthy' lthy
   375 end*}
   392 end*}
   376 
   393 
   377 ML {*
   394 text {*
   378   let 
   395   In Line 3 we generate a string @{text [quotes] "P"} for each predicate. 
   379     val rules = [@{prop "even (0::nat)"},
   396   In Line 4, we use the same trick as in the previous function, that is making the 
   380                  @{prop "\<And>n::nat. odd n \<Longrightarrow> even (Suc n)"},
   397   @{text "\<^raw:$Ps$>"} fresh and declaring them as fixed but free in
   381                  @{prop "\<And>n::nat. even n \<Longrightarrow> odd (Suc n)"}] 
   398   the new local theory @{text "lthy'"}. From the local theory we extract
   382     val defs = [@{thm even_def}, @{thm odd_def}]
   399   the ambient theory in Line 6. We need this theory in order to certify 
   383     val preds = [@{term "even::nat\<Rightarrow>bool"}, @{term "odd::nat\<Rightarrow>bool"}]
   400   the new predicates. In Line 8 we calculate the types of these new predicates
   384     val tyss = [[@{typ "nat"}], [@{typ "nat"}]]
   401   using the argument types. Next we turn them into terms and subsequently
   385   in
   402   certify them. We can now produce the substituted introduction rules 
   386     inductions rules defs preds tyss @{context}
   403   (Line 11). Line 14 and 15 just iterate the proofs for all predicates.
   387   end
   404   From this we obtain a list of theorems. Finally we need to export the 
   388 *}
   405   fixed variables @{text "\<^raw:$Ps$>"} to obtain the correct quantification 
   389 
   406   (Line 16).
   390 
   407 
   391 subsection {* Introduction Rules *}
   408   A testcase for this function is
       
   409 *}
       
   410 
       
   411 local_setup %gray {* fn lthy =>
       
   412 let 
       
   413   val rules = [@{prop "even (0::nat)"},
       
   414                @{prop "\<And>n::nat. odd n \<Longrightarrow> even (Suc n)"},
       
   415                @{prop "\<And>n::nat. even n \<Longrightarrow> odd (Suc n)"}] 
       
   416   val defs = [@{thm even_def}, @{thm odd_def}]
       
   417   val preds = [@{term "even::nat\<Rightarrow>bool"}, @{term "odd::nat\<Rightarrow>bool"}]
       
   418   val tyss = [[@{typ "nat"}], [@{typ "nat"}]]
       
   419   val ind_thms = inductions rules defs preds tyss lthy
       
   420 in
       
   421   warning (str_of_thms lthy ind_thms); lthy
       
   422 end  
       
   423 *}
       
   424 
       
   425 
       
   426 text {*
       
   427   which prints out
       
   428 
       
   429 @{text [display]
       
   430 "> even z \<Longrightarrow> 
       
   431 >  P 0 \<Longrightarrow> (\<And>m. Pa m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Pa (Suc m)) \<Longrightarrow> P z,
       
   432 > odd z \<Longrightarrow> 
       
   433 >  P 0 \<Longrightarrow> (\<And>m. Pa m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Pa (Suc m)) \<Longrightarrow> Pa z"}
       
   434 
       
   435 
       
   436   This completes the code for the induction principles. Finally we can 
       
   437   prove the introduction rules. 
       
   438 
       
   439 *}
       
   440 
       
   441 ML {* ObjectLogic.rulify  *}
       
   442 
   392 
   443 
   393 ML{*val all_elims = fold (fn ct => fn th => th RS inst_spec ct)
   444 ML{*val all_elims = fold (fn ct => fn th => th RS inst_spec ct)
   394 val imp_elims = fold (fn th => fn th' => [th', th] MRS @{thm mp})*}
   445 val imp_elims = fold (fn th => fn th' => [th', th] MRS @{thm mp})*}
   395 
   446 
   396 ML{*fun subproof2 prem params2 prems2 =  
   447 ML{*fun subproof2 prem params2 prems2 =  
   420 
   471 
   421 ML{*
   472 ML{*
   422 fun introductions_tac defs rules preds i ctxt =
   473 fun introductions_tac defs rules preds i ctxt =
   423   EVERY1 [ObjectLogic.rulify_tac,
   474   EVERY1 [ObjectLogic.rulify_tac,
   424           K (rewrite_goals_tac defs),
   475           K (rewrite_goals_tac defs),
   425           REPEAT o (resolve_tac [@{thm allI},@{thm impI}]),
   476           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   426           subproof1 rules preds i ctxt]*}
   477           subproof1 rules preds i ctxt]*}
   427 
   478 
   428 lemma evenS: 
   479 lemma evenS: 
   429   shows "odd m \<Longrightarrow> even (Suc m)"
   480   shows "odd m \<Longrightarrow> even (Suc m)"
   430 apply(tactic {* 
   481 apply(tactic {* 
   489 in
   540 in
   490   add_inductive_i pred_specs' rule_specs' lthy
   541   add_inductive_i pred_specs' rule_specs' lthy
   491 end*} 
   542 end*} 
   492 
   543 
   493 ML{*val spec_parser = 
   544 ML{*val spec_parser = 
   494    OuterParse.opt_target --
       
   495    OuterParse.fixes -- 
   545    OuterParse.fixes -- 
   496    Scan.optional 
   546    Scan.optional 
   497      (OuterParse.$$$ "where" |--
   547      (OuterParse.$$$ "where" |--
   498         OuterParse.!!! 
   548         OuterParse.!!! 
   499           (OuterParse.enum1 "|" 
   549           (OuterParse.enum1 "|" 
   500              (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*}
   550              (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*}
   501 
   551 
   502 ML{*val specification =
   552 ML{*val specification =
   503   spec_parser >>
   553   spec_parser >>
   504     (fn ((loc, pred_specs), rule_specs) =>
   554     (fn ((pred_specs), rule_specs) => add_inductive pred_specs rule_specs)*}
   505       Toplevel.local_theory loc (add_inductive pred_specs rule_specs))*}
   555 
   506 
   556 ML{*val _ = OuterSyntax.local_theory "simple_inductive" "define inductive predicates"
   507 ML{*val _ = OuterSyntax.command "simple_inductive" "define inductive predicates"
       
   508           OuterKeyword.thy_decl specification*}
   557           OuterKeyword.thy_decl specification*}
   509 
   558 
   510 text {*
   559 text {*
   511   Things to include at the end:
   560   Things to include at the end:
   512 
   561