CookBook/Package/Ind_Code.thy
changeset 180 9c25418db6f0
parent 179 75381fa516cd
child 183 8bb4eaa2ec92
equal deleted inserted replaced
179:75381fa516cd 180:9c25418db6f0
   227 
   227 
   228 text {*
   228 text {*
   229   For example we can use it to instantiate an assumption:
   229   For example we can use it to instantiate an assumption:
   230 *}
   230 *}
   231 
   231 
   232 lemma "\<forall>x1 x2 x3. P (x1::nat) (x2::nat) (x3::nat) \<Longrightarrow> True"
   232 lemma "\<forall>(x1::nat) (x2::nat) (x3::nat). P x1 x2 x3 \<Longrightarrow> True"
   233 apply (tactic {* 
   233 apply (tactic {* 
   234   let 
   234   let 
   235     val ctrms = [@{cterm "y1::nat"},@{cterm "y2::nat"},@{cterm "y3::nat"}]
   235     val ctrms = [@{cterm "y1::nat"},@{cterm "y2::nat"},@{cterm "y3::nat"}]
   236   in 
   236   in 
   237     EVERY1 (map (dtac o inst_spec) ctrms)
   237     EVERY1 (map (dtac o inst_spec) ctrms)
   247 text {*
   247 text {*
   248   Now the tactic for proving the induction rules can be implemented 
   248   Now the tactic for proving the induction rules can be implemented 
   249   as follows
   249   as follows
   250 *}
   250 *}
   251 
   251 
   252 ML{*fun induction_tac defs prems insts =
   252 ML %linenosgray{*fun induction_tac defs prems insts =
   253   EVERY1 [ObjectLogic.full_atomize_tac,
   253   EVERY1 [ObjectLogic.full_atomize_tac,
   254           cut_facts_tac prems,
   254           cut_facts_tac prems,
   255           K (rewrite_goals_tac defs),
   255           K (rewrite_goals_tac defs),
   256           EVERY' (map (dtac o inst_spec) insts),
   256           EVERY' (map (dtac o inst_spec) insts),
   257           assume_tac]*}
   257           assume_tac]*}
   278 text {*
   278 text {*
   279   which indeed proves the lemma. 
   279   which indeed proves the lemma. 
   280 
   280 
   281   While the generic proof for the induction principle is relatively simple, 
   281   While the generic proof for the induction principle is relatively simple, 
   282   it is a bit harder to set up the goals just from the given introduction 
   282   it is a bit harder to set up the goals just from the given introduction 
   283   rules. For this we have to construct
   283   rules. For this we have to construct for each predicate @{text "pred"}
   284 
   284 
   285   @{text [display] 
   285   @{text [display] 
   286   "\<And>\<^raw:$zs$>. pred \<^raw:$zs$> \<Longrightarrow> rules[preds := \<^raw:$Ps$>] \<Longrightarrow> \<^raw:$P$> \<^raw:$zs$>"}
   286   "\<And>\<^raw:$zs$>. pred \<^raw:$zs$> \<Longrightarrow> rules[preds := \<^raw:$Ps$>] \<Longrightarrow> \<^raw:$P$>\<^raw:$zs$>"}
   287 
   287 
   288   where the given predicates are replaced by new ones written
   288   where the given predicates @{text preds} are replaced by new distinct 
   289   as @{text "\<^raw:$Ps$>"}, and also generate new variables 
   289   ones written as @{text "\<^raw:$Ps$>"}, and also need to be applied to
   290   @{text "\<^raw:$zs$>"}.
   290   new variables @{text "\<^raw:$zs$>"}. 
   291 *}
   291 
   292 
   292   The function below expects that the rules are already appropriately
   293 ML %linenosgray{* fun prove_induction lthy defs rules cnewpreds ((pred, newpred), tys)  =
   293   replaced. The argument @{text "mrules"} stands for these modified
       
   294   introduction rules; @{text cnewpreds} are the certified terms coresponding
       
   295   to the variables @{text "\<^raw:$Ps$>"}; @{text "pred"} is the predicate for
       
   296   which we prove the introduction principle; @{text "newpred"} is its
       
   297   replacement and @{text "tys"} are the types of its argument.
       
   298 *}
       
   299 
       
   300 ML %linenosgray{* fun prove_induction lthy defs mrules cnewpreds ((pred, newpred), tys)  =
   294 let
   301 let
   295   val zs = replicate (length tys) "z"
   302   val zs = replicate (length tys) "z"
   296   val (newargnames, lthy') = Variable.variant_fixes zs lthy;
   303   val (newargnames, lthy') = Variable.variant_fixes zs lthy;
   297   val newargs = map Free (newargnames ~~ tys)
   304   val newargs = map Free (newargnames ~~ tys)
   298   
   305   
   299   val prem = HOLogic.mk_Trueprop (list_comb (pred, newargs))
   306   val prem = HOLogic.mk_Trueprop (list_comb (pred, newargs))
   300   val goal = Logic.list_implies 
   307   val goal = Logic.list_implies 
   301          (rules, HOLogic.mk_Trueprop (list_comb (newpred, newargs)))
   308          (mrules, HOLogic.mk_Trueprop (list_comb (newpred, newargs)))
   302 in
   309 in
   303   Goal.prove lthy' [] [prem] goal
   310   Goal.prove lthy' [] [prem] goal
   304   (fn {prems, ...} => induction_tac defs prems cnewpreds)
   311   (fn {prems, ...} => induction_tac defs prems cnewpreds)
   305   |> singleton (ProofContext.export lthy' lthy)
   312   |> singleton (ProofContext.export lthy' lthy)
   306 end *}
   313 end *}
   307 
   314 
   308 text {* *}
   315 text {* 
       
   316   In Line 3 we produce a list of names @{text "\<^raw:$zs$>"} according to the type 
       
   317   list. Line 4 makes these names unique and declare them as \emph{free} (but fixed)
       
   318   variables. These variables are free in the new theory @{text "lthy'"}. In Line 5
       
   319   we just construct the terms corresponding to the variables. The term variables are
       
   320   applied to the predicate in Line 7 (this is the first premise 
       
   321   @{text "pred \<^raw:$zs$>"} of the induction principle). In Line 8 and 9
       
   322   we first the term  @{text "\<^raw:$P$>\<^raw:$zs$>"} and then add
       
   323   the (modified) introduction rules as premises.
       
   324 
       
   325   In Line 11 we set up the goal to be proved; call the induction tactic in
       
   326   Line 13. This returns a theorem. However, it is a theorem proved inside
       
   327   the local theory @{text "lthy'"} where the variables @{text "\<^raw:$zs$>"} are
       
   328   fixed, but free. By exporting this theorem from @{text "lthy'"} (which does contain
       
   329   the  @{text "\<^raw:$zs$>"} as free) to @{text "lthy"} (which does not), we
       
   330   obtain the desired quantifications @{text "\<And>\<^raw:$zs$>"}.
       
   331 
       
   332   So it is left to produce the modified rules and 
       
   333 *}
   309 
   334 
   310 ML %linenosgray{*fun inductions rules defs preds tyss lthy1  =
   335 ML %linenosgray{*fun inductions rules defs preds tyss lthy1  =
   311 let
   336 let
   312   val Ps = replicate (length preds) "P"
   337   val Ps = replicate (length preds) "P"
   313   val (newprednames, lthy2) = Variable.variant_fixes Ps lthy1
   338   val (newprednames, lthy2) = Variable.variant_fixes Ps lthy1