author | Christian Urban <christian.urban@kcl.ac.uk> |
Tue, 07 Jan 2025 12:42:42 +0000 | |
changeset 653 | 2807ec31d144 |
parent 415 | f1be8028a4a9 |
permissions | -rw-r--r-- |
415
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
1 |
theory Conversions |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
2 |
imports Main |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
3 |
begin |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
4 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
5 |
section {* Basic conversions *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
6 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
7 |
ML {* Conv.all_conv : cterm -> thm *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
8 |
ML {* Conv.all_conv *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
9 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
10 |
text {* Always succeeds *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
11 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
12 |
ML {* Conv.all_conv @{cterm "42::int"} *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
13 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
14 |
text {* Always fails *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
15 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
16 |
(* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
17 |
ML {* Conv.no_conv @{cterm "42::int"} *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
18 |
*) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
19 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
20 |
text {* Rewrite with a single rule *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
21 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
22 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
23 |
val rev_Cons = mk_meta_eq @{thm rev.simps(2)} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
24 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
25 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
26 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
27 |
Conv.rewr_conv rev_Cons @{cterm "rev [1::int, 2]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
28 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
29 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
30 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
31 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
32 |
section {* Combining conversions (``conversionals'') *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
33 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
34 |
text {* Sequencing *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
35 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
36 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
37 |
val add_0_right = mk_meta_eq @{thm monoid_add_class.add_0_right} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
38 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
39 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
40 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
41 |
val mult_1_left = mk_meta_eq @{thm monoid_mult_class.mult_1_left} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
42 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
43 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
44 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
45 |
(Conv.rewr_conv add_0_right then_conv Conv.rewr_conv mult_1_left) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
46 |
@{cterm "((1::int) * x) + 0"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
47 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
48 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
49 |
text {* Alternative *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
50 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
51 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
52 |
val rev_Nil = mk_meta_eq @{thm rev.simps(1)} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
53 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
54 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
55 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
56 |
(Conv.rewr_conv rev_Nil else_conv Conv.rewr_conv rev_Cons) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
57 |
@{cterm "rev [1::int, 2, 3]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
58 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
59 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
60 |
text {* Try conversion (yields reflexivity instead of exception) *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
61 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
62 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
63 |
Conv.try_conv (Conv.rewr_conv rev_Nil) @{cterm "[1::int, 2]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
64 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
65 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
66 |
text {* Descend into subterms *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
67 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
68 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
69 |
Conv.combination_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
70 |
(Conv.combination_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
71 |
Conv.all_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
72 |
(Conv.rewr_conv rev_Cons)) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
73 |
(Conv.rewr_conv rev_Cons) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
74 |
@{cterm "rev [1::int, 2] @ rev [3, 4]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
75 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
76 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
77 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
78 |
Conv.combination_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
79 |
(Conv.arg_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
80 |
(Conv.rewr_conv rev_Cons)) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
81 |
(Conv.rewr_conv rev_Cons) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
82 |
@{cterm "rev [1::int, 2] @ rev [3, 4]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
83 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
84 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
85 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
86 |
Conv.abs_conv (fn (v, ctxt) => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
87 |
Conv.abs_conv (fn (v', ctxt') => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
88 |
Conv.rewr_conv rev_Cons) ctxt) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
89 |
@{context} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
90 |
@{cterm "\<lambda>x y. rev [x, y]"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
91 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
92 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
93 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
94 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
95 |
section {* Simple bottom-up rewriting, using Isabelle's conversion library *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
96 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
97 |
text {* Descend into immediate subterms *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
98 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
99 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
100 |
fun subc conv ctxt = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
101 |
Conv.comb_conv (conv ctxt) else_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
102 |
Conv.abs_conv (conv o snd) ctxt else_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
103 |
Conv.all_conv; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
104 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
105 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
106 |
text {* The ct argument is necessary to avoid nontermination! *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
107 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
108 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
109 |
fun botc conv ctxt ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
110 |
(subc (botc conv) ctxt then_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
111 |
Conv.try_conv (conv then_conv botc conv ctxt)) ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
112 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
113 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
114 |
text {* Running example: reversing lists *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
115 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
116 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
117 |
val eqns = map mk_meta_eq (@{thms "append.simps"} @ @{thms "rev.simps"}); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
118 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
119 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
120 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
121 |
val rev_int = @{cterm "rev :: int list \<Rightarrow> int list"}; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
122 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
123 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
124 |
text {* Produce lists of length i *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
125 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
126 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
127 |
fun mk_upto thy i = Thm.cterm_of thy (HOLogic.mk_list HOLogic.intT |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
128 |
(map (HOLogic.mk_number HOLogic.intT) (1 upto i))); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
129 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
130 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
131 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
132 |
val ct = Thm.capply rev_int (mk_upto @{theory} 100) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
133 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
134 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
135 |
text {* Fully rewrite the term (slow, i.e. 40 secs on my laptop) *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
136 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
137 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
138 |
timeit (fn () => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
139 |
botc (Conv.first_conv (map Conv.rewr_conv eqns)) @{context} ct) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
140 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
141 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
142 |
text {* Also rewrites inside quantifiers, thanks to abs_conv *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
143 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
144 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
145 |
botc (Conv.first_conv (map Conv.rewr_conv eqns)) @{context} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
146 |
@{cterm "\<forall>x y z. P (rev [x, y, z])"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
147 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
148 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
149 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
150 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
151 |
section {* Using exceptions for signalling unchanged terms *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
152 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
153 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
154 |
Motivation: avoid unnecessary applications of reflexivity |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
155 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
156 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
157 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
158 |
infix 1 then_conv'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
159 |
infix 0 else_conv'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
160 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
161 |
exception Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
162 |
exception Unchanged; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
163 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
164 |
fun (cv1 else_conv' cv2) ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
165 |
cv1 ct handle Fail => cv2 ct; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
166 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
167 |
fun all_conv' ct = raise Unchanged; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
168 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
169 |
fun no_conv' ct = raise Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
170 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
171 |
fun try_conv' cv ct = cv ct handle Fail => raise Unchanged; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
172 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
173 |
fun (cv1 then_conv' cv2) ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
174 |
let val eq = cv1 ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
175 |
in Thm.transitive eq (cv2 (Thm.rhs_of eq)) handle Unchanged => eq |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
176 |
end handle Unchanged => cv2 ct; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
177 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
178 |
fun first_conv' cvs = fold_rev (curry op else_conv') cvs no_conv'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
179 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
180 |
fun comb_conv' cv ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
181 |
let val (ct1, ct2) = Thm.dest_comb ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
182 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
183 |
let val eq1 = cv ct1 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
184 |
in Thm.combination eq1 (cv ct2) handle Unchanged => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
185 |
Thm.combination eq1 (Thm.reflexive ct2) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
186 |
end handle Unchanged => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
187 |
let val eq2 = cv ct2 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
188 |
in Thm.combination (Thm.reflexive ct1) eq2 end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
189 |
end handle CTERM _ => raise Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
190 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
191 |
fun abs_conv' cv ctxt ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
192 |
(case Thm.term_of ct of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
193 |
Abs (x, _, _) => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
194 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
195 |
val ([u], ctxt') = Variable.variant_fixes ["u"] ctxt; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
196 |
val (v, ct') = Thm.dest_abs (SOME u) ct; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
197 |
val eq = cv (v, ctxt') ct'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
198 |
in Thm.abstract_rule x v eq end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
199 |
| _ => raise Fail); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
200 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
201 |
fun subc' conv ctxt = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
202 |
comb_conv' (conv ctxt) else_conv' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
203 |
abs_conv' (conv o snd) ctxt else_conv' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
204 |
all_conv'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
205 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
206 |
fun botc' conv ctxt ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
207 |
(subc' (botc' conv) ctxt then_conv' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
208 |
try_conv' (conv then_conv' botc' conv ctxt)) ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
209 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
210 |
fun rewr_conv' rule ct = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
211 |
Conv.rewr_conv rule ct handle CTERM _ => raise Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
212 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
213 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
214 |
text {* Fully rewrite the term (32 secs on my laptop) *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
215 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
216 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
217 |
timeit (fn () => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
218 |
botc' (first_conv' (map rewr_conv' eqns)) @{context} ct) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
219 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
220 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
221 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
222 |
botc' (first_conv' (map rewr_conv' eqns)) @{context} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
223 |
@{cterm "\<forall>x y z. P (rev [x, y, z])"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
224 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
225 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
226 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
227 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
228 |
section {* Bottom-up writing using skeletons *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
229 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
230 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
231 |
Motivation: avoid re-inspecting terms that are already |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
232 |
in normal form |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
233 |
Skeleton = rhs of last rewrite rule applied |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
234 |
decomposed in parallel with the term to be normalized |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
235 |
if skeleton is a variable, then the corresponding |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
236 |
term must already be in normal form. |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
237 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
238 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
239 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
240 |
infix 1 then_conv''; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
241 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
242 |
fun (cv1 then_conv'' cv2) cts = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
243 |
let val (eq1, skel1) = cv1 cts |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
244 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
245 |
let val (eq2, skel2) = cv2 (Thm.rhs_of eq1, skel1) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
246 |
in (Thm.transitive eq1 eq2, skel2) end handle Unchanged => (eq1, skel1) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
247 |
end handle Unchanged => cv2 cts; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
248 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
249 |
val dummy_skel = Bound 0; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
250 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
251 |
fun comb_conv'' cv (ct, skel) = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
252 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
253 |
val (ct1, ct2) = Thm.dest_comb ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
254 |
val (skel1, skel2) = (case skel of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
255 |
skel1 $ skel2 => (skel1, skel2) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
256 |
| _ => (dummy_skel, dummy_skel)); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
257 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
258 |
let val (eq1, skel1') = cv (ct1, skel1) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
259 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
260 |
let val (eq2, skel2') = cv (ct2, skel2) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
261 |
in (Thm.combination eq1 eq2, skel1' $ skel2') end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
262 |
handle Unchanged => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
263 |
(Thm.combination eq1 (Thm.reflexive ct2), skel1' $ skel2) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
264 |
end handle Unchanged => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
265 |
let val (eq2, skel2') = cv (ct2, skel2) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
266 |
in (Thm.combination (Thm.reflexive ct1) eq2, skel1 $ skel2') end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
267 |
end handle CTERM _ => raise Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
268 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
269 |
fun abs_conv'' cv ctxt (ct, skel) = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
270 |
(case Thm.term_of ct of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
271 |
Abs (x, T, _) => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
272 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
273 |
val ([u], ctxt') = Variable.variant_fixes ["u"] ctxt; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
274 |
val (v, ct') = Thm.dest_abs (SOME u) ct; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
275 |
val skel' = (case skel of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
276 |
Abs (_, _, skel') => skel' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
277 |
| _ => dummy_skel) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
278 |
val (eq, skel'') = cv (v, ctxt') (ct', skel'); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
279 |
in (Thm.abstract_rule x v eq, Abs (x, T, skel'')) end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
280 |
| _ => raise Fail); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
281 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
282 |
fun subc'' conv ctxt = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
283 |
comb_conv'' (conv ctxt) else_conv' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
284 |
abs_conv'' (conv o snd) ctxt else_conv' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
285 |
all_conv'; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
286 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
287 |
fun botc'' conv ctxt (_, Var _) = raise Unchanged |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
288 |
| botc'' conv ctxt cts = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
289 |
(subc'' (botc'' conv) ctxt then_conv'' |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
290 |
try_conv' (conv then_conv'' botc'' conv ctxt)) cts |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
291 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
292 |
fun rewr_conv'' rule (ct, _) = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
293 |
(Conv.rewr_conv rule ct, term_of (Thm.rhs_of rule)) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
294 |
handle CTERM _ => raise Fail; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
295 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
296 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
297 |
text {* Fully rewrite the term (1.5 secs on my laptop) *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
298 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
299 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
300 |
timeit (fn () => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
301 |
fst (botc'' (first_conv' (map rewr_conv'' eqns)) @{context} (ct, dummy_skel))) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
302 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
303 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
304 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
305 |
fst (botc'' (first_conv' (map rewr_conv'' eqns)) @{context} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
306 |
(@{cterm "\<forall>x y z. P (rev [x, y, z])"}, dummy_skel)) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
307 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
308 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
309 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
310 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
311 |
section {* The simplifier *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
312 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
313 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
314 |
The simplifier is a conversion itself, using many of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
315 |
the techniques just described. |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
316 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
317 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
318 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
319 |
Simplifier.rewrite (HOL_basic_ss addsimps eqns) ct |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
320 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
321 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
322 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
323 |
Simplifier.rewrite @{simpset} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
324 |
@{cterm "\<And>(x::int) (y::int). P x \<Longrightarrow> x = 42 \<Longrightarrow> Q x \<Longrightarrow> R (y + 0) \<Longrightarrow> S (1 * x)"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
325 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
326 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
327 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
328 |
Simplifier.asm_rewrite @{simpset} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
329 |
@{cterm "\<And>(x::int) (y::int). P x \<Longrightarrow> x = 42 \<Longrightarrow> Q x \<Longrightarrow> R (y + 0) \<Longrightarrow> S (1 * x)"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
330 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
331 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
332 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
333 |
Simplifier.full_rewrite @{simpset} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
334 |
@{cterm "\<And>(x::int) (y::int). P x \<Longrightarrow> x = 42 \<Longrightarrow> Q x \<Longrightarrow> R (y + 0) \<Longrightarrow> S (1 * x)"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
335 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
336 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
337 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
338 |
Simplifier.asm_full_rewrite @{simpset} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
339 |
@{cterm "\<And>(x::int) (y::int). P x \<Longrightarrow> x = 42 \<Longrightarrow> Q x \<Longrightarrow> R (y + 0) \<Longrightarrow> S (1 * x)"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
340 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
341 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
342 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
343 |
Simplifier.asm_lr_rewrite @{simpset} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
344 |
@{cterm "\<And>(x::int) (y::int). P x \<Longrightarrow> x = 42 \<Longrightarrow> Q x \<Longrightarrow> R (y + 0) \<Longrightarrow> S (1 * x)"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
345 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
346 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
347 |
section {* Simplification procedures *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
348 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
349 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
350 |
A simplification procedure is a function of type |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
351 |
@{ML_type "cterm -> thm option"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
352 |
It can be used to prove rewrite rules on-the-fly. |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
353 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
354 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
355 |
text {* Example 1: One-point rules *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
356 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
357 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
358 |
Problem: how to rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
359 |
@{term "\<And>x y z. P y \<Longrightarrow> y = t \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
360 |
to |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
361 |
@{term "\<And>x z. P t \<Longrightarrow> Q t"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
362 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
363 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
364 |
lemma meta_onepoint1: "(\<And>x. x = t \<Longrightarrow> PROP P x) \<equiv> PROP P t" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
365 |
proof |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
366 |
assume R: "\<And>x. x = t \<Longrightarrow> PROP P x" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
367 |
show "PROP P t" by (rule R [OF refl]) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
368 |
next |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
369 |
fix x assume "PROP P t" "x = t" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
370 |
then show "PROP P x" by simp |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
371 |
qed |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
372 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
373 |
lemma meta_onepoint2: "(\<And>x. t = x \<Longrightarrow> PROP P x) \<equiv> PROP P t" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
374 |
proof |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
375 |
assume R: "\<And>x. t = x \<Longrightarrow> PROP P x" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
376 |
show "PROP P t" by (rule R [OF refl]) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
377 |
next |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
378 |
fix x assume "PROP P t" "t = x" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
379 |
then show "PROP P x" by simp |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
380 |
qed |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
381 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
382 |
lemmas meta_onepoint = meta_onepoint1 meta_onepoint2 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
383 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
384 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
385 |
Note: only works with formulae like |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
386 |
@{term "\<And>x z y. y = t \<Longrightarrow> P y \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
387 |
but not |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
388 |
@{term "\<And>x y z. P y \<Longrightarrow> y = t \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
389 |
Solution: reorder quantifiers and premises |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
390 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
391 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
392 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
393 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
394 |
(HOL_basic_ss addsimps @{thms meta_onepoint}) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
395 |
@{cterm "\<And>x z y. y = t \<Longrightarrow> P y \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
396 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
397 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
398 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
399 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
400 |
(HOL_basic_ss addsimps @{thms meta_onepoint}) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
401 |
@{cterm "\<And>x y z. P y \<Longrightarrow> y = t \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
402 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
403 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
404 |
text {* Move parameters to the right *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
405 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
406 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
407 |
fun swap_params_conv ctxt i j cv = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
408 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
409 |
fun conv1 0 ctxt = Conv.forall_conv (cv o snd) ctxt |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
410 |
| conv1 k ctxt = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
411 |
Conv.rewr_conv @{thm swap_params} then_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
412 |
Conv.forall_conv (conv1 (k-1) o snd) ctxt |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
413 |
fun conv2 0 ctxt = conv1 j ctxt |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
414 |
| conv2 k ctxt = Conv.forall_conv (conv2 (k-1) o snd) ctxt |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
415 |
in conv2 i ctxt end; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
416 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
417 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
418 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
419 |
swap_params_conv @{context} 2 3 (K Conv.all_conv) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
420 |
@{cterm "\<And>a b c d e f. P a b c d e f"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
421 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
422 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
423 |
text {* Move premises to the left *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
424 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
425 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
426 |
fun swap_prems_conv 0 = Conv.all_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
427 |
| swap_prems_conv i = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
428 |
Conv.implies_concl_conv (swap_prems_conv (i-1)) then_conv |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
429 |
Conv.rewr_conv Drule.swap_prems_eq |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
430 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
431 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
432 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
433 |
swap_prems_conv 3 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
434 |
@{cterm "A \<Longrightarrow> B \<Longrightarrow> C \<Longrightarrow> D \<Longrightarrow> E \<Longrightarrow> F"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
435 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
436 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
437 |
text {* Find out which equation to move *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
438 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
439 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
440 |
fun find_eq t = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
441 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
442 |
val l = length (Logic.strip_params t); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
443 |
val Hs = Logic.strip_assums_hyp t; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
444 |
fun find (i, (_ $ (Const ("op =", _) $ Bound j $ _))) = SOME (i, j) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
445 |
| find (i, (_ $ (Const ("op =", _) $ _ $ Bound j))) = SOME (i, j) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
446 |
| find _ = NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
447 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
448 |
case get_first find (map_index I Hs) of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
449 |
NONE => NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
450 |
| SOME (0, 0) => NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
451 |
| SOME (i, j) => SOME (i, l - j - 1, j) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
452 |
end; |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
453 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
454 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
455 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
456 |
find_eq @{term "\<And>x y z. P y \<Longrightarrow> y = t \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
457 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
458 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
459 |
text {* Turn it into a simproc *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
460 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
461 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
462 |
fun mk_rrule ctxt ct = case find_eq (term_of ct) of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
463 |
NONE => NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
464 |
| SOME (i, k, j) => SOME (swap_params_conv ctxt k j (K (swap_prems_conv i)) ct); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
465 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
466 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
467 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
468 |
val rearrange_eqs_simproc = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
469 |
Simplifier.simproc @{theory} "rearrange_eqs" ["all t"] (fn thy => fn ss => fn t => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
470 |
mk_rrule (Simplifier.the_context ss) (cterm_of thy t)) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
471 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
472 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
473 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
474 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
475 |
(HOL_basic_ss addsimps @{thms meta_onepoint} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
476 |
addsimprocs [rearrange_eqs_simproc]) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
477 |
@{cterm "\<And>x y z. P y \<Longrightarrow> y = t \<Longrightarrow> Q y"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
478 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
479 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
480 |
subsection {* Example 2: Simplifying set comprehensions *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
481 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
482 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
483 |
Problem: How to simplify |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
484 |
@{term "{(x, y, z). (x, y, z) \<in> S}"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
485 |
to |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
486 |
@{term S} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
487 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
488 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
489 |
ML {* @{thm Collect_mem_eq} *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
490 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
491 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
492 |
Note: does not work with pairs |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
493 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
494 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
495 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
496 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
497 |
(HOL_basic_ss addsimps @{thms Collect_mem_eq}) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
498 |
@{cterm "P {x. x \<in> S}"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
499 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
500 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
501 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
502 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
503 |
(HOL_basic_ss addsimps @{thms Collect_mem_eq}) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
504 |
@{cterm "P {(x, y). (x, y) \<in> S}"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
505 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
506 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
507 |
text {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
508 |
Write a simproc to prove |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
509 |
@{term "{(x, y). (x, y) \<in> S} \<equiv> S"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
510 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
511 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
512 |
lemma test: "{(x, y). (x, y) \<in> S} \<equiv> S" |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
513 |
apply (rule eq_reflection) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
514 |
apply (rule subset_antisym) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
515 |
apply (rule subsetI) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
516 |
apply (drule CollectD) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
517 |
apply (simp only: split_paired_all split_conv) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
518 |
apply (rule subsetI) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
519 |
apply (rule CollectI) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
520 |
apply (simp only: split_paired_all split_conv) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
521 |
done |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
522 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
523 |
text {* The same in ML *} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
524 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
525 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
526 |
let |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
527 |
val simp = full_simp_tac |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
528 |
(HOL_basic_ss addsimps [split_paired_all, split_conv]) 1 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
529 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
530 |
Goal.prove @{context} [] [] |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
531 |
@{term "{(x, y). (x, y) \<in> S} \<equiv> S"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
532 |
(K (EVERY |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
533 |
[rtac eq_reflection 1, rtac @{thm subset_antisym} 1, |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
534 |
rtac subsetI 1, dtac CollectD 1, simp, |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
535 |
rtac subsetI 1, rtac CollectI 1, simp])) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
536 |
end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
537 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
538 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
539 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
540 |
val (u, Ts, ps) = HOLogic.strip_split |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
541 |
@{term "\<lambda>(x, y). (x, y) \<in> S"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
542 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
543 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
544 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
545 |
val collect_mem_simproc = |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
546 |
Simplifier.simproc (theory "Set") "Collect_mem" ["Collect t"] (fn thy => fn ss => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
547 |
fn S as Const ("Collect", Type ("fun", [_, T])) $ t => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
548 |
let val (u, Ts, ps) = HOLogic.strip_split t |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
549 |
in case u of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
550 |
(c as Const ("op :", _)) $ q $ S' => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
551 |
(case try (HOLogic.dest_tuple' ps) q of |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
552 |
NONE => NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
553 |
| SOME ts => |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
554 |
if not (loose_bvar (S', 0)) andalso |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
555 |
ts = map Bound (length ps downto 0) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
556 |
then |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
557 |
let val simp = full_simp_tac (Simplifier.inherit_context ss |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
558 |
(HOL_basic_ss addsimps [split_paired_all, split_conv])) 1 |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
559 |
in |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
560 |
SOME (Goal.prove (Simplifier.the_context ss) [] [] |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
561 |
(Const ("==", T --> T --> propT) $ S $ S') |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
562 |
(K (EVERY |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
563 |
[rtac eq_reflection 1, rtac @{thm subset_antisym} 1, |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
564 |
rtac subsetI 1, dtac CollectD 1, simp, |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
565 |
rtac subsetI 1, rtac CollectI 1, simp]))) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
566 |
end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
567 |
else NONE) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
568 |
| _ => NONE |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
569 |
end |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
570 |
| _ => NONE); |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
571 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
572 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
573 |
ML {* |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
574 |
Simplifier.rewrite |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
575 |
(HOL_basic_ss addsimps @{thms Collect_mem_eq} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
576 |
addsimprocs [collect_mem_simproc]) |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
577 |
@{cterm "P {(x, y). (x, y) \<in> S}"} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
578 |
*} |
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
579 |
|
f1be8028a4a9
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
580 |
end |