14 val dest_local_rules: Proof.context -> |
14 val dest_local_rules: Proof.context -> |
15 {type_cases: (string * thm) list, set_cases: (string * thm) list, |
15 {type_cases: (string * thm) list, set_cases: (string * thm) list, |
16 type_induct: (string * thm) list, set_induct: (string * thm) list} |
16 type_induct: (string * thm) list, set_induct: (string * thm) list} |
17 val print_local_rules: Proof.context -> unit |
17 val print_local_rules: Proof.context -> unit |
18 val vars_of: term -> term list |
18 val vars_of: term -> term list |
|
19 val concls_of: thm -> term list |
19 val cases_type_global: string -> theory attribute |
20 val cases_type_global: string -> theory attribute |
20 val cases_set_global: string -> theory attribute |
21 val cases_set_global: string -> theory attribute |
21 val cases_type_local: string -> Proof.context attribute |
22 val cases_type_local: string -> Proof.context attribute |
22 val cases_set_local: string -> Proof.context attribute |
23 val cases_set_local: string -> Proof.context attribute |
23 val induct_type_global: string -> theory attribute |
24 val induct_type_global: string -> theory attribute |
293 fun induct_tac (ctxt, (stripped, args)) facts = |
296 fun induct_tac (ctxt, (stripped, args)) facts = |
294 let |
297 let |
295 val sg = ProofContext.sign_of ctxt; |
298 val sg = ProofContext.sign_of ctxt; |
296 val cert = Thm.cterm_of sg; |
299 val cert = Thm.cterm_of sg; |
297 |
300 |
|
301 fun prep_var (x, Some t) = Some (cert x, cert t) |
|
302 | prep_var (_, None) = None; |
|
303 |
298 fun prep_inst (concl, ts) = |
304 fun prep_inst (concl, ts) = |
299 let val xs = vars_of concl; val n = length xs - length ts in |
305 let val xs = vars_of concl; val n = length xs - length ts in |
300 if n < 0 then error "More arguments given than in induction rule" |
306 if n < 0 then error "More variables than given than in induction rule" |
301 else map cert (Library.drop (n, xs)) ~~ map cert ts |
307 else mapfilter prep_var (Library.drop (n, xs) ~~ ts) |
302 end; |
308 end; |
303 |
309 |
304 fun inst_rule insts thm = |
310 fun inst_rule insts thm = |
305 Drule.cterm_instantiate (flat (map2 prep_inst |
311 let val concls = concls_of thm in |
306 (HOLogic.dest_conj (HOLogic.dest_Trueprop (Thm.concl_of thm)), insts))) thm; |
312 if length concls < length insts then |
|
313 error "More arguments than given than in induction rule" |
|
314 else Drule.cterm_instantiate (flat (map prep_inst (concls ~~ insts))) thm |
|
315 end; |
307 |
316 |
308 fun find_induct th = |
317 fun find_induct th = |
309 NetRules.may_unify (#2 (get_induct ctxt)) |
318 NetRules.may_unify (#2 (get_induct ctxt)) |
310 (Logic.strip_assums_concl (#prop (Thm.rep_thm th))); |
319 (Logic.strip_assums_concl (#prop (Thm.rep_thm th))); |
311 |
320 |
312 val rules = |
321 val rules = |
313 (case (args, facts) of |
322 (case (args, facts) of |
314 (([], None), []) => [] |
323 (([], None), []) => [] |
315 | ((insts, None), []) => |
324 | ((insts, None), []) => |
316 let val thms = map (induct_rule ctxt o last_elem) insts |
325 let val thms = map (induct_rule ctxt o last_elem o mapfilter I) insts |
|
326 handle Library.LIST _ => error "Unable to figure out type induction rule" |
317 in [(inst_rule insts (join_rules thms), RuleCases.get (#2 (hd thms)))] end |
327 in [(inst_rule insts (join_rules thms), RuleCases.get (#2 (hd thms)))] end |
318 | (([], None), th :: _) => map (RuleCases.add o #2) (find_induct th) |
328 | (([], None), th :: _) => map (RuleCases.add o #2) (find_induct th) |
319 | ((insts, None), th :: _) => |
329 | ((insts, None), th :: _) => |
320 (case find_induct th of (*may instantiate first rule only!*) |
330 (case find_induct th of (*may instantiate first rule only!*) |
321 (_, thm) :: _ => [(inst_rule insts thm, RuleCases.get thm)] |
331 (_, thm) :: _ => [(inst_rule insts thm, RuleCases.get thm)] |
390 val cases_rule = rule lookup_casesT lookup_casesS; |
400 val cases_rule = rule lookup_casesT lookup_casesS; |
391 val induct_rule = rule lookup_inductT lookup_inductS; |
401 val induct_rule = rule lookup_inductT lookup_inductS; |
392 |
402 |
393 val kind = (Args.$$$ typeN || Args.$$$ setN || Args.$$$ ruleN) -- Args.$$$ ":"; |
403 val kind = (Args.$$$ typeN || Args.$$$ setN || Args.$$$ ruleN) -- Args.$$$ ":"; |
394 val term = Scan.unless (Scan.lift kind) Args.local_term; |
404 val term = Scan.unless (Scan.lift kind) Args.local_term; |
|
405 val term_dummy = Scan.unless (Scan.lift kind) |
|
406 (Scan.lift (Args.$$$ "_") >> K None || Args.local_term >> Some); |
395 |
407 |
396 fun mode name = |
408 fun mode name = |
397 Scan.lift (Scan.optional (Args.$$$ name -- Args.$$$ ":" >> K true) false); |
409 Scan.lift (Scan.optional (Args.$$$ name -- Args.$$$ ":" >> K true) false); |
398 |
410 |
399 in |
411 in |
400 |
412 |
401 val cases_args = |
413 val cases_args = Method.syntax (mode simplifiedN -- (Scan.option term -- Scan.option cases_rule)); |
402 Method.syntax (mode simplifiedN -- (Scan.option term -- Scan.option cases_rule)); |
414 val induct_args = Method.syntax |
403 val induct_args = |
415 (mode strippedN -- (Args.and_list (Scan.repeat term_dummy) -- Scan.option induct_rule)); |
404 Method.syntax (mode strippedN -- (Args.and_list (Scan.repeat1 term) -- Scan.option induct_rule)); |
|
405 |
416 |
406 end; |
417 end; |
407 |
418 |
408 |
419 |
409 |
420 |