1 (*Attempts to remove occurrences of split, and pair-valued parameters*) |
1 (* Title: Tools/split_rule.ML |
2 val remove_split = rewrite_rule [split_conv RS eq_reflection] o split_all; |
2 ID: $Id$ |
|
3 Author: Stefan Berghofer, David von Oheimb, and Markus Wenzel, TU Muenchen |
|
4 License: GPL (GNU GENERAL PUBLIC LICENSE) |
3 |
5 |
4 local |
6 Some tools for managing tupled arguments and abstractions in rules. |
|
7 *) |
|
8 |
|
9 signature BASIC_SPLIT_RULE = |
|
10 sig |
|
11 val split_rule: thm -> thm |
|
12 val complete_split_rule: thm -> thm |
|
13 end; |
|
14 |
|
15 signature SPLIT_RULE = |
|
16 sig |
|
17 include BASIC_SPLIT_RULE |
|
18 val split_rule_var: term * thm -> thm |
|
19 val split_rule_goal: string list list -> thm -> thm |
|
20 val setup: (theory -> theory) list |
|
21 end; |
|
22 |
|
23 structure SplitRule: SPLIT_RULE = |
|
24 struct |
|
25 |
|
26 |
|
27 (** theory context references **) |
|
28 |
|
29 fun internal_split_const (Ta, Tb, Tc) = |
|
30 Const ("Product_Type.internal_split", [[Ta, Tb] ---> Tc, HOLogic.mk_prodT (Ta, Tb)] ---> Tc); |
|
31 |
|
32 val internal_split_def = thm "internal_split_def"; |
|
33 val internal_split_conv = thm "internal_split_conv"; |
|
34 |
|
35 |
|
36 |
|
37 (** split rules **) |
|
38 |
|
39 val eval_internal_split = hol_simplify [internal_split_def] o hol_simplify [internal_split_conv]; |
|
40 val remove_internal_split = eval_internal_split o split_all; |
|
41 |
5 |
42 |
6 (*In ap_split S T u, term u expects separate arguments for the factors of S, |
43 (*In ap_split S T u, term u expects separate arguments for the factors of S, |
7 with result type T. The call creates a new term expecting one argument |
44 with result type T. The call creates a new term expecting one argument |
8 of type S.*) |
45 of type S.*) |
9 fun ap_split (Type ("*", [T1, T2])) T3 u = |
46 fun ap_split (Type ("*", [T1, T2])) T3 u = |
10 HOLogic.split_const (T1, T2, T3) $ |
47 internal_split_const (T1, T2, T3) $ |
11 Abs("v", T1, |
48 Abs ("v", T1, |
12 ap_split T2 T3 |
49 ap_split T2 T3 |
13 ((ap_split T1 (HOLogic.prodT_factors T2 ---> T3) (incr_boundvars 1 u)) $ |
50 ((ap_split T1 (HOLogic.prodT_factors T2 ---> T3) (incr_boundvars 1 u)) $ |
14 Bound 0)) |
51 Bound 0)) |
15 | ap_split T T3 u = u; |
52 | ap_split T T3 u = u; |
16 |
53 |
17 (*Curries any Var of function type in the rule*) |
54 (*Curries any Var of function type in the rule*) |
18 fun split_rule_var' (t as Var (v, Type ("fun", [T1, T2])), rl) = |
55 fun split_rule_var' (t as Var (v, Type ("fun", [T1, T2])), rl) = |
19 let val T' = HOLogic.prodT_factors T1 ---> T2 |
56 let val T' = HOLogic.prodT_factors T1 ---> T2; |
20 val newt = ap_split T1 T2 (Var (v, T')) |
57 val newt = ap_split T1 T2 (Var (v, T')); |
21 val cterm = Thm.cterm_of (#sign (rep_thm rl)) |
58 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)); |
22 in |
59 in Thm.instantiate ([], [(cterm t, cterm newt)]) rl end |
23 instantiate ([], [(cterm t, cterm newt)]) rl |
|
24 end |
|
25 | split_rule_var' (t, rl) = rl; |
60 | split_rule_var' (t, rl) = rl; |
26 |
61 |
27 (*** Complete splitting of partially splitted rules ***) |
62 |
|
63 (* complete splitting of partially splitted rules *) |
28 |
64 |
29 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
65 fun ap_split' (T::Ts) U u = Abs ("v", T, ap_split' Ts U |
30 (ap_split T (flat (map HOLogic.prodT_factors Ts) ---> U) |
66 (ap_split T (flat (map HOLogic.prodT_factors Ts) ---> U) |
31 (incr_boundvars 1 u) $ Bound 0)) |
67 (incr_boundvars 1 u) $ Bound 0)) |
32 | ap_split' _ _ u = u; |
68 | ap_split' _ _ u = u; |
33 |
69 |
34 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) = |
70 fun complete_split_rule_var ((t as Var (v, T), ts), (rl, vs)) = |
35 let |
71 let |
36 val cterm = Thm.cterm_of (#sign (rep_thm rl)) |
72 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)) |
37 val (Us', U') = strip_type T; |
73 val (Us', U') = strip_type T; |
38 val Us = take (length ts, Us'); |
74 val Us = take (length ts, Us'); |
39 val U = drop (length ts, Us') ---> U'; |
75 val U = drop (length ts, Us') ---> U'; |
40 val T' = flat (map HOLogic.prodT_factors Us) ---> U; |
76 val T' = flat (map HOLogic.prodT_factors Us) ---> U; |
41 fun mk_tuple ((xs, insts), v as Var ((a, _), T)) = |
77 fun mk_tuple ((xs, insts), v as Var ((a, _), T)) = |
42 let |
78 let |
43 val Ts = HOLogic.prodT_factors T; |
79 val Ts = HOLogic.prodT_factors T; |
44 val ys = variantlist (replicate (length Ts) a, xs); |
80 val ys = Term.variantlist (replicate (length Ts) a, xs); |
45 in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T |
81 in (xs @ ys, (cterm v, cterm (HOLogic.mk_tuple T |
46 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts) |
82 (map (Var o apfst (rpair 0)) (ys ~~ Ts))))::insts) |
47 end |
83 end |
48 | mk_tuple (x, _) = x; |
84 | mk_tuple (x, _) = x; |
49 val newt = ap_split' Us U (Var (v, T')); |
85 val newt = ap_split' Us U (Var (v, T')); |
50 val cterm = Thm.cterm_of (#sign (rep_thm rl)); |
86 val cterm = Thm.cterm_of (#sign (Thm.rep_thm rl)); |
51 val (vs', insts) = foldl mk_tuple ((vs, []), ts); |
87 val (vs', insts) = foldl mk_tuple ((vs, []), ts); |
52 in |
88 in |
53 (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs') |
89 (instantiate ([], [(cterm t, cterm newt)] @ insts) rl, vs') |
54 end |
90 end |
55 | complete_split_rule_var (_, x) = x; |
91 | complete_split_rule_var (_, x) = x; |
57 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t) |
93 fun collect_vars (vs, Abs (_, _, t)) = collect_vars (vs, t) |
58 | collect_vars (vs, t) = (case strip_comb t of |
94 | collect_vars (vs, t) = (case strip_comb t of |
59 (v as Var _, ts) => (v, ts)::vs |
95 (v as Var _, ts) => (v, ts)::vs |
60 | (t, ts) => foldl collect_vars (vs, ts)); |
96 | (t, ts) => foldl collect_vars (vs, ts)); |
61 |
97 |
62 in |
|
63 |
98 |
64 val split_rule_var = standard o remove_split o split_rule_var'; |
99 val split_rule_var = Drule.standard o remove_internal_split o split_rule_var'; |
65 |
100 |
66 (*Curries ALL function variables occurring in a rule's conclusion*) |
101 (*curries ALL function variables occurring in a rule's conclusion*) |
67 fun split_rule rl = standard (remove_split (foldr split_rule_var' (term_vars (concl_of rl), rl))); |
102 fun split_rule rl = |
|
103 foldr split_rule_var' (Term.term_vars (concl_of rl), rl) |
|
104 |> remove_internal_split |
|
105 |> Drule.standard; |
68 |
106 |
69 fun complete_split_rule rl = |
107 fun complete_split_rule rl = |
70 standard (remove_split (fst (foldr complete_split_rule_var |
108 fst (foldr complete_split_rule_var |
71 (collect_vars ([], concl_of rl), |
109 (collect_vars ([], concl_of rl), |
72 (rl, map (fst o fst o dest_Var) (term_vars (#prop (rep_thm rl)))))))) |
110 (rl, map (fst o fst o dest_Var) (Term.term_vars (#prop (Thm.rep_thm rl)))))) |
73 |> RuleCases.save rl; |
111 |> remove_internal_split |
|
112 |> Drule.standard |
|
113 |> RuleCases.save rl; |
|
114 |
|
115 |
|
116 val split_rule_ss = HOL_basic_ss addsimps [split_conv, fst_conv, snd_conv]; |
|
117 |
|
118 fun split_rule_goal xss rl = |
|
119 let |
|
120 fun one_split i (th, s) = Tactic.rule_by_tactic (pair_tac s i) th; |
|
121 fun one_goal (xs, i) th = foldl (one_split i) (th, xs); |
|
122 in |
|
123 Drule.standard (Simplifier.full_simplify split_rule_ss (Library.foldln one_goal xss rl)) |
|
124 |> RuleCases.save rl |
|
125 end; |
|
126 |
|
127 |
|
128 (* attribute syntax *) |
|
129 |
|
130 fun complete_split x = |
|
131 Attrib.no_args (Drule.rule_attribute (K complete_split_rule)) x; |
|
132 |
|
133 fun split_format x = |
|
134 Attrib.syntax (Args.and_list1 (Scan.lift (Scan.repeat Args.name)) |
|
135 >> (fn xss => Drule.rule_attribute (K (split_rule_goal xss)))) x; |
|
136 |
|
137 val split_attributes = |
|
138 [("complete_split", (complete_split, complete_split), |
|
139 "recursively split all pair-typed function arguments"), |
|
140 ("split_format", (split_format, split_format), |
|
141 "split given pair-typed subterms in premises")]; |
|
142 |
|
143 |
|
144 |
|
145 (** theory setup **) |
|
146 |
|
147 val setup = |
|
148 [Attrib.add_attributes split_attributes]; |
|
149 |
74 |
150 |
75 end; |
151 end; |
76 fun complete_split x = |
|
77 Attrib.no_args (Drule.rule_attribute (K complete_split_rule)) x; |
|
78 |
152 |
79 fun split_rule_goal xss rl = let |
153 structure BasicSplitRule: BASIC_SPLIT_RULE = SplitRule; |
80 val ss = HOL_basic_ss addsimps [split_conv, fst_conv, snd_conv]; |
154 open BasicSplitRule; |
81 fun one_split i (th,s) = rule_by_tactic (pair_tac s i) th; |
|
82 fun one_goal (xs,i) th = foldl (one_split i) (th,xs); |
|
83 in standard (Simplifier.full_simplify ss (foldln one_goal xss rl)) |
|
84 |> RuleCases.save rl |
|
85 end; |
|
86 fun split_format x = |
|
87 Attrib.syntax (Args.and_list1 (Scan.lift (Scan.repeat Args.name)) |
|
88 >> (fn xss => Drule.rule_attribute (K (split_rule_goal xss)))) x; |
|
89 |
|
90 val split_attributes = [Attrib.add_attributes |
|
91 [("complete_split", (complete_split, complete_split), |
|
92 "recursively split all pair-typed function arguments"), |
|
93 ("split_format", (split_format, split_format), |
|
94 "split given pair-typed subterms in premises")]]; |
|
95 |
|