ProgTutorial/Package/Ind_Code.thy
changeset 215 8d1a344a621e
parent 212 ac01ddb285f6
child 217 75154f4d4e2f
equal deleted inserted replaced
214:7e04dc2368b0 215:8d1a344a621e
     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: code that deals 
     8   As mentioned before the code falls roughly into three parts: code that deals
     9   with the definitions, the induction principles and the introduction rules, respectively. 
     9   with the definitions, withe the induction principles and the introduction
    10   In addition there are some administrative functions that string everything together. 
    10   rules, respectively. In addition there are some administrative functions
       
    11   that string everything together.
    11 *}
    12 *}
    12 
    13 
    13 subsection {* Definitions *}
    14 subsection {* Definitions *}
    14 
    15 
    15 text {*
    16 text {*
   204 *}
   205 *}
   205 
   206 
   206 subsection {* Induction Principles *}
   207 subsection {* Induction Principles *}
   207 
   208 
   208 text {*
   209 text {*
   209   Recall that the proof of the induction principle 
   210   Recall that the manual proof for the induction principle 
   210   for @{text "even"} was:
   211   of @{text "even"} was:
   211 *}
   212 *}
   212 
   213 
   213 lemma manual_ind_prin_even: 
   214 lemma manual_ind_prin_even: 
   214 assumes prem: "even z"
   215 assumes prem: "even z"
   215 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   216 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   234  Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   235  Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}*}
   235 
   236 
   236 text {*
   237 text {*
   237   This helper function instantiates the @{text "?x"} in the theorem 
   238   This helper function instantiates the @{text "?x"} in the theorem 
   238   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   239   @{thm spec} with a given @{ML_type cterm}. We call this helper function
   239   in the following tactic, called @{text inst_spec_tac}.
   240   in the following tactic, called @{text inst_spec_tac}\label{fun:instspectac}.
   240 *}
   241 *}
   241 
   242 
   242 ML{*fun inst_spec_tac ctrms = 
   243 ML{*fun inst_spec_tac ctrms = 
   243   EVERY' (map (dtac o inst_spec) ctrms)*}
   244   EVERY' (map (dtac o inst_spec) ctrms)*}
   244 
   245 
   271           K (rewrite_goals_tac defs),
   272           K (rewrite_goals_tac defs),
   272           inst_spec_tac insts,
   273           inst_spec_tac insts,
   273           assume_tac]*}
   274           assume_tac]*}
   274 
   275 
   275 text {*
   276 text {*
   276   We have to give it as arguments the definitions, the premise (this premise
   277   We have to give it as arguments the definitions, the premise (a list of
   277   is @{text "even n"} in lemma @{thm [source] manual_ind_prin_even}) and the
   278   formulae) and the instantiations. The premise is @{text "even n"} in lemma
   278   instantiations. Compare this tactic with the manual proof for the lemma @{thm
   279   @{thm [source] manual_ind_prin_even}; in our code it will always be a list
   279   [source] manual_ind_prin_even}: as you can see there is almost a one-to-one
   280   consisting of a single formula. Compare this tactic with the manual proof
   280   correspondence between the \isacommand{apply}-script and the @{ML
   281   for the lemma @{thm [source] manual_ind_prin_even}: as you can see there is
   281   ind_tac}. Two testcases for this tactic are:
   282   almost a one-to-one correspondence between the \isacommand{apply}-script and
       
   283   the @{ML ind_tac}. Two testcases for this tactic are:
   282 *}
   284 *}
   283 
   285 
   284 lemma automatic_ind_prin_even:
   286 lemma automatic_ind_prin_even:
   285 assumes prem: "even z"
   287 assumes prem: "even z"
   286 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   288 shows "P 0 \<Longrightarrow> (\<And>m. Q m \<Longrightarrow> P (Suc m)) \<Longrightarrow> (\<And>m. P m \<Longrightarrow> Q (Suc m)) \<Longrightarrow> P z"
   307   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   309   \isacommand{thm}~@{thm [source] automatic_ind_prin_even}\\
   308   @{text "> "}~@{thm automatic_ind_prin_even}
   310   @{text "> "}~@{thm automatic_ind_prin_even}
   309   \end{isabelle}
   311   \end{isabelle}
   310 
   312 
   311   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   313   The variables @{text "z"}, @{text "P"} and @{text "Q"} are schematic
   312   variables (since they are not quantified in the lemma). These schematic
   314   variables (since they are not quantified in the lemma). These 
   313   variables are needed so that they can be instantiated by the user. 
   315   variables must be schematic, otherwise they cannot be instantiated 
   314   It will take a bit of work to generate these schematic variables when
   316   by the user. To generate these schematic variables we use a common trick
   315   constructing the goals for the induction principles.  In general we have 
   317   in Isabelle programming: we first declare them as \emph{free}, 
   316   to construct for each predicate @{text "pred"} a goal of the form
   318   \emph{but fixed}, and then use the infrastructure to turn them into 
       
   319   schematic variables.
       
   320 
       
   321   In general we have to construct for each predicate @{text "pred"} a goal 
       
   322   of the form
   317 
   323 
   318   @{text [display] 
   324   @{text [display] 
   319   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   325   "pred ?zs \<Longrightarrow> rules[preds := ?Ps] \<Longrightarrow> ?P ?zs"}
   320 
   326 
   321   where the predicates @{text preds} are replaced in @{text rules} by new 
   327   where the predicates @{text preds} are replaced in @{text rules} by new 
   322   distinct variables @{text "?Ps"}. We also need to generate fresh arguments 
   328   distinct variables @{text "?Ps"}. We also need to generate fresh arguments 
   323   @{text "?zs"} for the predicate  @{text "pred"} and the @{text "?P"} in 
   329   @{text "?zs"} for the predicate  @{text "pred"} and the @{text "?P"} in 
   324   the conclusion. As just mentioned, the crucial point is that the  
   330   the conclusion. 
   325   @{text "?Ps"} and @{text "?zs"} need to be schematic variables that can 
       
   326   be instantiated by the user.
       
   327 
   331 
   328   We generate these goals in two steps. The first function, named @{text prove_ind}, 
   332   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
   333   expects that the introduction rules are already appropriately substituted. The argument
   330   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   334   @{text "srules"} stands for these substituted rules; @{text cnewpreds} are
   331   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   335   the certified terms coresponding to the variables @{text "?Ps"}; @{text
   350 end *}
   354 end *}
   351 
   355 
   352 text {* 
   356 text {* 
   353   In Line 3 we produce names @{text "zs"} for each type in the 
   357   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 
   358   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'"}. 
   359   free, but fixed, variables in the local theory @{text "lthy'"}. 
   356   That means they are not schematic variables (yet).
   360   That means they are not schematic variables (yet).
   357   In Line 5 we construct the terms corresponding to these variables. 
   361   In Line 5 we construct the terms corresponding to these variables. 
   358   The variables are applied to the predicate in Line 7 (this corresponds
   362   The variables are applied to the predicate in Line 7 (this corresponds
   359   to the first premise @{text "pred zs"} of the induction principle). 
   363   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"} 
   364   In Line 8 and 9, we first construct the term  @{text "P zs"} 
   512 in
   516 in
   513   warning (str_of_thm_no_vars @{context} new_thm)
   517   warning (str_of_thm_no_vars @{context} new_thm)
   514 end"
   518 end"
   515   "P a b c"}
   519   "P a b c"}
   516 
   520 
       
   521   Note the difference with @{ML inst_spec_tac} from Page~\pageref{fun:instspectac}:
       
   522   @{ML inst_spec_tac} is a tactic which operates on a goal state; in contrast
       
   523   @{ML all_elims} operates on theorems. 
       
   524 
   517   Similarly, the function @{ML imp_elims} eliminates preconditions from implications. 
   525   Similarly, the function @{ML imp_elims} eliminates preconditions from implications. 
   518   For example we can eliminate the preconditions @{text "A"} and @{text "B"} from
   526   For example we can eliminate the preconditions @{text "A"} and @{text "B"} from
   519   @{thm [source] imp_elims_test}:
   527   @{thm [source] imp_elims_test}:
   520 
   528 
   521   @{ML_response_fake [display, gray]
   529   @{ML_response_fake [display, gray]
   541   THEN rewrite_goals_tac defs
   549   THEN rewrite_goals_tac defs
   542   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   550   THEN (REPEAT (resolve_tac [@{thm allI}, @{thm impI}] 1)) *}
   543 
   551 
   544 text {*
   552 text {*
   545   The function in Line 2 ``rulifies'' the lemma. This will turn out to 
   553   The function in Line 2 ``rulifies'' the lemma. This will turn out to 
   546   be important later on. Applying this tactic 
   554   be important later on. Applying this tactic in our proof of @{text "fresh_Lem"}
   547 *}
   555 *}
   548 
   556 
   549 (*<*)
   557 (*<*)
   550 lemma fresh_Lam:
   558 lemma fresh_Lam:
   551   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   559   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   552 (*>*)
   560 (*>*)
   553 apply(tactic {* expand_tac @{thms fresh_def} *})
   561 apply(tactic {* expand_tac @{thms fresh_def} *})
   554 
   562 
   555 txt {*
   563 txt {*
   556   we end up in the goal state
   564   gives us the goal state
   557 
   565 
   558   \begin{isabelle}
   566   \begin{isabelle}
   559   @{subgoals [display]}
   567   @{subgoals [display]}
   560   \end{isabelle}
   568   \end{isabelle}
   561 
   569 
   562   As you can see, there are parameters (namely @{text "a"}, @{text "b"} 
   570   As you can see, there are parameters (namely @{text "a"}, @{text "b"} and
   563   and @{text "t"}) which come from the introduction rule and parameters
   571   @{text "t"}) which come from the introduction rule and parameters (in the
   564   (in the case above only @{text "fresh"}) which come from the universal
   572   case above only @{text "fresh"}) which come from the universal
   565   quantification in the definition @{term "fresh a (App t s)"}.
   573   quantification in the definition @{term "fresh a (App t s)"}.  Similarly,
   566   Similarly, there are assumptions
   574   there are assumptions that come from the premises of the rule (namely the
   567   that come from the premises of the rule and assumptions from the
   575   first two) and assumptions from the definition of the predicate (assumption
   568   definition of the predicate. We need to treat these 
   576   three to six). We need to treat these parameters and assumptions
   569   parameters and assumptions differently. In the code below
   577   differently. In the code below we will therefore separate them into @{text
   570   we will therefore separate them into @{text "params1"} and @{text params2},
   578   "params1"} and @{text params2}, respectively @{text "prems1"} and @{text
   571   respectively @{text "prems1"} and @{text "prems2"}. To do this 
   579   "prems2"}. To do this separation, it is best to open a subproof with the
   572   separation, it is best to open a subproof with the tactic 
   580   tactic @{ML SUBPROOF}, since this tactic provides us with the parameters (as
   573   @{ML SUBPROOF}, since this tactic provides us
   581   list of @{ML_type cterm}s) and the assumptions (as list of @{ML_type thm}s). 
   574   with the parameters (as list of @{ML_type cterm}s) and the assumptions
   582   The problem we have to overcome with @{ML SUBPROOF}
   575   (as list of @{ML_type thm}s called @{text prems}). The problem we have 
   583   is, however, that this tactic always expects us to completely discharge the
   576   to overcome with @{ML SUBPROOF} is, however, that this tactic always 
   584   goal (see Section~\ref{sec:simpletacs}). This is inconvenient for our
   577   expects us to completely discharge the goal (see Section~\ref{sec:simpletacs}). 
   585   gradual explanation of the proof here. To circumvent this inconvenience we
   578   This is inconvenient for our gradual explanation of the proof here. To 
   586   use the following modified tactic:
   579   circumvent this inconvenience we use the following modified tactic: 
       
   580 *}
   587 *}
   581 (*<*)oops(*>*)
   588 (*<*)oops(*>*)
   582 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   589 ML{*fun SUBPROOF_test tac ctxt = (SUBPROOF tac ctxt 1) ORELSE all_tac*}
   583 
   590 
   584 text {*
   591 text {*
   697     THEN no_tac
   704     THEN no_tac
   698   end) *}
   705   end) *}
   699 
   706 
   700 text {* 
   707 text {* 
   701   The argument @{text i} corresponds to the number of the 
   708   The argument @{text i} corresponds to the number of the 
   702   introduction we want to prove. We will later on lat it range
   709   introduction we want to prove. We will later on let it range
   703   from @{text 0} to the number of @{text "rules - 1"}.
   710   from @{text 0} to the number of @{text "rules - 1"}.
   704   Below we apply this function with @{text 3}, since 
   711   Below we apply this function with @{text 3}, since 
   705   we are proving the fourth introduction rule. 
   712   we are proving the fourth introduction rule. 
   706 *}
   713 *}
   707 
   714 
   720   \begin{isabelle}
   727   \begin{isabelle}
   721   @{text "1."}~@{prop "a \<noteq> b"}\\
   728   @{text "1."}~@{prop "a \<noteq> b"}\\
   722   @{text "2."}~@{prop "fresh a t"}
   729   @{text "2."}~@{prop "fresh a t"}
   723   \end{isabelle}
   730   \end{isabelle}
   724 
   731 
   725   As expected there are two subgoals, where the first comes from a
   732   As expected there are two subgoals, where the first comes from the
   726   non-recursive premise of the introduction rule and the second comes 
   733   non-recursive premise of the introduction rule and the second comes 
   727   from a recursive premise. The first goal can be solved immediately 
   734   from the recursive one. The first goal can be solved immediately 
   728   by @{text "prems1"}. The second needs more work. It can be solved 
   735   by @{text "prems1"}. The second needs more work. It can be solved 
   729   with the other premise in @{text "prems1"}, namely
   736   with the other premise in @{text "prems1"}, namely
   730 
   737 
   731 
   738 
   732   @{term [break,display]
   739   @{term [break,display]
   771     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   778     THEN EVERY1 (map (prepare_prem params2 prems2) prems1)
   772   end) *}
   779   end) *}
   773 
   780 
   774 text {*
   781 text {*
   775   Note that the tactic is now @{ML SUBPROOF}, not @{ML SUBPROOF_test}. 
   782   Note that the tactic is now @{ML SUBPROOF}, not @{ML SUBPROOF_test}. 
   776   The full proof of the introduction rule now as follows:
   783   The full proof of the introduction rule is as follows:
   777 *}
   784 *}
   778 
   785 
   779 lemma fresh_Lam:
   786 lemma fresh_Lam:
   780   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   787   shows "\<And>a b t. \<lbrakk>a \<noteq> b; fresh a t\<rbrakk> \<Longrightarrow> fresh a (Lam b t)"
   781 apply(tactic {* expand_tac @{thms fresh_def} *})
   788 apply(tactic {* expand_tac @{thms fresh_def} *})
   782 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   789 apply(tactic {* prove_intro_tac 3 [fresh_pred] fresh_rules @{context} 1 *})
   783 done
   790 done
   784 
   791 
   785 text {* 
   792 text {* 
   786   Phew!  Unfortunately, not everything is done yet. If you look closely
   793   Phew!  ...Unfortunately, not everything is done yet. If you look closely
   787   at the general principle outlined for the introduction rules in 
   794   at the general principle outlined for the introduction rules in 
   788   Section~\ref{sec:nutshell}, we have  not yet dealt with the case where 
   795   Section~\ref{sec:nutshell}, we have  not yet dealt with the case where 
   789   recursive premises have preconditions. The introduction rule
   796   recursive premises have preconditions. The introduction rule
   790   of the accessible part is such a rule. 
   797   of the accessible part is such a rule. 
   791 *}
   798 *}
   887           K (rewrite_goals_tac defs),
   894           K (rewrite_goals_tac defs),
   888           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   895           REPEAT o (resolve_tac [@{thm allI}, @{thm impI}]),
   889           prove_intro_tac i preds rules ctxt]*}
   896           prove_intro_tac i preds rules ctxt]*}
   890 
   897 
   891 text {*
   898 text {*
   892   Lines 2 to 4 correspond to the function @{ML expand_tac}. Some testcases
   899   Lines 2 to 4 in this tactic correspond to the function @{ML expand_tac}. 
   893   for this tactic are:
   900   Some testcases for this tactic are:
   894 *}
   901 *}
   895 
   902 
   896 lemma even0_intro:
   903 lemma even0_intro:
   897   shows "even 0"
   904   shows "even 0"
   898 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *})
   905 by (tactic {* intro_tac eo_defs eo_rules eo_preds 0 @{context} *})
   905   shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
   912   shows "\<And>a t s. \<lbrakk>fresh a t; fresh a s\<rbrakk> \<Longrightarrow> fresh a (App t s)"
   906 by (tactic {* 
   913 by (tactic {* 
   907   intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *})
   914   intro_tac @{thms fresh_def} fresh_rules [fresh_pred] 1 @{context} *})
   908 
   915 
   909 text {*
   916 text {*
   910   The second function sets up in Line 4 the goals (this is easy
   917   The second function sets up in Line 4 the goals to be proved (this is easy
   911   for the introduction rules since they are exactly the rules 
   918   for the introduction rules since they are exactly the rules 
   912   given by the user) and iterates @{ML intro_tac} over all 
   919   given by the user) and iterates @{ML intro_tac} over all 
   913   introduction rules.
   920   introduction rules.
   914 *}
   921 *}
   915 
   922 
   928   @{text 0}). This completes the code for the functions deriving the
   935   @{text 0}). This completes the code for the functions deriving the
   929   reasoning infrastructure. It remains to implement some administrative
   936   reasoning infrastructure. It remains to implement some administrative
   930   code that strings everything together.
   937   code that strings everything together.
   931 *}
   938 *}
   932 
   939 
   933 subsection {* Main Function *}
   940 subsection {* Administrative Functions *}
   934 
   941 
   935 text {* main internal function *}
   942 text {* 
   936 
   943   We have produced various theorems (definitions, induction principles and
   937 ML {* LocalTheory.notes *}
   944   introduction rules), but apart from the definitions, we have not yet 
   938 
   945   registered them with the theorem database. This is what the functions 
       
   946   @{ML LocalTheory.note} does. 
       
   947 
       
   948 
       
   949   For convenience, we use the following 
       
   950   three wrappers this function:
       
   951 *}
       
   952 
       
   953 ML{*fun reg_many qname ((name, attrs), thms) = 
       
   954   LocalTheory.note Thm.theoremK 
       
   955     ((Binding.qualify false qname name, attrs), thms) 
       
   956 
       
   957 fun reg_single1 qname ((name, attrs), thm) = 
       
   958   reg_many qname ((name, attrs), [thm]) 
       
   959 
       
   960 fun reg_single2 name attrs (qname, thm) = 
       
   961   reg_many (Binding.name_of qname) ((name, attrs), [thm]) *}
       
   962 
       
   963 text {*
       
   964   The function that ``holds everything together'' is @{text "add_inductive"}. 
       
   965   Its arguments are the specification of the predicates @{text "pred_specs"} 
       
   966   and the introduction rules @{text "rule_spec"}.   
       
   967 *}
   939 
   968 
   940 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   969 ML %linenosgray{*fun add_inductive pred_specs rule_specs lthy =
   941 let
   970 let
   942   val syns = map snd pred_specs
   971   val syns = map snd pred_specs
   943   val pred_specs' = map fst pred_specs
   972   val pred_specs' = map fst pred_specs
   944   val prednames = map fst pred_specs'
   973   val prednames = map fst pred_specs'
   945   val preds = map (fn (p, ty) => Free (Binding.name_of p, ty)) pred_specs'
   974   val preds = map (fn (p, ty) => Free (Binding.name_of p, ty)) pred_specs'
   946 
       
   947   val tyss = map (binder_types o fastype_of) preds   
   975   val tyss = map (binder_types o fastype_of) preds   
   948   val (attrs, rules) = split_list rule_specs    
   976 
       
   977   val (namesattrs, rules) = split_list rule_specs    
   949 
   978 
   950   val (defs, lthy') = defns rules preds prednames syns tyss lthy      
   979   val (defs, lthy') = defns rules preds prednames syns tyss lthy      
   951   val ind_rules = inds rules defs preds tyss lthy' 	
   980   val ind_prin = inds rules defs preds tyss lthy' 	
   952   val intro_rules = intros rules preds defs lthy'
   981   val intro_rules = intros rules preds defs lthy'
   953 
   982 
   954   val mut_name = space_implode "_" (map Binding.name_of prednames)
   983   val mut_name = space_implode "_" (map Binding.name_of prednames)
   955   val case_names = map (Binding.name_of o fst) attrs
   984   val case_names = map (Binding.name_of o fst) namesattrs
   956 in
   985 in
   957     lthy' 
   986   lthy' |> reg_many mut_name ((@{binding "intros"}, []), intro_rules) 
   958     |> LocalTheory.notes Thm.theoremK (map (fn (((a, atts), _), th) =>
   987         ||>> fold_map (reg_single1 mut_name) (namesattrs ~~ intro_rules)  
   959         ((Binding.qualify false mut_name a, atts), [([th], [])])) (rule_specs ~~ intro_rules)) 
   988         ||>> fold_map (reg_single2 @{binding "induct"} 
   960     |-> (fn intross => LocalTheory.note Thm.theoremK
   989               [Attrib.internal (K (RuleCases.case_names case_names)),
   961          ((Binding.qualify false mut_name (@{binding "intros"}), []), maps snd intross)) 
   990                Attrib.internal (K (RuleCases.consumes 1)),
   962     |>> snd 
   991                Attrib.internal (K (Induct.induct_pred ""))]) 
   963     ||>> (LocalTheory.notes Thm.theoremK (map (fn (((R, _), _), th) =>
   992              (prednames ~~ ind_prin) 
   964          ((Binding.qualify false (Binding.name_of R) (@{binding "induct"}),
   993         |> snd
   965           [Attrib.internal (K (RuleCases.case_names case_names)),
       
   966            Attrib.internal (K (RuleCases.consumes 1)),
       
   967            Attrib.internal (K (Induct.induct_pred ""))]), [([th], [])]))
       
   968           (pred_specs ~~ ind_rules)) #>> maps snd) 
       
   969     |> snd
       
   970 end*}
   994 end*}
       
   995 
       
   996 text {*
       
   997   In Line 3 the function extracts the syntax annotations from the predicates. 
       
   998   Lines 4 to 6 extract the names of the predicates and generate
       
   999   the variables terms (with types) corresponding to the predicates. 
       
  1000   Line 7 produces the argument types for each predicate. 
       
  1001 
       
  1002   Line 9 extracts the introduction rules from the specifications
       
  1003   and stores also in @{text namesattrs} the names and attributes the
       
  1004   user may have attached to these rules.
       
  1005 
       
  1006   Line 11 produces the definitions and also registers the definitions
       
  1007   in the local theory @{text "lthy'"}. The next two lines produce
       
  1008   the induction principles and the introduction rules (all of them
       
  1009   as theorems). Both need the local theory @{text lthy'} in which
       
  1010   the definitions have been registered.
       
  1011 
       
  1012   Lines 15 produces the name that is used to register the introduction
       
  1013   rules. It is costum to collect all introduction rules under 
       
  1014   @{text "string.intros"}, whereby @{text "string"} stands for the 
       
  1015   @{text [quotes] "_"}-separated list of predicate names (for example
       
  1016   @{text "even_odd"}. Also by custom, the case names in intuction 
       
  1017   proofs correspond to the names of the introduction rules. These
       
  1018   are generated in Line 16.
       
  1019 
       
  1020   Line 18 now adds to @{text "lthy'"} all the introduction rules 
       
  1021   under the name @{text "mut_name.intros"} (see previous paragraph).
       
  1022   Line 19 add further every introduction rule under its own name
       
  1023   (given by the user).\footnote{FIXME: what happens if the user did not give
       
  1024   any name.} Line 20 registers the induction principles. For this we have
       
  1025   to use some specific attributes. The first @{ML "case_names" in RuleCases} 
       
  1026   corresponds to the case names that are used by Isar to reference the proof
       
  1027   obligations in the induction. The second @{ML "consumes 1" in RuleCases}
       
  1028   indicates that the first premise of the induction principle (namely
       
  1029   the predicate over which the induction proceeds) is eliminated. 
       
  1030 
       
  1031   (FIXME: What does @{ML Induct.induct_pred} do?)
       
  1032 
       
  1033   (FIXME: why the mut-name?)
       
  1034 
       
  1035   (FIXME: What does @{ML Binding.qualify} do?)
       
  1036 
       
  1037 
       
  1038   This completes all the code and fits in with the ``front end'' described
       
  1039   in Section \ref{sec:interface}
       
  1040 *}
       
  1041 
   971 
  1042 
   972 ML{*fun add_inductive_cmd pred_specs rule_specs lthy =
  1043 ML{*fun add_inductive_cmd pred_specs rule_specs lthy =
   973 let
  1044 let
   974   val ((pred_specs', rule_specs'), _) = 
  1045   val ((pred_specs', rule_specs'), _) = 
   975          Specification.read_spec pred_specs rule_specs lthy
  1046          Specification.read_spec pred_specs rule_specs lthy
   990     (fn ((pred_specs), rule_specs) => add_inductive_cmd pred_specs rule_specs)*}
  1061     (fn ((pred_specs), rule_specs) => add_inductive_cmd pred_specs rule_specs)*}
   991 
  1062 
   992 ML{*val _ = OuterSyntax.local_theory "simple_inductive" 
  1063 ML{*val _ = OuterSyntax.local_theory "simple_inductive" 
   993               "define inductive predicates"
  1064               "define inductive predicates"
   994                  OuterKeyword.thy_decl specification*}
  1065                  OuterKeyword.thy_decl specification*}
       
  1066 
       
  1067 
       
  1068 section {* Extensions *}
   995 
  1069 
   996 text {*
  1070 text {*
   997   Things to include at the end:
  1071   Things to include at the end:
   998 
  1072 
   999   \begin{itemize}
  1073   \begin{itemize}
  1014 where
  1088 where
  1015   Even0: "Even 0"
  1089   Even0: "Even 0"
  1016 | EvenS: "Odd n \<Longrightarrow> Even (Suc n)"
  1090 | EvenS: "Odd n \<Longrightarrow> Even (Suc n)"
  1017 | OddS: "Even n \<Longrightarrow> Odd (Suc n)"
  1091 | OddS: "Even n \<Longrightarrow> Odd (Suc n)"
  1018 
  1092 
       
  1093 thm Even0
       
  1094 thm EvenS
       
  1095 thm OddS
       
  1096 
       
  1097 thm Even_Odd.intros
       
  1098 thm Even.induct
       
  1099 thm Odd.induct
       
  1100 
       
  1101 thm Even_def
       
  1102 thm Odd_def
       
  1103 
  1019 end
  1104 end