| author | wenzelm |
| Tue, 16 Jul 2002 18:41:50 +0200 | |
| changeset 13377 | cc8245843abc |
| parent 12809 | 787ecc2ac737 |
| child 13425 | 119ae829ad9b |
| permissions | -rw-r--r-- |
| 8364 | 1 |
(* Title: Pure/Isar/rule_cases.ML |
2 |
ID: $Id$ |
|
3 |
Author: Markus Wenzel, TU Muenchen |
|
| 8807 | 4 |
License: GPL (GNU GENERAL PUBLIC LICENSE) |
| 8364 | 5 |
|
6 |
Manage local contexts of rules. |
|
7 |
*) |
|
8 |
||
9 |
signature RULE_CASES = |
|
10 |
sig |
|
| 10530 | 11 |
val consumes: int -> 'a attribute |
12 |
val consumes_default: int -> 'a attribute |
|
| 8364 | 13 |
val name: string list -> thm -> thm |
| 8427 | 14 |
val case_names: string list -> 'a attribute |
| 12761 | 15 |
val save: thm -> thm -> thm |
| 10530 | 16 |
val get: thm -> string list * int |
17 |
val add: thm -> thm * (string list * int) |
|
| 10811 | 18 |
type T |
| 12166 | 19 |
val empty: T |
|
12809
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
20 |
val make: bool -> Sign.sg * term -> string list -> (string * T) list |
| 8427 | 21 |
val rename_params: string list list -> thm -> thm |
| 8364 | 22 |
val params: string list list -> 'a attribute |
23 |
end; |
|
24 |
||
25 |
structure RuleCases: RULE_CASES = |
|
26 |
struct |
|
27 |
||
| 10811 | 28 |
(* names *) |
29 |
||
30 |
val consumes_tagN = "consumes"; |
|
31 |
val cases_tagN = "cases"; |
|
32 |
val case_conclN = "case"; |
|
33 |
||
34 |
||
| 10530 | 35 |
(* number of consumed facts *) |
| 8364 | 36 |
|
| 12761 | 37 |
fun lookup_consumes thm = |
| 10530 | 38 |
let fun err () = raise THM ("Malformed 'consumes' tag of theorem", 0, [thm]) in
|
| 12761 | 39 |
(case Library.assoc (Thm.tags_of_thm thm, consumes_tagN) of |
40 |
None => None |
|
41 |
| Some [s] => (case Syntax.read_nat s of Some n => Some n | _ => err ()) |
|
| 10530 | 42 |
| _ => err ()) |
43 |
end; |
|
44 |
||
| 12761 | 45 |
fun put_consumes None th = th |
46 |
| put_consumes (Some n) th = th |
|
47 |
|> Drule.untag_rule consumes_tagN |
|
48 |
|> Drule.tag_rule (consumes_tagN, [Library.string_of_int n]); |
|
| 10530 | 49 |
|
| 12761 | 50 |
val save_consumes = put_consumes o lookup_consumes; |
51 |
||
52 |
fun consumes n x = Drule.rule_attribute (K (put_consumes (Some n))) x; |
|
| 10530 | 53 |
fun consumes_default n x = if Library.is_some (lookup_consumes (#2 x)) then x else consumes n x; |
| 8364 | 54 |
|
55 |
||
56 |
(* case names *) |
|
57 |
||
| 12761 | 58 |
fun put_case_names None thm = thm |
59 |
| put_case_names (Some names) thm = |
|
60 |
thm |
|
61 |
|> Drule.untag_rule cases_tagN |
|
62 |
|> Drule.tag_rule (cases_tagN, names); |
|
| 8364 | 63 |
|
| 12761 | 64 |
fun lookup_case_names thm = Library.assoc (Thm.tags_of_thm thm, cases_tagN); |
| 10530 | 65 |
|
| 12761 | 66 |
val save_case_names = put_case_names o lookup_case_names; |
67 |
val name = put_case_names o Some; |
|
| 8427 | 68 |
fun case_names ss = Drule.rule_attribute (K (name ss)); |
| 8364 | 69 |
|
| 10530 | 70 |
|
71 |
(* access hints *) |
|
72 |
||
| 12761 | 73 |
fun save thm = save_case_names thm o save_consumes thm; |
74 |
||
75 |
fun get thm = |
|
76 |
let |
|
77 |
val n = if_none (lookup_consumes thm) 0; |
|
78 |
val ss = |
|
79 |
(case lookup_case_names thm of |
|
80 |
None => map Library.string_of_int (1 upto (Thm.nprems_of thm - n)) |
|
81 |
| Some ss => ss); |
|
82 |
in (ss, n) end; |
|
83 |
||
| 8364 | 84 |
fun add thm = (thm, get thm); |
| 10530 | 85 |
|
| 8364 | 86 |
|
87 |
(* prepare cases *) |
|
88 |
||
| 10811 | 89 |
type T = {fixes: (string * typ) list, assumes: term list, binds: (indexname * term option) list};
|
| 10530 | 90 |
|
| 12166 | 91 |
val empty = {fixes = [], assumes = [], binds = []};
|
92 |
||
|
12809
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
93 |
fun prep_case open_parms sg prop name i = |
| 8364 | 94 |
let |
|
12809
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
95 |
val Bi = Drule.norm_hhf sg (hd (#1 (Logic.strip_prems (i, [], Logic.skip_flexpairs prop)))); |
| 10830 | 96 |
val xs = map (if open_parms then I else apfst Syntax.internal) (Logic.strip_params Bi); |
| 10811 | 97 |
val asms = map (curry Term.list_abs xs) (Logic.strip_assums_hyp Bi); |
| 10872 | 98 |
val concl = Term.list_abs (xs, Logic.strip_assums_concl Bi); |
|
12809
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
99 |
val bind = ((case_conclN, 0), Some (ObjectLogic.drop_judgment sg concl)); |
| 10872 | 100 |
in (name, {fixes = xs, assumes = asms, binds = [bind]}) end;
|
| 8364 | 101 |
|
|
12809
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
102 |
fun make open_parms (sg, prop) names = |
|
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
103 |
let val nprems = Logic.count_prems (Logic.skip_flexpairs prop, 0) in |
|
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
104 |
#1 (foldr (fn (name, (cases, i)) => (prep_case open_parms sg prop name i :: cases, i - 1)) |
|
787ecc2ac737
RuleCases.make interface based on term instead of thm;
wenzelm
parents:
12761
diff
changeset
|
105 |
(Library.drop (length names - nprems, names), ([], length names))) |
| 10811 | 106 |
end; |
| 8364 | 107 |
|
108 |
||
| 8427 | 109 |
(* params *) |
| 8364 | 110 |
|
| 11002 | 111 |
fun rename_params xss thm = foldln Thm.rename_params_rule xss thm |
| 10530 | 112 |
|> save thm; |
| 8364 | 113 |
|
114 |
fun params xss = Drule.rule_attribute (K (rename_params xss)); |
|
115 |
||
116 |
end; |