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} |
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 = |