author | wenzelm |
Sat, 13 Jun 2015 14:37:50 +0200 | |
changeset 60451 | 1f2b29f78439 |
parent 60313 | 2a0b42cd58fb |
child 60456 | 323b15b5af73 |
permissions | -rw-r--r-- |
8364 | 1 |
(* Title: Pure/Isar/rule_cases.ML |
2 |
Author: Markus Wenzel, TU Muenchen |
|
3 |
||
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
4 |
Annotations and local contexts of rules. |
8364 | 5 |
*) |
6 |
||
18188 | 7 |
infix 1 THEN_ALL_NEW_CASES; |
8 |
||
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
9 |
signature BASIC_RULE_CASES = |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
10 |
sig |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
11 |
type cases |
59660
49e498cedd02
support structural composition (THEN_ALL_NEW) for proof methods;
wenzelm
parents:
59582
diff
changeset
|
12 |
type cases_state = cases * thm |
49e498cedd02
support structural composition (THEN_ALL_NEW) for proof methods;
wenzelm
parents:
59582
diff
changeset
|
13 |
type cases_tactic = thm -> cases_state Seq.seq |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
14 |
val CASES: cases -> tactic -> cases_tactic |
59953 | 15 |
val EMPTY_CASES: tactic -> cases_tactic |
59971 | 16 |
val SUBGOAL_CASES: (term * int -> cases_tactic) -> int -> cases_tactic |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
17 |
val THEN_ALL_NEW_CASES: (int -> cases_tactic) * (int -> tactic) -> int -> cases_tactic |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
18 |
end |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
19 |
|
8364 | 20 |
signature RULE_CASES = |
21 |
sig |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
22 |
include BASIC_RULE_CASES |
18608 | 23 |
datatype T = Case of |
42496 | 24 |
{fixes: (binding * typ) list, |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
25 |
assumes: (binding * term list) list, |
18608 | 26 |
binds: (indexname * term option) list, |
27 |
cases: (string * T) list} |
|
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
28 |
val case_hypsN: string |
18608 | 29 |
val strip_params: term -> (string * typ) list |
59970 | 30 |
val make_common: Proof.context -> term -> |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
31 |
((string * string list) * string list) list -> cases |
59970 | 32 |
val make_nested: Proof.context -> term -> term -> |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
33 |
((string * string list) * string list) list -> cases |
18608 | 34 |
val apply: term list -> T -> T |
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
35 |
val consume: Proof.context -> thm list -> thm list -> ('a * int) * thm -> |
18237 | 36 |
(('a * (int * thm list)) * thm) Seq.seq |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
37 |
val get_consumes: thm -> int |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
38 |
val put_consumes: int option -> thm -> thm |
18477 | 39 |
val add_consumes: int -> thm -> thm |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
40 |
val default_consumes: int -> thm -> thm |
18728 | 41 |
val consumes: int -> attribute |
34986
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
42 |
val get_constraints: thm -> int |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
43 |
val constraints: int -> attribute |
8364 | 44 |
val name: string list -> thm -> thm |
18728 | 45 |
val case_names: string list -> attribute |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
46 |
val cases_hyp_names: string list -> string list list -> attribute |
18728 | 47 |
val case_conclusion: string * string list -> attribute |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
48 |
val is_inner_rule: thm -> bool |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
49 |
val inner_rule: attribute |
12761 | 50 |
val save: thm -> thm -> thm |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
51 |
val get: thm -> ((string * string list) * string list) list * int |
8427 | 52 |
val rename_params: string list list -> thm -> thm |
18728 | 53 |
val params: string list list -> attribute |
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
54 |
val internalize_params: thm -> thm |
20289 | 55 |
val mutual_rule: Proof.context -> thm list -> (int list * thm) option |
56 |
val strict_mutual_rule: Proof.context -> thm list -> int list * thm |
|
8364 | 57 |
end; |
58 |
||
33368 | 59 |
structure Rule_Cases: RULE_CASES = |
8364 | 60 |
struct |
61 |
||
18608 | 62 |
(** cases **) |
63 |
||
64 |
datatype T = Case of |
|
42496 | 65 |
{fixes: (binding * typ) list, |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
66 |
assumes: (binding * term list) list, |
18608 | 67 |
binds: (indexname * term option) list, |
68 |
cases: (string * T) list}; |
|
69 |
||
70 |
type cases = (string * T option) list; |
|
71 |
||
72 |
val case_conclN = "case"; |
|
73 |
val case_hypsN = "hyps"; |
|
74 |
val case_premsN = "prems"; |
|
75 |
||
20087 | 76 |
val strip_params = map (apfst (perhaps (try Name.dest_skolem))) o Logic.strip_params; |
18608 | 77 |
|
78 |
local |
|
79 |
||
80 |
fun app us t = Term.betapplys (t, us); |
|
81 |
||
82 |
fun dest_binops cs tm = |
|
83 |
let |
|
84 |
val n = length cs; |
|
85 |
fun dest 0 _ = [] |
|
86 |
| dest 1 t = [t] |
|
87 |
| dest k (_ $ t $ u) = t :: dest (k - 1) u |
|
88 |
| dest _ _ = raise TERM ("Expected " ^ string_of_int n ^ " binop arguments", [tm]); |
|
89 |
in cs ~~ dest n tm end; |
|
90 |
||
91 |
fun extract_fixes NONE prop = (strip_params prop, []) |
|
92 |
| extract_fixes (SOME outline) prop = |
|
19012 | 93 |
chop (length (Logic.strip_params outline)) (strip_params prop); |
18608 | 94 |
|
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
95 |
fun extract_assumes _ _ NONE prop = ([(Binding.empty, Logic.strip_assums_hyp prop)], []) |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
96 |
| extract_assumes qualifier hyp_names (SOME outline) prop = |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
97 |
let |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
98 |
val qual = Binding.qualify true qualifier o Binding.name; |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
99 |
val (hyps, prems) = |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
100 |
chop (length (Logic.strip_assums_hyp outline)) (Logic.strip_assums_hyp prop) |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
101 |
fun extract ((hyp_name, hyp) :: rest) = (qual hyp_name, hyp :: map snd rest); |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
102 |
val (hyps1, hyps2) = chop (length hyp_names) hyps; |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
103 |
val pairs1 = if null hyps1 then [] else hyp_names ~~ hyps1; |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
104 |
val pairs = pairs1 @ map (pair case_hypsN) hyps2; |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
105 |
val named_hyps = map extract (partition_eq (eq_fst op =) pairs); |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
106 |
in (named_hyps, [(qual case_premsN, prems)]) end; |
18608 | 107 |
|
42496 | 108 |
fun bindings args = map (apfst Binding.name) args; |
109 |
||
59970 | 110 |
fun extract_case ctxt (case_outline, raw_prop) name hyp_names concls = |
18608 | 111 |
let |
59970 | 112 |
val props = Logic.dest_conjunctions (Drule.norm_hhf (Proof_Context.theory_of ctxt) raw_prop); |
18608 | 113 |
val len = length props; |
114 |
val nested = is_some case_outline andalso len > 1; |
|
115 |
||
116 |
fun extract prop = |
|
117 |
let |
|
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
118 |
val (fixes1, fixes2) = extract_fixes case_outline prop; |
46219
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
wenzelm
parents:
45525
diff
changeset
|
119 |
val abs_fixes = fold_rev Term.abs (fixes1 @ fixes2); |
18608 | 120 |
fun abs_fixes1 t = |
121 |
if not nested then abs_fixes t |
|
46219
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
wenzelm
parents:
45525
diff
changeset
|
122 |
else |
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
wenzelm
parents:
45525
diff
changeset
|
123 |
fold_rev Term.abs fixes1 |
426ed18eba43
discontinued old-style Term.list_abs in favour of plain Term.abs;
wenzelm
parents:
45525
diff
changeset
|
124 |
(app (map (Term.dummy_pattern o #2) fixes2) (fold_rev Term.abs fixes2 t)); |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
125 |
val (assumes1, assumes2) = |
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
126 |
extract_assumes name hyp_names case_outline prop |
59058
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents:
58950
diff
changeset
|
127 |
|> apply2 (map (apsnd (maps Logic.dest_conjunctions))); |
18608 | 128 |
|
59970 | 129 |
val concl = Object_Logic.drop_judgment ctxt (Logic.strip_assums_concl prop); |
18608 | 130 |
val binds = |
131 |
(case_conclN, concl) :: dest_binops concls concl |
|
132 |
|> map (fn (x, t) => ((x, 0), SOME (abs_fixes t))); |
|
133 |
in |
|
134 |
((fixes1, map (apsnd (map abs_fixes1)) assumes1), |
|
135 |
((fixes2, map (apsnd (map abs_fixes)) assumes2), binds)) |
|
136 |
end; |
|
137 |
||
138 |
val cases = map extract props; |
|
139 |
||
140 |
fun common_case ((fixes1, assumes1), ((fixes2, assumes2), binds)) = |
|
42496 | 141 |
Case {fixes = bindings (fixes1 @ fixes2), |
142 |
assumes = assumes1 @ assumes2, binds = binds, cases = []}; |
|
18608 | 143 |
fun inner_case (_, ((fixes2, assumes2), binds)) = |
42496 | 144 |
Case {fixes = bindings fixes2, assumes = assumes2, binds = binds, cases = []}; |
18608 | 145 |
fun nested_case ((fixes1, assumes1), _) = |
42496 | 146 |
Case {fixes = bindings fixes1, assumes = assumes1, binds = [], |
18608 | 147 |
cases = map string_of_int (1 upto len) ~~ map inner_case cases}; |
148 |
in |
|
149 |
if len = 0 then NONE |
|
150 |
else if len = 1 then SOME (common_case (hd cases)) |
|
19046
bc5c6c9b114e
removed distinct, renamed gen_distinct to distinct;
wenzelm
parents:
19012
diff
changeset
|
151 |
else if is_none case_outline orelse length (distinct (op =) (map fst cases)) > 1 then NONE |
18608 | 152 |
else SOME (nested_case (hd cases)) |
153 |
end; |
|
154 |
||
59970 | 155 |
fun make ctxt rule_struct prop cases = |
18608 | 156 |
let |
157 |
val n = length cases; |
|
21576 | 158 |
val nprems = Logic.count_prems prop; |
53380
08f3491c50bf
cases: formal binding of 'assumes', with position provided via invoke_case;
wenzelm
parents:
46219
diff
changeset
|
159 |
fun add_case ((name, hyp_names), concls) (cs, i) = |
18608 | 160 |
((case try (fn () => |
161 |
(Option.map (curry Logic.nth_prem i) rule_struct, Logic.nth_prem (i, prop))) () of |
|
162 |
NONE => (name, NONE) |
|
59970 | 163 |
| SOME p => (name, extract_case ctxt p name hyp_names concls)) :: cs, i - 1); |
34058 | 164 |
in fold_rev add_case (drop (Int.max (n - nprems, 0)) cases) ([], n) |> #1 end; |
18608 | 165 |
|
166 |
in |
|
167 |
||
59970 | 168 |
fun make_common ctxt = make ctxt NONE; |
169 |
fun make_nested ctxt rule_struct = make ctxt (SOME rule_struct); |
|
18608 | 170 |
|
171 |
fun apply args = |
|
172 |
let |
|
173 |
fun appl (Case {fixes, assumes, binds, cases}) = |
|
174 |
let |
|
175 |
val assumes' = map (apsnd (map (app args))) assumes; |
|
176 |
val binds' = map (apsnd (Option.map (app args))) binds; |
|
177 |
val cases' = map (apsnd appl) cases; |
|
178 |
in Case {fixes = fixes, assumes = assumes', binds = binds', cases = cases'} end; |
|
179 |
in appl end; |
|
180 |
||
181 |
end; |
|
182 |
||
183 |
||
184 |
||
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
185 |
(** tactics with cases **) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
186 |
|
59660
49e498cedd02
support structural composition (THEN_ALL_NEW) for proof methods;
wenzelm
parents:
59582
diff
changeset
|
187 |
type cases_state = cases * thm; |
49e498cedd02
support structural composition (THEN_ALL_NEW) for proof methods;
wenzelm
parents:
59582
diff
changeset
|
188 |
type cases_tactic = thm -> cases_state Seq.seq; |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
189 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
190 |
fun CASES cases tac st = Seq.map (pair cases) (tac st); |
59953 | 191 |
fun EMPTY_CASES tac = CASES [] tac; |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
192 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
193 |
fun SUBGOAL_CASES tac i st = |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
194 |
(case try Logic.nth_prem (i, Thm.prop_of st) of |
59971 | 195 |
SOME goal => tac (goal, i) st |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
196 |
| NONE => Seq.empty); |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
197 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
198 |
fun (tac1 THEN_ALL_NEW_CASES tac2) i st = |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
199 |
st |> tac1 i |> Seq.maps (fn (cases, st') => |
59582 | 200 |
CASES cases (Seq.INTERVAL tac2 i (i + Thm.nprems_of st' - Thm.nprems_of st)) st'); |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
201 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
202 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
203 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
204 |
(** consume facts **) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
205 |
|
18477 | 206 |
local |
207 |
||
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
208 |
fun unfold_prems ctxt n defs th = |
18477 | 209 |
if null defs then th |
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
210 |
else Conv.fconv_rule (Conv.prems_conv n (Raw_Simplifier.rewrite ctxt true defs)) th; |
18477 | 211 |
|
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
212 |
fun unfold_prems_concls ctxt defs th = |
18477 | 213 |
if null defs orelse not (can Logic.dest_conjunction (Thm.concl_of th)) then th |
214 |
else |
|
22900 | 215 |
Conv.fconv_rule |
23418 | 216 |
(Conv.concl_conv ~1 (Conjunction.convs |
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
217 |
(Conv.prems_conv ~1 (Raw_Simplifier.rewrite ctxt true defs)))) th; |
18477 | 218 |
|
219 |
in |
|
220 |
||
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
221 |
fun consume ctxt defs facts ((xx, n), th) = |
18237 | 222 |
let val m = Int.min (length facts, n) in |
18477 | 223 |
th |
54742
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
224 |
|> unfold_prems ctxt n defs |
7a86358a3c0b
proper context for basic Simplifier operations: rewrite_rule, rewrite_goals_rule, rewrite_goals_tac etc.;
wenzelm
parents:
53380
diff
changeset
|
225 |
|> unfold_prems_concls ctxt defs |
58950
d07464875dd4
optional proof context for unify operations, for the sake of proper local options;
wenzelm
parents:
58014
diff
changeset
|
226 |
|> Drule.multi_resolve (SOME ctxt) (take m facts) |
33957 | 227 |
|> Seq.map (pair (xx, (n - m, drop m facts))) |
18237 | 228 |
end; |
10811 | 229 |
|
18477 | 230 |
end; |
231 |
||
10811 | 232 |
val consumes_tagN = "consumes"; |
233 |
||
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
234 |
fun lookup_consumes th = |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
235 |
(case AList.lookup (op =) (Thm.get_tags th) consumes_tagN of |
23657 | 236 |
NONE => NONE |
237 |
| SOME s => |
|
55639 | 238 |
(case Lexicon.read_nat s of |
239 |
SOME n => SOME n |
|
23657 | 240 |
| _ => raise THM ("Malformed 'consumes' tag of theorem", 0, [th]))); |
10530 | 241 |
|
18477 | 242 |
fun get_consumes th = the_default 0 (lookup_consumes th); |
243 |
||
15531 | 244 |
fun put_consumes NONE th = th |
245 |
| put_consumes (SOME n) th = th |
|
27865
27a8ad9612a3
moved basic thm operations from structure PureThy to Thm (cf. more_thm.ML);
wenzelm
parents:
26923
diff
changeset
|
246 |
|> Thm.untag_rule consumes_tagN |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
247 |
|> Thm.tag_rule (consumes_tagN, string_of_int (if n < 0 then Thm.nprems_of th + n else n)); |
10530 | 248 |
|
18477 | 249 |
fun add_consumes k th = put_consumes (SOME (k + get_consumes th)) th; |
250 |
||
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
251 |
fun default_consumes n th = |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
252 |
if is_some (lookup_consumes th) then th else put_consumes (SOME n) th; |
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
253 |
|
12761 | 254 |
val save_consumes = put_consumes o lookup_consumes; |
255 |
||
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
256 |
fun consumes n = Thm.mixed_attribute (apsnd (put_consumes (SOME n))); |
21395
f34ac19659ae
moved some fundamental concepts to General/basics.ML;
wenzelm
parents:
20289
diff
changeset
|
257 |
|
8364 | 258 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
259 |
|
34986
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
260 |
(** equality constraints **) |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
261 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
262 |
val constraints_tagN = "constraints"; |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
263 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
264 |
fun lookup_constraints th = |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
265 |
(case AList.lookup (op =) (Thm.get_tags th) constraints_tagN of |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
266 |
NONE => NONE |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
267 |
| SOME s => |
55639 | 268 |
(case Lexicon.read_nat s of |
269 |
SOME n => SOME n |
|
34986
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
270 |
| _ => raise THM ("Malformed 'constraints' tag of theorem", 0, [th]))); |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
271 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
272 |
fun get_constraints th = the_default 0 (lookup_constraints th); |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
273 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
274 |
fun put_constraints NONE th = th |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
275 |
| put_constraints (SOME n) th = th |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
276 |
|> Thm.untag_rule constraints_tagN |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
277 |
|> Thm.tag_rule (constraints_tagN, string_of_int (if n < 0 then 0 else n)); |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
278 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
279 |
val save_constraints = put_constraints o lookup_constraints; |
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
280 |
|
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
281 |
fun constraints n = Thm.mixed_attribute (apsnd (put_constraints (SOME n))); |
34986
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
282 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
283 |
|
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
284 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
285 |
(** case names **) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
286 |
|
23657 | 287 |
val implode_args = space_implode ";"; |
288 |
val explode_args = space_explode ";"; |
|
289 |
||
18237 | 290 |
val case_names_tagN = "case_names"; |
8364 | 291 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
292 |
fun add_case_names NONE = I |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
293 |
| add_case_names (SOME names) = |
27865
27a8ad9612a3
moved basic thm operations from structure PureThy to Thm (cf. more_thm.ML);
wenzelm
parents:
26923
diff
changeset
|
294 |
Thm.untag_rule case_names_tagN |
27a8ad9612a3
moved basic thm operations from structure PureThy to Thm (cf. more_thm.ML);
wenzelm
parents:
26923
diff
changeset
|
295 |
#> Thm.tag_rule (case_names_tagN, implode_args names); |
8364 | 296 |
|
23657 | 297 |
fun lookup_case_names th = |
298 |
AList.lookup (op =) (Thm.get_tags th) case_names_tagN |
|
299 |
|> Option.map explode_args; |
|
10530 | 300 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
301 |
val save_case_names = add_case_names o lookup_case_names; |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
302 |
val name = add_case_names o SOME; |
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
303 |
fun case_names cs = Thm.mixed_attribute (apsnd (name cs)); |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
304 |
|
8364 | 305 |
|
10530 | 306 |
|
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
307 |
(** hyp names **) |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
308 |
|
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
309 |
val implode_hyps = implode_args o map (suffix "," o space_implode ","); |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
310 |
val explode_hyps = map (space_explode "," o unsuffix ",") o explode_args; |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
311 |
|
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
312 |
val cases_hyp_names_tagN = "cases_hyp_names"; |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
313 |
|
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
314 |
fun add_cases_hyp_names NONE = I |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
315 |
| add_cases_hyp_names (SOME namess) = |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
316 |
Thm.untag_rule cases_hyp_names_tagN |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
317 |
#> Thm.tag_rule (cases_hyp_names_tagN, implode_hyps namess); |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
318 |
|
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
319 |
fun lookup_cases_hyp_names th = |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
320 |
AList.lookup (op =) (Thm.get_tags th) cases_hyp_names_tagN |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
321 |
|> Option.map explode_hyps; |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
322 |
|
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
323 |
val save_cases_hyp_names = add_cases_hyp_names o lookup_cases_hyp_names; |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
324 |
fun cases_hyp_names cs hs = |
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
325 |
Thm.mixed_attribute (apsnd (name cs #> add_cases_hyp_names (SOME hs))); |
45375
7fe19930dfc9
more explicit representation of rule_attribute vs. declaration_attribute vs. mixed_attribute;
wenzelm
parents:
45328
diff
changeset
|
326 |
|
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
327 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
328 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
329 |
(** case conclusions **) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
330 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
331 |
val case_concl_tagN = "case_conclusion"; |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
332 |
|
23657 | 333 |
fun get_case_concl name (a, b) = |
334 |
if a = case_concl_tagN then |
|
58014 | 335 |
(case explode_args b of |
336 |
c :: cs => if c = name then SOME cs else NONE |
|
337 |
| [] => NONE) |
|
23657 | 338 |
else NONE; |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
339 |
|
21646
c07b5b0e8492
thm/prf: separate official name vs. additional tags;
wenzelm
parents:
21576
diff
changeset
|
340 |
fun add_case_concl (name, cs) = Thm.map_tags (fn tags => |
23657 | 341 |
filter_out (is_some o get_case_concl name) tags @ |
342 |
[(case_concl_tagN, implode_args (name :: cs))]); |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
343 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
344 |
fun get_case_concls th name = |
23657 | 345 |
these (get_first (get_case_concl name) (Thm.get_tags th)); |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
346 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
347 |
fun save_case_concls th = |
21646
c07b5b0e8492
thm/prf: separate official name vs. additional tags;
wenzelm
parents:
21576
diff
changeset
|
348 |
let val concls = Thm.get_tags th |> map_filter |
23657 | 349 |
(fn (a, b) => |
55639 | 350 |
if a = case_concl_tagN |
351 |
then (case explode_args b of c :: cs => SOME (c, cs) | _ => NONE) |
|
23657 | 352 |
else NONE) |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
353 |
in fold add_case_concl concls end; |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
354 |
|
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
355 |
fun case_conclusion concl = Thm.mixed_attribute (apsnd (add_case_concl concl)); |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
356 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
357 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
358 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
359 |
(** inner rule **) |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
360 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
361 |
val inner_rule_tagN = "inner_rule"; |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
362 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
363 |
fun is_inner_rule th = |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
364 |
AList.defined (op =) (Thm.get_tags th) inner_rule_tagN; |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
365 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
366 |
fun put_inner_rule inner = |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
367 |
Thm.untag_rule inner_rule_tagN |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
368 |
#> inner ? Thm.tag_rule (inner_rule_tagN, ""); |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
369 |
|
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
370 |
val save_inner_rule = put_inner_rule o is_inner_rule; |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
371 |
|
45525
59561859c452
tagging is not stable under morphisms and need to be replayed dynamically (mixed_attribute);
wenzelm
parents:
45375
diff
changeset
|
372 |
val inner_rule = Thm.mixed_attribute (apsnd (put_inner_rule true)); |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
373 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
374 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
375 |
|
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
376 |
(** case declarations **) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
377 |
|
10530 | 378 |
(* access hints *) |
379 |
||
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
380 |
fun save th = |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
381 |
save_consumes th #> |
34986
7f7939c9370f
Added "constraints" tag / attribute for specifying the number of equality
berghofe
parents:
34916
diff
changeset
|
382 |
save_constraints th #> |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
383 |
save_case_names th #> |
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
384 |
save_cases_hyp_names th #> |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
385 |
save_case_concls th #> |
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
386 |
save_inner_rule th; |
12761 | 387 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
388 |
fun get th = |
12761 | 389 |
let |
18477 | 390 |
val n = get_consumes th; |
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
391 |
val cases = |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
392 |
(case lookup_case_names th of |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
393 |
NONE => map (rpair [] o Library.string_of_int) (1 upto (Thm.nprems_of th - n)) |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
394 |
| SOME names => map (fn name => (name, get_case_concls th name)) names); |
55639 | 395 |
val cases_hyps = |
396 |
(case lookup_cases_hyp_names th of |
|
44045
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
397 |
NONE => replicate (length cases) [] |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
398 |
| SOME names => names); |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
399 |
fun regroup ((name,concls),hyps) = ((name,hyps),concls) |
2814ff2a6e3e
infrastructure for attaching names to hypothesis in cases; realised via the same tag mechanism as case names
nipkow
parents:
42496
diff
changeset
|
400 |
in (map regroup (cases ~~ cases_hyps), n) end; |
10530 | 401 |
|
8364 | 402 |
|
8427 | 403 |
(* params *) |
8364 | 404 |
|
18229
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
405 |
fun rename_params xss th = |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
406 |
th |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
407 |
|> fold_index (fn (i, xs) => Thm.rename_params_rule (xs, i + 1)) xss |
e5a624483a23
added type cases/cases_tactic, and CASES, SUBGOAL_CASES;
wenzelm
parents:
18188
diff
changeset
|
408 |
|> save th; |
8364 | 409 |
|
18728 | 410 |
fun params xss = Thm.rule_attribute (K (rename_params xss)); |
8364 | 411 |
|
18477 | 412 |
|
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
413 |
(* internalize parameter names *) |
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
414 |
|
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
415 |
fun internalize_params rule = |
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
416 |
let |
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
417 |
fun rename prem = |
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
418 |
let val xs = |
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
419 |
map (Name.internal o Name.clean o fst) (Logic.strip_params prem) |
45328 | 420 |
in Logic.list_rename_params xs prem end; |
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
421 |
fun rename_prems prop = |
36354 | 422 |
let val (As, C) = Logic.strip_horn prop |
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
423 |
in Logic.list_implies (map rename As, C) end; |
60313 | 424 |
in Thm.renamed_prop (rename_prems (Thm.prop_of rule)) rule end; |
34916
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
425 |
|
f625d8d6fcf3
Eliminated is_open option of Rule_Cases.make_nested/make_common;
berghofe
parents:
34058
diff
changeset
|
426 |
|
18477 | 427 |
|
428 |
(** mutual_rule **) |
|
429 |
||
430 |
local |
|
431 |
||
432 |
fun equal_cterms ts us = |
|
59058
a78612c67ec0
renamed "pairself" to "apply2", in accordance to @{apply 2};
wenzelm
parents:
58950
diff
changeset
|
433 |
is_equal (list_ord (Term_Ord.fast_term_ord o apply2 Thm.term_of) (ts, us)); |
18477 | 434 |
|
19917 | 435 |
fun prep_rule n th = |
18477 | 436 |
let |
19917 | 437 |
val th' = Thm.permute_prems 0 n th; |
33957 | 438 |
val prems = take (Thm.nprems_of th' - n) (Drule.cprems_of th'); |
18477 | 439 |
val th'' = Drule.implies_elim_list th' (map Thm.assume prems); |
440 |
in (prems, (n, th'')) end; |
|
441 |
||
442 |
in |
|
443 |
||
19917 | 444 |
fun mutual_rule _ [] = NONE |
445 |
| mutual_rule _ [th] = SOME ([0], th) |
|
446 |
| mutual_rule ctxt (ths as th :: _) = |
|
18477 | 447 |
let |
31794
71af1fd6a5e4
renamed Variable.import_thms to Variable.import (back again cf. ed7aa5a350ef -- Alice is no longer supported);
wenzelm
parents:
30364
diff
changeset
|
448 |
val ((_, ths'), ctxt') = Variable.import true ths ctxt; |
19917 | 449 |
val rules as (prems, _) :: _ = map (prep_rule (get_consumes th)) ths'; |
450 |
val (ns, rls) = split_list (map #2 rules); |
|
18477 | 451 |
in |
452 |
if not (forall (equal_cterms prems o #1) rules) then NONE |
|
453 |
else |
|
454 |
SOME (ns, |
|
19917 | 455 |
rls |
23418 | 456 |
|> Conjunction.intr_balanced |
18477 | 457 |
|> Drule.implies_intr_list prems |
19917 | 458 |
|> singleton (Variable.export ctxt' ctxt) |
459 |
|> save th |
|
18477 | 460 |
|> put_consumes (SOME 0)) |
461 |
end; |
|
462 |
||
463 |
end; |
|
464 |
||
19917 | 465 |
fun strict_mutual_rule ctxt ths = |
466 |
(case mutual_rule ctxt ths of |
|
18581 | 467 |
NONE => error "Failed to join given rules into one mutual rule" |
468 |
| SOME res => res); |
|
469 |
||
8364 | 470 |
end; |
17113 | 471 |
|
33368 | 472 |
structure Basic_Rule_Cases: BASIC_RULE_CASES = Rule_Cases; |
33303
1e1210f31207
separate "inner_rule" tag indicates parts of induction rules -- avoids unclear overlap with "internal" tag;
wenzelm
parents:
31794
diff
changeset
|
473 |
open Basic_Rule_Cases; |