23 {fixes: (string * typ) list, |
23 {fixes: (string * typ) list, |
24 assumes: (string * term list) list, |
24 assumes: (string * term list) list, |
25 binds: (indexname * term option) list, |
25 binds: (indexname * term option) list, |
26 cases: (string * T) list} |
26 cases: (string * T) list} |
27 val strip_params: term -> (string * typ) list |
27 val strip_params: term -> (string * typ) list |
28 val make_common: bool -> theory * term -> (string * string list) list -> cases |
28 val make_common: theory * term -> (string * string list) list -> cases |
29 val make_nested: bool -> term -> theory * term -> (string * string list) list -> cases |
29 val make_nested: term -> theory * term -> (string * string list) list -> cases |
30 val apply: term list -> T -> T |
30 val apply: term list -> T -> T |
31 val consume: thm list -> thm list -> ('a * int) * thm -> |
31 val consume: thm list -> thm list -> ('a * int) * thm -> |
32 (('a * (int * thm list)) * thm) Seq.seq |
32 (('a * (int * thm list)) * thm) Seq.seq |
33 val add_consumes: int -> thm -> thm |
33 val add_consumes: int -> thm -> thm |
34 val get_consumes: thm -> int |
34 val get_consumes: thm -> int |
41 val inner_rule: attribute |
41 val inner_rule: attribute |
42 val save: thm -> thm -> thm |
42 val save: thm -> thm -> thm |
43 val get: thm -> (string * string list) list * int |
43 val get: thm -> (string * string list) list * int |
44 val rename_params: string list list -> thm -> thm |
44 val rename_params: string list list -> thm -> thm |
45 val params: string list list -> attribute |
45 val params: string list list -> attribute |
|
46 val internalize_params: thm -> thm |
46 val mutual_rule: Proof.context -> thm list -> (int list * thm) option |
47 val mutual_rule: Proof.context -> thm list -> (int list * thm) option |
47 val strict_mutual_rule: Proof.context -> thm list -> int list * thm |
48 val strict_mutual_rule: Proof.context -> thm list -> int list * thm |
48 end; |
49 end; |
49 |
50 |
50 structure Rule_Cases: RULE_CASES = |
51 structure Rule_Cases: RULE_CASES = |
88 | extract_assumes qual (SOME outline) prop = |
89 | extract_assumes qual (SOME outline) prop = |
89 let val (hyps, prems) = |
90 let val (hyps, prems) = |
90 chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop) |
91 chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop) |
91 in ([(qual case_hypsN, hyps)], [(qual case_premsN, prems)]) end; |
92 in ([(qual case_hypsN, hyps)], [(qual case_premsN, prems)]) end; |
92 |
93 |
93 fun extract_case is_open thy (case_outline, raw_prop) name concls = |
94 fun extract_case thy (case_outline, raw_prop) name concls = |
94 let |
95 let |
95 val rename = if is_open then I else apfst (Name.internal o Name.clean); |
|
96 |
|
97 val props = Logic.dest_conjunctions (Drule.norm_hhf thy raw_prop); |
96 val props = Logic.dest_conjunctions (Drule.norm_hhf thy raw_prop); |
98 val len = length props; |
97 val len = length props; |
99 val nested = is_some case_outline andalso len > 1; |
98 val nested = is_some case_outline andalso len > 1; |
100 |
99 |
101 fun extract prop = |
100 fun extract prop = |
102 let |
101 let |
103 val (fixes1, fixes2) = extract_fixes case_outline prop |
102 val (fixes1, fixes2) = extract_fixes case_outline prop; |
104 |> apfst (map rename); |
|
105 val abs_fixes = abs (fixes1 @ fixes2); |
103 val abs_fixes = abs (fixes1 @ fixes2); |
106 fun abs_fixes1 t = |
104 fun abs_fixes1 t = |
107 if not nested then abs_fixes t |
105 if not nested then abs_fixes t |
108 else abs fixes1 (app (map (Term.dummy_pattern o #2) fixes2) (abs fixes2 t)); |
106 else abs fixes1 (app (map (Term.dummy_pattern o #2) fixes2) (abs fixes2 t)); |
109 |
107 |
133 else if len = 1 then SOME (common_case (hd cases)) |
131 else if len = 1 then SOME (common_case (hd cases)) |
134 else if is_none case_outline orelse length (distinct (op =) (map fst cases)) > 1 then NONE |
132 else if is_none case_outline orelse length (distinct (op =) (map fst cases)) > 1 then NONE |
135 else SOME (nested_case (hd cases)) |
133 else SOME (nested_case (hd cases)) |
136 end; |
134 end; |
137 |
135 |
138 fun make is_open rule_struct (thy, prop) cases = |
136 fun make rule_struct (thy, prop) cases = |
139 let |
137 let |
140 val n = length cases; |
138 val n = length cases; |
141 val nprems = Logic.count_prems prop; |
139 val nprems = Logic.count_prems prop; |
142 fun add_case (name, concls) (cs, i) = |
140 fun add_case (name, concls) (cs, i) = |
143 ((case try (fn () => |
141 ((case try (fn () => |
144 (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of |
142 (Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of |
145 NONE => (name, NONE) |
143 NONE => (name, NONE) |
146 | SOME p => (name, extract_case is_open thy p name concls)) :: cs, i - 1); |
144 | SOME p => (name, extract_case thy p name concls)) :: cs, i - 1); |
147 in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end; |
145 in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end; |
148 |
146 |
149 in |
147 in |
150 |
148 |
151 fun make_common is_open = make is_open NONE; |
149 val make_common = make NONE; |
152 fun make_nested is_open rule_struct = make is_open (SOME rule_struct); |
150 fun make_nested rule_struct = make (SOME rule_struct); |
153 |
151 |
154 fun apply args = |
152 fun apply args = |
155 let |
153 let |
156 fun appl (Case {fixes, assumes, binds, cases}) = |
154 fun appl (Case {fixes, assumes, binds, cases}) = |
157 let |
155 let |
330 th |
328 th |
331 |> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss |
329 |> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss |
332 |> save th; |
330 |> save th; |
333 |
331 |
334 fun params xss = Thm.rule_attribute (K (rename_params xss)); |
332 fun params xss = Thm.rule_attribute (K (rename_params xss)); |
|
333 |
|
334 |
|
335 (* internalize parameter names *) |
|
336 |
|
337 fun internalize_params rule = |
|
338 let |
|
339 fun rename prem = |
|
340 let val xs = |
|
341 map (Name.internal o Name.clean o fst) (Logic.strip_params prem) |
|
342 in Logic.list_rename_params (xs, prem) end; |
|
343 fun rename_prems prop = |
|
344 let val (As, C) = Logic.strip_horn (Thm.prop_of rule) |
|
345 in Logic.list_implies (map rename As, C) end; |
|
346 in Thm.equal_elim (Thm.reflexive (Drule.cterm_fun rename_prems (Thm.cprop_of rule))) rule end; |
335 |
347 |
336 |
348 |
337 |
349 |
338 (** mutual_rule **) |
350 (** mutual_rule **) |
339 |
351 |