1 %% $Id$ |
1 %% $Id$ |
2 \chapter{Simplification} |
2 \chapter{Simplification} |
3 \label{chap:simplification} |
3 \label{chap:simplification} |
4 \index{simplification|(} |
4 \index{simplification|(} |
5 |
5 |
6 This chapter describes Isabelle's generic simplification package, which |
6 This chapter describes Isabelle's generic simplification package. It |
7 provides a suite of simplification tactics. It performs conditional and |
7 performs conditional and unconditional rewriting and uses contextual |
8 unconditional rewriting and uses contextual information (`local |
8 information (`local assumptions'). It provides several general hooks, |
9 assumptions'). It provides a few general hooks, which can provide |
9 which can provide automatic case splits during rewriting, for example. |
10 automatic case splits during rewriting, for example. The simplifier is set |
10 The simplifier is already set up for many of Isabelle's logics: \FOL, |
11 up for many of Isabelle's logics: \FOL, \ZF, \HOL\ and \HOLCF. |
11 \ZF, \HOL, \HOLCF. |
12 |
12 |
13 The next section is a quick introduction to the simplifier, the later |
13 The first section is a quick introduction to the simplifier that |
14 sections explain advanced features. |
14 should be sufficient to get started. The later sections explain more |
|
15 advanced features. |
|
16 |
15 |
17 |
16 \section{Simplification for dummies} |
18 \section{Simplification for dummies} |
17 \label{sec:simp-for-dummies} |
19 \label{sec:simp-for-dummies} |
18 |
20 |
19 In some logics (\FOL, {\HOL} and \ZF), the simplifier is particularly easy to |
21 Basic use of the simplifier is particularly easy because each theory |
20 use because it supports the concept of a {\em current |
22 is equipped with an implicit {\em current |
21 simpset}\index{simpset!current}. This is a default set of simplification |
23 simpset}\index{simpset!current}. This provides sensible default |
22 rules. All commands are interpreted relative to the current simpset. For |
24 information in many cases. A suite of commands refer to the implicit |
23 example, in the theory of arithmetic the goal |
25 simpset of the current theory context. |
24 \begin{ttbox} |
26 |
|
27 \begin{warn} |
|
28 Make sure that you are working within the correct theory context. |
|
29 Executing proofs interactively, or loading them from ML files |
|
30 without associated theories may require setting the current theory |
|
31 manually via the \ttindex{context} command. |
|
32 \end{warn} |
|
33 |
|
34 \subsection{Simplification tactics} \label{sec:simp-for-dummies-tacs} |
|
35 \begin{ttbox} |
|
36 Simp_tac : int -> tactic |
|
37 Asm_simp_tac : int -> tactic |
|
38 Full_simp_tac : int -> tactic |
|
39 Asm_full_simp_tac : int -> tactic |
|
40 trace_simp : bool ref \hfill{\bf initially false} |
|
41 \end{ttbox} |
|
42 |
|
43 \begin{ttdescription} |
|
44 \item[\ttindexbold{Simp_tac} $i$] simplifies subgoal~$i$ using the |
|
45 current simpset. It may solve the subgoal completely if it has |
|
46 become trivial, using the simpset's solver tactic. |
|
47 |
|
48 \item[\ttindexbold{Asm_simp_tac}]\index{assumptions!in simplification} |
|
49 is like \verb$Simp_tac$, but extracts additional rewrite rules from |
|
50 the local assumptions. |
|
51 |
|
52 \item[\ttindexbold{Full_simp_tac}] is like \verb$Simp_tac$, but also |
|
53 simplifies the assumptions (without using the assumptions to |
|
54 simplify each other or the actual goal). |
|
55 |
|
56 \item[\ttindexbold{Asm_full_simp_tac}] is like \verb$Asm_simp_tac$, |
|
57 but also simplifies the assumptions one by one. Working from |
|
58 \emph{left to right}, it uses each assumption in the simplification |
|
59 of those following. |
|
60 |
|
61 \item[set \ttindexbold{trace_simp};] makes the simplifier output |
|
62 internal operations. This includes rewrite steps, but also |
|
63 bookkeeping like modifications of the simpset. |
|
64 \end{ttdescription} |
|
65 |
|
66 \medskip |
|
67 |
|
68 As an example, consider the theory of arithmetic in \HOL. The (rather |
|
69 trivial) goal $0 + (x + 0) = x + 0 + 0$ can be solved by a single call |
|
70 of \texttt{Simp_tac} as follows: |
|
71 \begin{ttbox} |
|
72 context Arith.thy; |
|
73 goal Arith.thy "0 + (x + 0) = x + 0 + 0"; |
25 {\out 1. 0 + (x + 0) = x + 0 + 0} |
74 {\out 1. 0 + (x + 0) = x + 0 + 0} |
26 \end{ttbox} |
|
27 can be solved by a single |
|
28 \begin{ttbox} |
|
29 by (Simp_tac 1); |
75 by (Simp_tac 1); |
30 \end{ttbox} |
76 {\out Level 1} |
31 The simplifier uses the current simpset, which in the case of arithmetic |
77 {\out 0 + (x + 0) = x + 0 + 0} |
32 contains the required theorems $\Var{n}+0 = \Var{n}$ and $0+\Var{n} = |
78 {\out No subgoals!} |
|
79 \end{ttbox} |
|
80 |
|
81 The simplifier uses the current simpset of \texttt{Arith.thy}, which |
|
82 contains suitable theorems like $\Var{n}+0 = \Var{n}$ and $0+\Var{n} = |
33 \Var{n}$. |
83 \Var{n}$. |
34 |
84 |
35 If assumptions of the subgoal are also needed in the simplification |
85 \medskip In many cases, assumptions of a subgoal are also needed in |
36 process, as in |
86 the simplification process. For example, \texttt{x = 0 ==> x + x = 0} |
|
87 is solved by \texttt{Asm_simp_tac} as follows: |
37 \begin{ttbox} |
88 \begin{ttbox} |
38 {\out 1. x = 0 ==> x + x = 0} |
89 {\out 1. x = 0 ==> x + x = 0} |
39 \end{ttbox} |
|
40 then there is the more powerful |
|
41 \begin{ttbox} |
|
42 by (Asm_simp_tac 1); |
90 by (Asm_simp_tac 1); |
43 \end{ttbox} |
91 \end{ttbox} |
44 which solves the above goal. |
92 |
45 |
93 \medskip {\tt Asm_full_simp_tac} is the most powerful of this quartet |
46 There are four basic simplification tactics: |
94 of tactics but may also loop where some of the others terminate. For |
47 \begin{ttdescription} |
95 example, |
48 \item[\ttindexbold{Simp_tac} $i$] simplifies subgoal~$i$ using the current |
96 \begin{ttbox} |
49 simpset. It may solve the subgoal completely if it has become trivial, |
97 {\out 1. ALL x. f x = g (f (g x)) ==> f 0 = f 0 + 0} |
50 using the solver. |
98 \end{ttbox} |
51 |
99 is solved by {\tt Simp_tac}, but {\tt Asm_simp_tac} and {\tt |
52 \item[\ttindexbold{Asm_simp_tac}]\index{assumptions!in simplification} |
100 Asm_simp_tac} loop because the rewrite rule $f\,\Var{x} = |
53 is like \verb$Simp_tac$, but extracts additional rewrite rules from the |
101 g\,(f\,(g\,\Var{x}))$ extracted from the assumption does not |
54 assumptions. |
102 terminate. Isabelle notices certain simple forms of nontermination, |
55 |
103 but not this one. |
56 \item[\ttindexbold{Full_simp_tac}] is like \verb$Simp_tac$, but also |
|
57 simplifies the assumptions (but without using the assumptions to simplify |
|
58 each other or the actual goal.) |
|
59 |
|
60 \item[\ttindexbold{Asm_full_simp_tac}] |
|
61 is like \verb$Asm_simp_tac$, but also simplifies the assumptions one by |
|
62 one. {\em Working from left to right, it uses each assumption in the |
|
63 simplification of those following.} |
|
64 \end{ttdescription} |
|
65 |
|
66 {\tt Asm_full_simp_tac} is the most powerful of this quartet but may also |
|
67 loop where some of the others terminate. For example, |
|
68 \begin{ttbox} |
|
69 {\out 1. ALL x. f(x) = g(f(g(x))) ==> f(0) = f(0)+0} |
|
70 \end{ttbox} |
|
71 is solved by {\tt Simp_tac}, but {\tt Asm_simp_tac} and {\tt Asm_simp_tac} |
|
72 loop because the rewrite rule $f(\Var{x}) = f(g(f(\Var{x})))$ extracted from |
|
73 the assumption does not terminate. Isabelle notices certain simple forms of |
|
74 nontermination, but not this one. |
|
75 |
104 |
76 \begin{warn} |
105 \begin{warn} |
77 Since \verb$Asm_full_simp_tac$ works from left to right, it sometimes |
106 Since \verb$Asm_full_simp_tac$ works from left to right, it sometimes |
78 misses opportunities for simplification: given the subgoal |
107 misses opportunities for simplification: given the subgoal |
79 \begin{ttbox} |
108 \begin{ttbox} |
80 {\out [| P(f(a)); f(a) = t |] ==> ...} |
109 {\out [| P (f a); f a = t |] ==> \dots} |
81 \end{ttbox} |
110 \end{ttbox} |
82 \verb$Asm_full_simp_tac$ will not simplify the first assumption using the |
111 \verb$Asm_full_simp_tac$ will not simplify the first assumption using the |
83 second but will leave the assumptions unchanged. See |
112 second but will leave the assumptions unchanged. See |
84 \S\ref{sec:reordering-asms} for ways around this problem. |
113 \S\ref{sec:reordering-asms} for ways around this problem. |
85 \end{warn} |
114 \end{warn} |
86 |
115 |
|
116 \medskip |
|
117 |
87 Using the simplifier effectively may take a bit of experimentation. |
118 Using the simplifier effectively may take a bit of experimentation. |
88 \index{tracing!of simplification}\index{*trace_simp} The tactics can |
119 Set the \verb$trace_simp$\index{tracing!of simplification} flag to get |
89 be traced by setting \verb$trace_simp$. |
120 a better idea of what is going on. The resulting output can be |
90 |
121 enormous, especially since invocations of the simplifier are often |
91 There is not just one global current simpset, but one associated with each |
122 nested (e.g.\ when solving conditions of rewrite rules). |
92 theory as well. How are these simpset built up? |
123 |
93 \begin{enumerate} |
124 |
94 \item When loading {\tt T.thy}, the current simpset is initialized with the |
125 \subsection{Modifying the current simpset} |
95 union of the simpsets associated with all the ancestors of {\tt T}. In |
126 \begin{ttbox} |
96 addition, certain constructs in {\tt T} may add new rules to the simpset, |
127 Addsimps : thm list -> unit |
97 e.g.\ \ttindex{datatype} and \ttindex{primrec} in \HOL. Definitions are not |
128 Delsimps : thm list -> unit |
98 added automatically! |
129 Addsimprocs : simproc list -> unit |
99 \item The script in {\tt T.ML} may manipulate the current simpset further by |
130 Delsimprocs : simproc list -> unit |
100 explicitly adding/deleting theorems to/from it (see below). |
131 Addcongs : thm list -> unit |
101 \item After {\tt T.ML} has been read, the current simpset is associated with |
132 Delcongs : thm list -> unit |
102 theory {\tt T}. |
133 \end{ttbox} |
103 \end{enumerate} |
134 |
104 The current simpset is manipulated by |
135 Depending on the theory context, the \texttt{Add} and \texttt{Del} |
105 \begin{ttbox} |
136 functions manipulate basic components of the associated current |
106 Addsimps, Delsimps: thm list -> unit |
137 simpset. Internally, all rewrite rules have to be expressed as |
107 \end{ttbox} |
138 (conditional) meta-equalities. This form is derived automatically |
|
139 from object-level equations that are supplied by the user. Another |
|
140 source of rewrite rules are \emph{simplification procedures}, that is |
|
141 \ML\ functions that produce suitable theorems on demand, depending on |
|
142 the current redex. Congruences are a more advanced feature; see |
|
143 \S\ref{sec:simp-congs}. |
|
144 |
108 \begin{ttdescription} |
145 \begin{ttdescription} |
109 \item[\ttindexbold{Addsimps} $thms$] adds $thms$ to the current simpset |
146 |
110 \item[\ttindexbold{Delsimps} $thms$] deletes $thms$ from the current simpset |
147 \item[\ttindexbold{Addsimps} $thms$;] adds rewrite rules derived from |
|
148 $thms$ to the current simpset. |
|
149 |
|
150 \item[\ttindexbold{Delsimps} $thms$;] deletes rewrite rules derived |
|
151 from $thms$ from the current simpset. |
|
152 |
|
153 \item[\ttindexbold{Addsimprocs} $procs$;] adds simplification |
|
154 procedures $procs$ to the current simpset. |
|
155 |
|
156 \item[\ttindexbold{Delsimprocs} $procs$;] deletes simplification |
|
157 procedures $procs$ from the current simpset. |
|
158 |
|
159 \item[\ttindexbold{Addcongs} $thms$;] adds congruence rules to the |
|
160 current simpset. |
|
161 |
|
162 \item[\ttindexbold{Delcongs} $thms$;] deletes congruence rules to the |
|
163 current simpset. |
|
164 |
111 \end{ttdescription} |
165 \end{ttdescription} |
112 |
166 |
113 Generally useful simplification rules $\Var{n}+0 = \Var{n}$ should be added |
167 When a new theory is built, its implicit simpset is initialized by the |
114 to the current simpset right after they have been proved. Those of a more |
168 union of the respective simpsets of its parent theories. In addition, |
115 specific nature (e.g.\ the laws of de~Morgan, which alter the structure of a |
169 certain theory definition constructs (e.g.\ \ttindex{datatype} and |
116 formula) should only be added for specific proofs and deleted again |
170 \ttindex{primrec} in \HOL) implicitly augment the current simpset. |
117 afterwards. Conversely, it may also happen that a generally useful rule needs |
171 Ordinary definitions are not added automatically! |
118 to be removed for a certain proof and is added again afterwards. Well |
172 |
119 designed simpsets need few temporary additions or deletions. |
173 It is up the user to manipulate the current simpset further by |
|
174 explicitly adding or deleting theorems and simplification procedures. |
|
175 |
|
176 \medskip |
|
177 |
|
178 Good simpsets are hard to design. As a rule of thump, generally |
|
179 useful ``simplification rules'' like $\Var{n}+0 = \Var{n}$ should be |
|
180 added to the current simpset right after they have been proved. Those |
|
181 of a more specific nature (e.g.\ the laws of de~Morgan, which alter |
|
182 the structure of a formula) should only be added for specific proofs |
|
183 and deleted again afterwards. Conversely, it may also happen that a |
|
184 generally useful rule needs to be removed for a certain proof and is |
|
185 added again afterwards. The need of frequent temporary additions or |
|
186 deletions may indicate a badly designed simpset. |
120 |
187 |
121 \begin{warn} |
188 \begin{warn} |
122 The union of the ancestor simpsets (as described above) is not always a good |
189 The union of the parent simpsets (as described above) is not always |
123 simpset for the new theory. If some ancestors have deleted simplification |
190 a good starting point for the new theory. If some ancestors have |
124 rules because they are no longer wanted, while others have left those rules |
191 deleted simplification rules because they are no longer wanted, |
125 in, then the union will contain the unwanted rules. If the ancestor |
192 while others have left those rules in, then the union will contain |
126 simpsets differ in other components (the subgoaler, solver, looper or rule |
193 the unwanted rules. |
127 preprocessor: see below), then you cannot be sure which version of that |
|
128 component will be inherited. You may have to set the component explicitly |
|
129 for the new theory's simpset by an assignment of the form |
|
130 {\tt simpset := \dots}. |
|
131 \end{warn} |
194 \end{warn} |
132 |
195 |
133 \begin{warn} |
|
134 If you execute proofs interactively, or load them from an ML file without |
|
135 associated {\tt .thy} file, you must set the current simpset by calling |
|
136 \ttindex{set_current_thy}~{\tt"}$T${\tt"}, where $T$ is the name of the |
|
137 theory you want to work in. If you have just loaded $T$, this is not |
|
138 necessary. |
|
139 \end{warn} |
|
140 |
|
141 |
196 |
142 \section{Simplification sets}\index{simplification sets} |
197 \section{Simplification sets}\index{simplification sets} |
143 The simplification tactics are controlled by {\bf simpsets}. These |
198 |
144 consist of several components, including rewrite rules, congruence |
199 The simplifier is controlled by information contained in {\bf |
145 rules, the subgoaler, the solver and the looper. The simplifier |
200 simpsets}. These consist of several components, including rewrite |
146 should be set up with sensible defaults so that most simplifier calls |
201 rules, simplification procedures, congruence rules, and the subgoaler, |
147 specify only rewrite rules. Experienced users can exploit the other |
202 solver and looper tactics. The simplifier should be set up with |
148 components to streamline proofs. |
203 sensible defaults so that most simplifier calls specify only rewrite |
149 |
204 rules or simplification procedures. Experienced users can exploit the |
150 Logics like \HOL, which support a current |
205 other components to streamline proofs in more sophisticated manners. |
151 simpset\index{simpset!current}, store its value in an ML reference |
206 |
152 variable called {\tt simpset}\index{simpset@{\tt simpset} ML value}. |
207 \subsection{Inspecting simpsets} |
|
208 \begin{ttbox} |
|
209 print_ss : simpset -> unit |
|
210 \end{ttbox} |
|
211 \begin{ttdescription} |
|
212 |
|
213 \item[\ttindexbold{print_ss} $ss$;] displays the printable contents of |
|
214 simpset $ss$. This includes the rewrite rules and congruences in |
|
215 their internal form expressed as meta-equalities. The names of the |
|
216 simplification procedures and the patterns they are invoked on are |
|
217 also shown. The other parts, functions and tactics, are |
|
218 non-printable. |
|
219 |
|
220 \end{ttdescription} |
|
221 |
|
222 |
|
223 \subsection{Building simpsets} |
|
224 \begin{ttbox} |
|
225 empty_ss : simpset |
|
226 merge_ss : simpset * simpset -> simpset |
|
227 \end{ttbox} |
|
228 \begin{ttdescription} |
|
229 |
|
230 \item[\ttindexbold{empty_ss}] is the empty simpset. This is not very |
|
231 useful under normal circumstances because it doesn't contain |
|
232 suitable tactics (subgoaler etc.). When setting up the simplifier |
|
233 for a particular object-logic, one will typically define a more |
|
234 appropriate ``almost empty'' simpset. For example, in \HOL\ this is |
|
235 called \ttindexbold{HOL_basic_ss}. |
|
236 |
|
237 \item[\ttindexbold{merge_ss} ($ss@1$, $ss@2$)] merges simpsets $ss@1$ |
|
238 and $ss@2$ by building the union of their respective rewrite rules, |
|
239 simplification procedures and congruences. The other components |
|
240 (tactics etc.) cannot be merged, though; they are simply inherited |
|
241 from either simpset. |
|
242 |
|
243 \end{ttdescription} |
|
244 |
|
245 |
|
246 \subsection{Accessing the current simpset} |
|
247 |
|
248 \begin{ttbox} |
|
249 simpset : unit -> simpset |
|
250 simpset_ref : unit -> simpset ref |
|
251 simpset_of : theory -> simpset |
|
252 simpset_ref_of : theory -> simpset ref |
|
253 print_simpset : theory -> unit |
|
254 \end{ttbox} |
|
255 |
|
256 Each theory contains a current simpset\index{simpset!current} stored |
|
257 within a private ML reference variable. This can be retrieved and |
|
258 modified as follows. |
|
259 |
|
260 \begin{ttdescription} |
|
261 |
|
262 \item[\ttindexbold{simpset}();] retrieves the simpset value from the |
|
263 current theory context. |
|
264 |
|
265 \item[\ttindexbold{simpset_ref}();] retrieves the simpset reference |
|
266 variable from the current theory context. This can be assigned to |
|
267 by using \texttt{:=} in ML. |
|
268 |
|
269 \item[\ttindexbold{simpset_of} $thy$;] retrieves the simpset value |
|
270 from theory $thy$. |
|
271 |
|
272 \item[\ttindexbold{simpset_ref_of} $thy$;] retrieves the simpset |
|
273 reference variable from theory $thy$. |
|
274 |
|
275 \item[\ttindexbold{print_simpset} $thy$;] prints the current simpset |
|
276 of theory $thy$ in the same way as \texttt{print_ss}. |
|
277 |
|
278 \end{ttdescription} |
|
279 |
153 |
280 |
154 \subsection{Rewrite rules} |
281 \subsection{Rewrite rules} |
155 \index{rewrite rules|(} |
282 \begin{ttbox} |
156 Rewrite rules are theorems expressing some form of equality: |
283 addsimps : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
284 delsimps : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
285 \end{ttbox} |
|
286 |
|
287 \index{rewrite rules|(} Rewrite rules are theorems expressing some |
|
288 form of equality, for example: |
157 \begin{eqnarray*} |
289 \begin{eqnarray*} |
158 Suc(\Var{m}) + \Var{n} &=& \Var{m} + Suc(\Var{n}) \\ |
290 Suc(\Var{m}) + \Var{n} &=& \Var{m} + Suc(\Var{n}) \\ |
159 \Var{P}\conj\Var{P} &\bimp& \Var{P} \\ |
291 \Var{P}\conj\Var{P} &\bimp& \Var{P} \\ |
160 \Var{A} \un \Var{B} &\equiv& \{x.x\in \Var{A} \disj x\in \Var{B}\} |
292 \Var{A} \un \Var{B} &\equiv& \{x.x\in \Var{A} \disj x\in \Var{B}\} |
161 \end{eqnarray*} |
293 \end{eqnarray*} |
162 Conditional rewrites such as $\Var{m}<\Var{n} \Imp \Var{m}/\Var{n} = |
294 Conditional rewrites such as $\Var{m}<\Var{n} \Imp \Var{m}/\Var{n} = |
163 0$ are permitted; the conditions can be arbitrary formulas. |
295 0$ are also permitted; the conditions can be arbitrary formulas. |
164 |
296 |
165 Internally, all rewrite rules are translated into meta-equalities, theorems |
297 Internally, all rewrite rules are translated into meta-equalities, |
166 with conclusion $lhs \equiv rhs$. Each simpset contains a function for |
298 theorems with conclusion $lhs \equiv rhs$. Each simpset contains a |
167 extracting equalities from arbitrary theorems. For example, |
299 function for extracting equalities from arbitrary theorems. For |
168 $\neg(\Var{x}\in \{\})$ could be turned into $\Var{x}\in \{\} \equiv |
300 example, $\neg(\Var{x}\in \{\})$ could be turned into $\Var{x}\in \{\} |
169 False$. This function can be installed using \ttindex{setmksimps} but only |
301 \equiv False$. This function can be installed using |
170 the definer of a logic should need to do this; see \S\ref{sec:setmksimps}. |
302 \ttindex{setmksimps} but only the definer of a logic should need to do |
171 The function processes theorems added by \ttindex{addsimps} as well as |
303 this; see \S\ref{sec:setmksimps}. The function processes theorems |
172 local assumptions. |
304 added by \texttt{addsimps} as well as local assumptions. |
173 |
305 |
|
306 \begin{ttdescription} |
|
307 |
|
308 \item[$ss$ \ttindexbold{addsimps} $thms$] adds rewrite rules derived |
|
309 from $thms$ to the simpset $ss$. |
|
310 |
|
311 \item[$ss$ \ttindexbold{delsimps} $thms$] deletes rewrite rules |
|
312 derived from $thms$ from the simpset $ss$. |
|
313 |
|
314 \end{ttdescription} |
174 |
315 |
175 \begin{warn} |
316 \begin{warn} |
176 The simplifier will accept all standard rewrite rules: those |
317 The simplifier will accept all standard rewrite rules: those where |
177 where all unknowns are of base type. Hence ${\Var{i}+(\Var{j}+\Var{k})} = |
318 all unknowns are of base type. Hence ${\Var{i}+(\Var{j}+\Var{k})} = |
178 {(\Var{i}+\Var{j})+\Var{k}}$ is ok. |
319 {(\Var{i}+\Var{j})+\Var{k}}$ is OK. |
179 |
320 |
180 It will also deal gracefully with all rules whose left-hand sides are |
321 It will also deal gracefully with all rules whose left-hand sides |
181 so-called {\em higher-order patterns}~\cite{nipkow-patterns}. |
322 are so-called {\em higher-order patterns}~\cite{nipkow-patterns}. |
182 \indexbold{higher-order pattern}\indexbold{pattern, higher-order} |
323 \indexbold{higher-order pattern}\indexbold{pattern, higher-order} |
183 These are terms in $\beta$-normal form (this will always be the case unless |
324 These are terms in $\beta$-normal form (this will always be the case |
184 you have done something strange) where each occurrence of an unknown is of |
325 unless you have done something strange) where each occurrence of an |
185 the form $\Var{F}(x@1,\dots,x@n)$, where the $x@i$ are distinct bound |
326 unknown is of the form $\Var{F}(x@1,\dots,x@n)$, where the $x@i$ are |
186 variables. Hence $(\forall x.\Var{P}(x) \land \Var{Q}(x)) \bimp (\forall |
327 distinct bound variables. Hence $(\forall x.\Var{P}(x) \land |
187 x.\Var{P}(x)) \land (\forall x.\Var{Q}(x))$ is also ok, in both directions. |
328 \Var{Q}(x)) \bimp (\forall x.\Var{P}(x)) \land (\forall |
188 |
329 x.\Var{Q}(x))$ is also OK, in both directions. |
189 In some rare cases the rewriter will even deal with quite general rules: for |
330 |
190 example ${\Var{f}(\Var{x})\in range(\Var{f})} = True$ rewrites $g(a) \in |
331 In some rare cases the rewriter will even deal with quite general |
191 range(g)$ to $True$, but will fail to match $g(h(b)) \in range(\lambda |
332 rules: for example ${\Var{f}(\Var{x})\in range(\Var{f})} = True$ |
192 x.g(h(x)))$. However, you can replace the offending subterms (in our case |
333 rewrites $g(a) \in range(g)$ to $True$, but will fail to match |
193 $\Var{f}(\Var{x})$, which is not a pattern) by adding new variables and |
334 $g(h(b)) \in range(\lambda x.g(h(x)))$. However, you can replace |
194 conditions: $\Var{y} = \Var{f}(\Var{x}) \Imp \Var{y}\in range(\Var{f}) |
335 the offending subterms (in our case $\Var{f}(\Var{x})$, which is not |
195 = True$ is acceptable as a conditional rewrite rule since conditions can |
336 a pattern) by adding new variables and conditions: $\Var{y} = |
196 be arbitrary terms. |
337 \Var{f}(\Var{x}) \Imp \Var{y}\in range(\Var{f}) = True$ is |
197 |
338 acceptable as a conditional rewrite rule since conditions can be |
198 There is no restriction on the form of the right-hand sides. |
339 arbitrary terms. |
|
340 |
|
341 There is basically no restriction on the form of the right-hand |
|
342 sides. They may not contain extraneous term or type variables, |
|
343 though. |
199 \end{warn} |
344 \end{warn} |
200 |
|
201 \index{rewrite rules|)} |
345 \index{rewrite rules|)} |
202 |
346 |
203 \subsection{*Congruence rules}\index{congruence rules} |
347 |
|
348 \subsection{Simplification procedures} |
|
349 \begin{ttbox} |
|
350 addsimprocs : simpset * simproc list -> simpset |
|
351 delsimprocs : simpset * simproc list -> simpset |
|
352 \end{ttbox} |
|
353 |
|
354 Simplification procedures are {\ML} functions that may produce |
|
355 \emph{proven} rewrite rules on demand. They are associated with |
|
356 certain patterns that conceptually represent left-hand sides of |
|
357 equations; these are shown by \texttt{print_ss}. During its |
|
358 operation, the simplifier may offer a simplification procedure the |
|
359 current redex and ask for a suitable rewrite rule. Thus rules may be |
|
360 specifically fashioned for particular situations, resulting in a more |
|
361 powerful mechanism than term rewriting by a fixed set of rules. |
|
362 |
|
363 |
|
364 \begin{ttdescription} |
|
365 |
|
366 \item[$ss$ \ttindexbold{addsimprocs} $procs$] adds simplification |
|
367 procedures $procs$ to the current simpset. |
|
368 |
|
369 \item[$ss$ \ttindexbold{delsimprocs} $procs$] deletes simplification |
|
370 procedures $procs$ from the current simpset. |
|
371 |
|
372 \end{ttdescription} |
|
373 |
|
374 |
|
375 \subsection{*Congruence rules}\index{congruence rules}\label{sec:simp-congs} |
|
376 \begin{ttbox} |
|
377 addcongs : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
378 delcongs : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
379 addeqcongs : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
380 deleqcongs : simpset * thm list -> simpset \hfill{\bf infix 4} |
|
381 \end{ttbox} |
|
382 |
204 Congruence rules are meta-equalities of the form |
383 Congruence rules are meta-equalities of the form |
205 \[ \dots \Imp |
384 \[ \dots \Imp |
206 f(\Var{x@1},\ldots,\Var{x@n}) \equiv f(\Var{y@1},\ldots,\Var{y@n}). |
385 f(\Var{x@1},\ldots,\Var{x@n}) \equiv f(\Var{y@1},\ldots,\Var{y@n}). |
207 \] |
386 \] |
208 This governs the simplification of the arguments of~$f$. For |
387 This governs the simplification of the arguments of~$f$. For |
209 example, some arguments can be simplified under additional assumptions: |
388 example, some arguments can be simplified under additional assumptions: |
210 \[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}} |
389 \[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}} |
211 \Imp (\Var{P@1} \imp \Var{P@2}) \equiv (\Var{Q@1} \imp \Var{Q@2}) |
390 \Imp (\Var{P@1} \imp \Var{P@2}) \equiv (\Var{Q@1} \imp \Var{Q@2}) |
212 \] |
391 \] |
213 Given this rule, the simplifier assumes $Q@1$ and extracts rewrite rules |
392 Given this rule, the simplifier assumes $Q@1$ and extracts rewrite |
214 from it when simplifying~$P@2$. Such local assumptions are effective for |
393 rules from it when simplifying~$P@2$. Such local assumptions are |
215 rewriting formulae such as $x=0\imp y+x=y$. The local assumptions are also |
394 effective for rewriting formulae such as $x=0\imp y+x=y$. The local |
216 provided as theorems to the solver; see page~\pageref{sec:simp-solver} below. |
395 assumptions are also provided as theorems to the solver; see |
217 |
396 \S~\ref{sec:simp-solver} below. |
218 Here are some more examples. The congruence rule for bounded quantifiers |
397 |
219 also supplies contextual information, this time about the bound variable: |
398 \begin{ttdescription} |
|
399 |
|
400 \item[$ss$ \ttindexbold{addcongs} $thms$] adds congruence rules to the |
|
401 simpset $ss$. These are derived from $thms$ in an appropriate way, |
|
402 depending on the underlying object-logic. |
|
403 |
|
404 \item[$ss$ \ttindexbold{delcongs} $thms$] deletes congruence rules |
|
405 derived from $thms$. |
|
406 |
|
407 \item[$ss$ \ttindexbold{addeqcongs} $thms$] adds congruence rules in |
|
408 their internal form (conclusions using meta-equality) to simpset |
|
409 $ss$. This is the basic mechanism that \texttt{addcongs} is built |
|
410 on. It should be rarely used directly. |
|
411 |
|
412 \item[$ss$ \ttindexbold{deleqcongs} $thms$] deletes congruence rules |
|
413 in internal form from simpset $ss$. |
|
414 |
|
415 \end{ttdescription} |
|
416 |
|
417 \medskip |
|
418 |
|
419 Here are some more examples. The congruence rule for bounded |
|
420 quantifiers also supplies contextual information, this time about the |
|
421 bound variable: |
220 \begin{eqnarray*} |
422 \begin{eqnarray*} |
221 &&\List{\Var{A}=\Var{B};\; |
423 &&\List{\Var{A}=\Var{B};\; |
222 \Forall x. x\in \Var{B} \Imp \Var{P}(x) = \Var{Q}(x)} \Imp{} \\ |
424 \Forall x. x\in \Var{B} \Imp \Var{P}(x) = \Var{Q}(x)} \Imp{} \\ |
223 &&\qquad\qquad |
425 &&\qquad\qquad |
224 (\forall x\in \Var{A}.\Var{P}(x)) = (\forall x\in \Var{B}.\Var{Q}(x)) |
426 (\forall x\in \Var{A}.\Var{P}(x)) = (\forall x\in \Var{B}.\Var{Q}(x)) |
236 \] |
438 \] |
237 Only the first argument is simplified; the others remain unchanged. |
439 Only the first argument is simplified; the others remain unchanged. |
238 This can make simplification much faster, but may require an extra case split |
440 This can make simplification much faster, but may require an extra case split |
239 to prove the goal. |
441 to prove the goal. |
240 |
442 |
241 Congruence rules are added/deleted using |
443 |
242 \ttindexbold{addeqcongs}/\ttindex{deleqcongs}. |
444 \subsection{*The subgoaler}\label{sec:simp-subgoaler} |
243 Their conclusion must be a meta-equality, as in the examples above. It is more |
445 \begin{ttbox} |
244 natural to derive the rules with object-logic equality, for example |
446 setsubgoaler : simpset * (simpset -> int -> tactic) -> simpset \hfill{\bf infix 4} |
245 \[ \List{\Var{P@1} \bimp \Var{Q@1};\; \Var{Q@1} \Imp \Var{P@2} \bimp \Var{Q@2}} |
447 prems_of_ss : simpset -> thm list |
246 \Imp (\Var{P@1} \imp \Var{P@2}) \bimp (\Var{Q@1} \imp \Var{Q@2}), |
448 \end{ttbox} |
247 \] |
449 |
248 Each object-logic should define operators called \ttindex{addcongs} and |
|
249 \ttindex{delcongs} that expects object-equalities and translates them into |
|
250 meta-equalities. |
|
251 |
|
252 \subsection{*The subgoaler} |
|
253 The subgoaler is the tactic used to solve subgoals arising out of |
450 The subgoaler is the tactic used to solve subgoals arising out of |
254 conditional rewrite rules or congruence rules. The default should be |
451 conditional rewrite rules or congruence rules. The default should be |
255 simplification itself. Occasionally this strategy needs to be changed. For |
452 simplification itself. Occasionally this strategy needs to be |
256 example, if the premise of a conditional rule is an instance of its |
453 changed. For example, if the premise of a conditional rule is an |
257 conclusion, as in $Suc(\Var{m}) < \Var{n} \Imp \Var{m} < \Var{n}$, the |
454 instance of its conclusion, as in $Suc(\Var{m}) < \Var{n} \Imp \Var{m} |
258 default strategy could loop. |
455 < \Var{n}$, the default strategy could loop. |
259 |
456 |
260 The subgoaler can be set explicitly with \ttindex{setsubgoaler}. For |
457 \begin{ttdescription} |
261 example, the subgoaler |
458 |
262 \begin{ttbox} |
459 \item[$ss$ \ttindexbold{setsubgoaler} $tacf$] sets the subgoaler of |
263 fun subgoal_tac ss = assume_tac ORELSE' |
460 $ss$ to $tacf$. The function $tacf$ will be applied to the current |
264 resolve_tac (prems_of_ss ss) ORELSE' |
461 simplifier context expressed as a simpset. |
265 asm_simp_tac ss; |
462 |
266 \end{ttbox} |
463 \item[\ttindexbold{prems_of_ss} $ss$] retrieves the current set of |
267 tries to solve the subgoal by assumption or with one of the premises, calling |
464 premises from simplifier context $ss$. This may be non-empty only |
268 simplification only if that fails; here {\tt prems_of_ss} extracts the |
465 if the simplifier has been told to utilize local assumptions in the |
269 current premises from a simpset. |
466 first place, e.g.\ if invoked via \texttt{asm_simp_tac}. |
|
467 |
|
468 \end{ttdescription} |
|
469 |
|
470 As an example, consider the following subgoaler: |
|
471 \begin{ttbox} |
|
472 fun subgoaler ss = |
|
473 assume_tac ORELSE' |
|
474 resolve_tac (prems_of_ss ss) ORELSE' |
|
475 asm_simp_tac ss; |
|
476 \end{ttbox} |
|
477 This tactic first tries to solve the subgoal by assumption or by |
|
478 resolving with with one of the premises, calling simplification only |
|
479 if that fails. |
|
480 |
270 |
481 |
271 \subsection{*The solver}\label{sec:simp-solver} |
482 \subsection{*The solver}\label{sec:simp-solver} |
|
483 \begin{ttbox} |
|
484 setSolver : simpset * (thm list -> int -> tactic) -> simpset \hfill{\bf infix 4} |
|
485 addSolver : simpset * (thm list -> int -> tactic) -> simpset \hfill{\bf infix 4} |
|
486 setSSolver : simpset * (thm list -> int -> tactic) -> simpset \hfill{\bf infix 4} |
|
487 addSSolver : simpset * (thm list -> int -> tactic) -> simpset \hfill{\bf infix 4} |
|
488 \end{ttbox} |
|
489 |
272 The solver is a pair of tactics that attempt to solve a subgoal after |
490 The solver is a pair of tactics that attempt to solve a subgoal after |
273 simplification. Typically it just proves trivial subgoals such as {\tt |
491 simplification. Typically it just proves trivial subgoals such as |
274 True} and $t=t$. It could use sophisticated means such as {\tt |
492 {\tt True} and $t=t$. It could use sophisticated means such as {\tt |
275 blast_tac}, though that could make simplification expensive. |
493 blast_tac}, though that could make simplification expensive. |
276 |
494 |
277 Rewriting does not instantiate unknowns. For example, rewriting |
495 Rewriting does not instantiate unknowns. For example, rewriting |
278 cannot prove $a\in \Var{A}$ since this requires |
496 cannot prove $a\in \Var{A}$ since this requires |
279 instantiating~$\Var{A}$. The solver, however, is an arbitrary tactic |
497 instantiating~$\Var{A}$. The solver, however, is an arbitrary tactic |
280 and may instantiate unknowns as it pleases. This is the only way the |
498 and may instantiate unknowns as it pleases. This is the only way the |
281 simplifier can handle a conditional rewrite rule whose condition |
499 simplifier can handle a conditional rewrite rule whose condition |
282 contains extra variables. When a simplification tactic is to be |
500 contains extra variables. When a simplification tactic is to be |
283 combined with other provers, especially with the classical reasoner, |
501 combined with other provers, especially with the classical reasoner, |
284 it is important whether it can be considered safe or not. Therefore, |
502 it is important whether it can be considered safe or not. For this |
285 the solver is split into a safe and an unsafe part. Both parts can be |
503 reason the solver is split into a safe and an unsafe part. |
286 set independently, using either \ttindex{setSSolver} with a safe |
|
287 tactic as argument, or \ttindex{setSolver} with an unsafe tactic. |
|
288 Additional solvers, which are tried after the already set solvers, may |
|
289 be added using \ttindex{addSSolver} and \ttindex{addSolver}. |
|
290 |
504 |
291 The standard simplification strategy solely uses the unsafe solver, |
505 The standard simplification strategy solely uses the unsafe solver, |
292 which is appropriate in most cases. But for special applications where |
506 which is appropriate in most cases. For special applications where |
293 the simplification process is not allowed to instantiate unknowns |
507 the simplification process is not allowed to instantiate unknowns |
294 within the goal, the tactic \ttindexbold{safe_asm_full_simp_tac} is |
508 within the goal, simplification starts with the safe solver, but may |
295 provided. It uses the \emph{safe} solver for the current subgoal, but |
509 still apply the ordinary unsafe one in nested simplifications for |
296 applies ordinary unsafe {\tt asm_full_simp_tac} for recursive internal |
510 conditional rules or congruences. |
297 simplifications (for conditional rules or congruences). |
511 |
298 |
512 \begin{ttdescription} |
299 \index{assumptions!in simplification} |
513 |
300 The tactic is presented with the full goal, including the asssumptions. |
514 \item[$ss$ \ttindexbold{setSSolver} $tacf$] installs $tacf$ as the |
301 Hence it can use those assumptions (say by calling {\tt assume_tac}) even |
515 \emph{safe} solver of $ss$. |
302 inside {\tt simp_tac}, which otherwise does not use assumptions. The |
516 |
303 solver is also supplied a list of theorems, namely assumptions that hold in |
517 \item[$ss$ \ttindexbold{addSSolver} $tacf$] adds $tacf$ as an |
304 the local context. |
518 additional \emph{safe} solver; it will be tried after the solvers |
305 |
519 which had already been present in $ss$. |
306 The subgoaler is also used to solve the premises of congruence rules, which |
520 |
307 are usually of the form $s = \Var{x}$, where $s$ needs to be simplified and |
521 \item[$ss$ \ttindexbold{setSolver} $tacf$] installs $tacf$ as the |
308 $\Var{x}$ needs to be instantiated with the result. Hence the subgoaler |
522 unsafe solver of $ss$. |
309 should call the simplifier at some point. The simplifier will then call the |
523 |
310 solver, which must therefore be prepared to solve goals of the form $t = |
524 \item[$ss$ \ttindexbold{addSolver} $tacf$] adds $tacf$ as an |
311 \Var{x}$, usually by reflexivity. In particular, reflexivity should be |
525 additional unsafe solver; it will be tried after the solvers which |
312 tried before any of the fancy tactics like {\tt blast_tac}. |
526 had already been present in $ss$. |
|
527 |
|
528 \end{ttdescription} |
|
529 |
|
530 \medskip |
|
531 |
|
532 \index{assumptions!in simplification} The solver tactic is invoked |
|
533 with a list of theorems, namely assumptions that hold in the local |
|
534 context. This may be non-empty only if the simplifier has been told |
|
535 to utilize local assumptions in the first place, e.g.\ if invoked via |
|
536 \texttt{asm_simp_tac}. The solver is also presented the full goal |
|
537 including its assumptions in any case. Thus it can use these (e.g.\ |
|
538 by calling \texttt{assume_tac}), even if the list of premises is not |
|
539 passed. |
|
540 |
|
541 \medskip |
|
542 |
|
543 As explained in \S\ref{sec:simp-subgoaler}, the subgoaler is also used |
|
544 to solve the premises of congruence rules. These are usually of the |
|
545 form $s = \Var{x}$, where $s$ needs to be simplified and $\Var{x}$ |
|
546 needs to be instantiated with the result. Typically, the subgoaler |
|
547 will invoke the simplifier at some point, which will eventually call |
|
548 the solver. For this reason, solver tactics must be prepared to solve |
|
549 goals of the form $t = \Var{x}$, usually by reflexivity. In |
|
550 particular, reflexivity should be tried before any of the fancy |
|
551 tactics like {\tt blast_tac}. |
313 |
552 |
314 It may even happen that due to simplification the subgoal is no longer |
553 It may even happen that due to simplification the subgoal is no longer |
315 an equality. For example $False \bimp \Var{Q}$ could be rewritten to |
554 an equality. For example $False \bimp \Var{Q}$ could be rewritten to |
316 $\neg\Var{Q}$. To cover this case, the solver could try resolving |
555 $\neg\Var{Q}$. To cover this case, the solver could try resolving |
317 with the theorem $\neg False$. |
556 with the theorem $\neg False$. |
318 |
557 |
|
558 \medskip |
|
559 |
319 \begin{warn} |
560 \begin{warn} |
320 If the simplifier aborts with the message {\tt Failed congruence |
561 If the simplifier aborts with the message \texttt{Failed congruence |
321 proof!}, then the subgoaler or solver has failed to prove a |
562 proof!}, then the subgoaler or solver has failed to prove a |
322 premise of a congruence rule. This should never occur under normal |
563 premise of a congruence rule. This should never occur under normal |
323 circumstances; it indicates that some congruence rule, or possibly |
564 circumstances; it indicates that some congruence rule, or possibly |
324 the subgoaler or solver, is faulty. |
565 the subgoaler or solver, is faulty. |
325 \end{warn} |
566 \end{warn} |
326 |
567 |
327 |
568 |
328 \subsection{*The looper} |
569 \subsection{*The looper}\label{sec:simp-looper} |
329 The looper is a tactic that is applied after simplification, in case the |
570 \begin{ttbox} |
330 solver failed to solve the simplified goal. If the looper succeeds, the |
571 setloop : simpset * (int -> tactic) -> simpset \hfill{\bf infix 4} |
331 simplification process is started all over again. Each of the subgoals |
572 addloop : simpset * (int -> tactic) -> simpset \hfill{\bf infix 4} |
332 generated by the looper is attacked in turn, in reverse order. A |
573 addsplits : simpset * thm list -> simpset \hfill{\bf infix 4} |
333 typical looper is case splitting: the expansion of a conditional. Another |
574 \end{ttbox} |
334 possibility is to apply an elimination rule on the assumptions. More |
575 |
335 adventurous loopers could start an induction. The looper is set with |
576 The looper is a tactic that is applied after simplification, in case |
336 \ttindex{setloop}. Additional loopers, which are tried after the already set |
577 the solver failed to solve the simplified goal. If the looper |
337 looper, may be added with \ttindex{addloop}. |
578 succeeds, the simplification process is started all over again. Each |
338 |
579 of the subgoals generated by the looper is attacked in turn, in |
339 |
580 reverse order. |
340 \begin{figure} |
581 |
341 \index{*simpset ML type} |
582 A typical looper is case splitting: the expansion of a conditional. |
342 \index{*empty_ss} |
583 Another possibility is to apply an elimination rule on the |
343 \index{*rep_ss} |
584 assumptions. More adventurous loopers could start an induction. |
344 \index{*prems_of_ss} |
585 |
345 \index{*setloop} |
586 \begin{ttdescription} |
346 \index{*addloop} |
587 |
347 \index{*setSSolver} |
588 \item[$ss$ \ttindexbold{setloop} $tacf$] installs $tacf$ as the looper |
348 \index{*addSSolver} |
589 of $ss$. |
349 \index{*setSolver} |
590 |
350 \index{*addSolver} |
591 \item[$ss$ \ttindexbold{addloop} $tacf$] adds $tacf$ as an additional |
351 \index{*setsubgoaler} |
592 looper; it will be tried after the loopers which had already been |
352 \index{*setmksimps} |
593 present in $ss$. |
353 \index{*addsimps} |
594 |
354 \index{*delsimps} |
595 \item[$ss$ \ttindexbold{addsplits} $thms$] adds |
355 \index{*addeqcongs} |
596 \texttt{(split_tac~$thms$)} as an additional looper. |
356 \index{*deleqcongs} |
597 |
357 \index{*merge_ss} |
598 \end{ttdescription} |
358 \index{*simpset} |
599 |
359 \index{*Addsimps} |
600 |
360 \index{*Delsimps} |
601 |
361 \index{*simp_tac} |
602 \section{The simplification tactics}\label{simp-tactics} |
362 \index{*asm_simp_tac} |
603 \index{simplification!tactics}\index{tactics!simplification} |
363 \index{*full_simp_tac} |
604 \begin{ttbox} |
364 \index{*asm_full_simp_tac} |
605 simp_tac : simpset -> int -> tactic |
365 \index{*safe_asm_full_simp_tac} |
606 asm_simp_tac : simpset -> int -> tactic |
366 \index{*Simp_tac} |
607 full_simp_tac : simpset -> int -> tactic |
367 \index{*Asm_simp_tac} |
608 asm_full_simp_tac : simpset -> int -> tactic |
368 \index{*Full_simp_tac} |
609 safe_asm_full_simp_tac : simpset -> int -> tactic |
369 \index{*Asm_full_simp_tac} |
610 SIMPSET : (simpset -> tactic) -> tactic |
370 |
611 SIMPSET' : (simpset -> 'a -> tactic) -> 'a -> tactic |
371 \begin{ttbox} |
612 \end{ttbox} |
372 infix 4 setsubgoaler setloop addloop |
613 |
373 setSSolver addSSolver setSolver addSolver |
614 These are the basic tactics that are underlying any actual |
374 setmksimps addsimps delsimps addeqcongs deleqcongs; |
615 simplification work. The rewriting strategy is always strictly bottom |
375 |
616 up, except for congruence rules, which are applied while descending |
376 signature SIMPLIFIER = |
617 into a term. Conditions in conditional rewrite rules are solved |
377 sig |
618 recursively before the rewrite rule is applied. |
378 type simpset |
619 |
379 val empty_ss: simpset |
620 \begin{ttdescription} |
380 val rep_ss: simpset -> {\ttlbrace}simps: thm list, procs: string list, |
621 |
381 congs: thm list, |
622 \item[\ttindexbold{simp_tac}, \ttindexbold{asm_simp_tac}, |
382 subgoal_tac: simpset -> int -> tactic, |
623 \ttindexbold{full_simp_tac}, \ttindexbold{asm_full_simp_tac}] are |
383 loop_tac: int -> tactic, |
624 the basic simplification tactics that work exactly like their |
384 finish_tac: thm list -> int -> tactic, |
625 namesakes in \S\ref{sec:simp-for-dummies}, except that they are |
385 unsafe_finish_tac: thm list -> int -> tactic{\ttrbrace} |
626 explicitly supplied with a simpset. |
386 val setsubgoaler: simpset * (simpset -> int -> tactic) -> simpset |
627 |
387 val setloop: simpset * (int -> tactic) -> simpset |
628 \item[\ttindexbold{safe_asm_full_simp_tac}] is like |
388 val addloop: simpset * (int -> tactic) -> simpset |
629 \texttt{asm_full_simp_tac}, but uses the safe solver as explained in |
389 val setSSolver: simpset * (thm list -> int -> tactic) -> simpset |
630 \S\ref{sec:simp-solver}. This tactic is mainly intended for |
390 val addSSolver: simpset * (thm list -> int -> tactic) -> simpset |
631 building special tools, e.g.\ for combining the simplifier with the |
391 val setSolver: simpset * (thm list -> int -> tactic) -> simpset |
632 classical reasoner. It is rarely used directly. |
392 val addSolver: simpset * (thm list -> int -> tactic) -> simpset |
633 |
393 val setmksimps: simpset * (thm -> thm list) -> simpset |
634 \item[\ttindexbold{SIMPSET} $tacf$, \ttindexbold{SIMPSET'} $tacf'$] |
394 val addsimps: simpset * thm list -> simpset |
635 are tacticals that make a tactic depend on the implicit current |
395 val delsimps: simpset * thm list -> simpset |
636 simpset of the theory associated with the proof state they are |
396 val addeqcongs: simpset * thm list -> simpset |
637 applied on. |
397 val deleqcongs: simpset * thm list -> simpset |
638 |
398 val merge_ss: simpset * simpset -> simpset |
639 \end{ttdescription} |
399 val prems_of_ss: simpset -> thm list |
640 |
400 val simpset: simpset ref |
641 \medskip |
401 val Addsimps: thm list -> unit |
642 |
402 val Delsimps: thm list -> unit |
643 Local modifications of simpsets within a proof are often much cleaner |
403 val simp_tac: simpset -> int -> tactic |
644 by using above tactics in conjunction with explicit simpsets, rather |
404 val asm_simp_tac: simpset -> int -> tactic |
645 than their capitalized counterparts. For example |
405 val full_simp_tac: simpset -> int -> tactic |
|
406 val asm_full_simp_tac: simpset -> int -> tactic |
|
407 val safe_asm_full_simp_tac: simpset -> int -> tactic |
|
408 val Simp_tac: int -> tactic |
|
409 val Asm_simp_tac: int -> tactic |
|
410 val Full_simp_tac: int -> tactic |
|
411 val Asm_full_simp_tac: int -> tactic |
|
412 end; |
|
413 \end{ttbox} |
|
414 \caption{The simplifier primitives} \label{SIMPLIFIER} |
|
415 \end{figure} |
|
416 |
|
417 |
|
418 \section{The simplification tactics} |
|
419 \label{simp-tactics} |
|
420 \index{simplification!tactics} |
|
421 \index{tactics!simplification} |
|
422 |
|
423 The actual simplification work is performed by the following basic tactics: |
|
424 \ttindexbold{simp_tac}, \ttindexbold{asm_simp_tac}, |
|
425 \ttindexbold{full_simp_tac} and \ttindexbold{asm_full_simp_tac}. They work |
|
426 exactly like their namesakes in \S\ref{sec:simp-for-dummies}, except that |
|
427 they are explicitly supplied with a simpset. This is because the ones in |
|
428 \S\ref{sec:simp-for-dummies} are defined in terms of the ones above, e.g. |
|
429 \begin{ttbox} |
|
430 fun Simp_tac i = simp_tac (!simpset) i; |
|
431 \end{ttbox} |
|
432 where \ttindex{!simpset} is the current simpset\index{simpset!current}. |
|
433 |
|
434 The rewriting strategy of all four tactics is strictly bottom up, except for |
|
435 congruence rules, which are applied while descending into a term. Conditions |
|
436 in conditional rewrite rules are solved recursively before the rewrite rule |
|
437 is applied. |
|
438 |
|
439 The infix operation \ttindex{addsimps} adds rewrite rules to a |
|
440 simpset, while \ttindex{delsimps} deletes them. They are used to |
|
441 implement \ttindex{Addsimps} and \ttindex{Delsimps}, e.g. |
|
442 \begin{ttbox} |
|
443 fun Addsimps thms = (simpset := (!simpset addsimps thms)); |
|
444 \end{ttbox} |
|
445 and can also be used directly, even in the presence of a current simpset. For |
|
446 example |
|
447 \begin{ttbox} |
646 \begin{ttbox} |
448 Addsimps \(thms\); |
647 Addsimps \(thms\); |
449 by (Simp_tac \(i\)); |
648 by (Simp_tac \(i\)); |
450 Delsimps \(thms\); |
649 Delsimps \(thms\); |
451 \end{ttbox} |
650 \end{ttbox} |
452 can be compressed into |
651 can be expressed more appropriately as |
453 \begin{ttbox} |
652 \begin{ttbox} |
454 by (simp_tac (!simpset addsimps \(thms\)) \(i\)); |
653 by (simp_tac (simpset() addsimps \(thms\)) \(i\)); |
455 \end{ttbox} |
654 \end{ttbox} |
456 |
655 |
457 The simpset associated with a particular theory can be retrieved via the name |
656 \medskip |
458 of the theory using the function |
657 |
459 \begin{ttbox} |
658 Also note that functions depending implicitly on the current theory |
460 simpset_of: string -> simpset |
659 context (like capital \texttt{Simp_tac} and the other commands of |
461 \end{ttbox}\index{*simpset_of} |
660 \S\ref{sec:simp-for-dummies}) should be considered harmful outside of |
462 |
661 actual proof scripts. In particular, ML programs like theory |
463 To remind yourself of what is in a simpset, use the function \verb$rep_ss$ to |
662 definition packages or special tactics should refer to simpsets only |
464 return its simplification and congruence rules. |
663 explicitly, via the above tactics used in conjunction with |
465 |
664 \texttt{simpset_of} or the \texttt{SIMPSET} tacticals. |
466 \section{Examples using the simplifier} |
665 |
|
666 \begin{warn} |
|
667 There is a subtle difference between \texttt{(SIMPSET'~$tacf$)} and |
|
668 \texttt{($tacf$~(simpset()))}. For example \texttt{(SIMPSET' |
|
669 simp_tac)} would depend on the theory of the proof state it is |
|
670 applied to, while \texttt{(simp_tac (simpset()))} implicitly refers |
|
671 to the current theory context. Both are usually the same in proof |
|
672 scripts, provided that goals are only stated within the current |
|
673 theory. Robust programs would not count on that, of course. |
|
674 \end{warn} |
|
675 |
|
676 |
|
677 \section{Forward simplification rules} |
|
678 \index{simplification!forward rules} |
|
679 \begin{ttbox}\index{*simplify}\index{*asm_simplify}\index{*full_simplify}\index{*asm_full_simplify} |
|
680 simplify : simpset -> thm -> thm |
|
681 asm_simplify : simpset -> thm -> thm |
|
682 full_simplify : simpset -> thm -> thm |
|
683 asm_full_simplify : simpset -> thm -> thm |
|
684 \end{ttbox} |
|
685 |
|
686 These are forward rules, simplifying theorems in a similar way as the |
|
687 corresponding simplification tactics do. The forward rules affect the whole |
|
688 |
|
689 subgoals of a proof state. The |
|
690 looper~/ solver process as described in \S\ref{sec:simp-looper} and |
|
691 \S\ref{sec:simp-solver} does not apply here, though. |
|
692 |
|
693 \begin{warn} |
|
694 Forward simplification should be used rarely in ordinary proof |
|
695 scripts. It as mainly intended to provide an internal interface to |
|
696 the simplifier for ML coded special utilities. |
|
697 \end{warn} |
|
698 |
|
699 |
|
700 \section{Examples of using the simplifier} |
467 \index{examples!of simplification} Assume we are working within {\tt |
701 \index{examples!of simplification} Assume we are working within {\tt |
468 FOL} (cf.\ \texttt{FOL/ex/Nat}) and that |
702 FOL} (cf.\ \texttt{FOL/ex/Nat}) and that |
469 \begin{ttdescription} |
703 \begin{ttdescription} |
470 \item[Nat.thy] |
704 \item[Nat.thy] |
471 is a theory including the constants $0$, $Suc$ and $+$, |
705 is a theory including the constants $0$, $Suc$ and $+$, |
798 or~$u=t$.) Then the simplifier can prove the goal outright. |
1050 or~$u=t$.) Then the simplifier can prove the goal outright. |
799 |
1051 |
800 \index{rewrite rules!permutative|)} |
1052 \index{rewrite rules!permutative|)} |
801 |
1053 |
802 |
1054 |
|
1055 \section{*Coding simplification procedures} |
|
1056 \begin{ttbox} |
|
1057 mk_simproc: string -> cterm list -> |
|
1058 (Sign.sg -> thm list -> term -> thm option) -> simproc |
|
1059 \end{ttbox} |
|
1060 |
|
1061 \begin{ttdescription} |
|
1062 \item[\ttindexbold{mk_simproc}~$name$~$lhss$~$proc$] makes $proc$ a |
|
1063 simplification procedure for left-hand side patterns $lhss$. The |
|
1064 name just serves as a comment. The function $proc$ may be invoked |
|
1065 by the simplifier for redex positions matched by one of $lhss$ as |
|
1066 described below. |
|
1067 \end{ttdescription} |
|
1068 |
|
1069 Simplification procedures are applied in a two-stage process as |
|
1070 follows: The simplifier tries to match the current redex position |
|
1071 against any one of the $lhs$ patterns of any simplification procedure. |
|
1072 If this succeeds, it invokes the corresponding {\ML} function, passing |
|
1073 with the current signature, local assumptions and the (potential) |
|
1074 redex. The result may be either \texttt{None} (indicating failure) or |
|
1075 \texttt{Some~$thm$}. |
|
1076 |
|
1077 Any successful result is supposed to be a (possibly conditional) |
|
1078 rewrite rule $t \equiv u$ that is applicable to the current redex. |
|
1079 The rule will be applied just as any ordinary rewrite rule. It is |
|
1080 expected to be already in \emph{internal form}, though, bypassing the |
|
1081 automatic preprocessing of object-level equivalences. |
|
1082 |
|
1083 \medskip |
|
1084 |
|
1085 As an example of how to write your own simplification procedures, |
|
1086 consider eta-expansion of pair abstraction (see also |
|
1087 \texttt{HOL/Modelcheck/MCSyn} where this is used to provide external |
|
1088 model checker syntax). |
|
1089 |
|
1090 The {\HOL} theory of tuples (see \texttt{HOL/Prod}) provides an |
|
1091 operator \texttt{split} together with some concrete syntax supporting |
|
1092 $\lambda\,(x,y).b$ abstractions. Assume that we would like to offer a |
|
1093 tactic that rewrites any function $\lambda\,p.f\,p$ (where $p$ is of |
|
1094 some pair type) to $\lambda\,(x,y).f\,(x,y)$. The corresponding rule |
|
1095 is: |
|
1096 \begin{ttbox} |
|
1097 pair_eta_expand: (f::'a*'b=>'c) = (\%(x, y). f (x, y)) |
|
1098 \end{ttbox} |
|
1099 Unfortunately, term rewriting using this rule directly would not |
|
1100 terminate! We now use the simplification procedure mechanism in order |
|
1101 to stop the simplifier from applying this rule over and over again, |
|
1102 making it rewrite only actual abstractions. The simplification |
|
1103 procedure \texttt{pair_eta_expand_proc} is defined as follows: |
|
1104 \begin{ttbox} |
|
1105 local |
|
1106 val lhss = |
|
1107 [read_cterm (sign_of Prod.thy) ("f::'a*'b=>'c", TVar (("'a", 0), []))]; |
|
1108 val rew = mk_meta_eq pair_eta_expand; \medskip |
|
1109 fun proc _ _ (Abs _) = Some rew |
|
1110 | proc _ _ _ = None; |
|
1111 in |
|
1112 val pair_eta_expand_proc = Simplifier.mk_simproc "pair_eta_expand" lhss proc; |
|
1113 end; |
|
1114 \end{ttbox} |
|
1115 This is an example of using \texttt{pair_eta_expand_proc}: |
|
1116 \begin{ttbox} |
|
1117 {\out 1. P (\%p::'a * 'a. fst p + snd p + z)} |
|
1118 by (simp_tac (simpset() addsimprocs [pair_eta_expand_proc]) 1); |
|
1119 {\out 1. P (\%(x::'a,y::'a). x + y + z)} |
|
1120 \end{ttbox} |
|
1121 |
|
1122 \medskip |
|
1123 |
|
1124 In the above example the simplification procedure just did fine |
|
1125 grained control over rule application, beyond higher-order pattern |
|
1126 matching. Usually, procedures would do some more work, in particular |
|
1127 prove particular theorems depending on the current redex. |
|
1128 |
|
1129 For example, simplification procedures \ttindexbold{nat_cancel} of |
|
1130 \texttt{HOL/Arith} cancel common summands and constant factors out of |
|
1131 several relations of sums over natural numbers. |
|
1132 |
|
1133 Consider the following goal, which after cancelling $a$ on both sides |
|
1134 contains a factor of $2$. Simplifying with the simpset of |
|
1135 \texttt{Arith.thy} will do the cancellation automatically: |
|
1136 \begin{ttbox} |
|
1137 {\out 1. x + a + x < y + y + 2 + a + a + a + a + a} |
|
1138 by (Simp_tac 1); |
|
1139 {\out 1. x < Suc (a + (a + y))} |
|
1140 \end{ttbox} |
|
1141 |
|
1142 \medskip |
|
1143 |
|
1144 The {\ML} sources for these simplification procedures consist of a |
|
1145 generic part (files \texttt{cancel_sums.ML} and |
|
1146 \texttt{cancel_factor.ML} in \texttt{Provers/Arith}), and a |
|
1147 \texttt{HOL} specific part in \texttt{HOL/arith_data.ML}. |
|
1148 |
|
1149 |
803 \section{*Setting up the simplifier}\label{sec:setting-up-simp} |
1150 \section{*Setting up the simplifier}\label{sec:setting-up-simp} |
804 \index{simplification!setting up} |
1151 \index{simplification!setting up} |
805 |
1152 |
806 Setting up the simplifier for new logics is complicated. This section |
1153 Setting up the simplifier for new logics is complicated. This section |
807 describes how the simplifier is installed for intuitionistic first-order |
1154 describes how the simplifier is installed for intuitionistic |
808 logic; the code is largely taken from {\tt FOL/simpdata.ML}. |
1155 first-order logic; the code is largely taken from {\tt |
|
1156 FOL/simpdata.ML} of the Isabelle sources. |
809 |
1157 |
810 The simplifier and the case splitting tactic, which reside on separate |
1158 The simplifier and the case splitting tactic, which reside on separate |
811 files, are not part of Pure Isabelle. They must be loaded explicitly: |
1159 files, are not part of Pure Isabelle. They must be loaded explicitly |
812 \begin{ttbox} |
1160 by the object-logic as follows: |
813 use "../Provers/simplifier.ML"; |
1161 \begin{ttbox} |
814 use "../Provers/splitter.ML"; |
1162 use "$ISABELLE_HOME/src/Provers/simplifier.ML"; |
|
1163 use "$ISABELLE_HOME/src/Provers/splitter.ML"; |
815 \end{ttbox} |
1164 \end{ttbox} |
816 |
1165 |
817 Simplification works by reducing various object-equalities to |
1166 Simplification works by reducing various object-equalities to |
818 meta-equality. It requires rules stating that equal terms and equivalent |
1167 meta-equality. It requires rules stating that equal terms and equivalent |
819 formulae are also equal at the meta-level. The rule declaration part of |
1168 formulae are also equal at the meta-level. The rule declaration part of |
940 The three functions {\tt gen_all}, {\tt atomize} and {\tt mk_meta_eq} will |
1292 The three functions {\tt gen_all}, {\tt atomize} and {\tt mk_meta_eq} will |
941 be composed together and supplied below to {\tt setmksimps}. |
1293 be composed together and supplied below to {\tt setmksimps}. |
942 |
1294 |
943 |
1295 |
944 \subsection{Making the initial simpset} |
1296 \subsection{Making the initial simpset} |
945 It is time to assemble these items. We open module {\tt Simplifier} to |
1297 |
946 gain access to its components. We define the infix operator |
1298 It is time to assemble these items. We open module {\tt Simplifier} |
947 \ttindexbold{addcongs} to insert congruence rules; given a list of theorems, |
1299 to gain direct access to its components. We define the infix operator |
948 it converts their conclusions into meta-equalities and passes them to |
1300 \ttindex{addcongs} to insert congruence rules; given a list of |
949 \ttindex{addeqcongs}. |
1301 theorems, it converts their conclusions into meta-equalities and |
|
1302 passes them to \ttindex{addeqcongs}. |
950 \begin{ttbox} |
1303 \begin{ttbox} |
951 open Simplifier; |
1304 open Simplifier; |
952 \ttbreak |
1305 \ttbreak |
953 infix addcongs; |
1306 infix 4 addcongs; |
954 fun ss addcongs congs = |
1307 fun ss addcongs congs = |
955 ss addeqcongs (congs RL [eq_reflection,iff_reflection]); |
1308 ss addeqcongs (congs RL [eq_reflection,iff_reflection]); |
956 \end{ttbox} |
1309 \end{ttbox} |
957 The list {\tt IFOL_rews} contains the default rewrite rules for first-order |
1310 Furthermore, we define the infix operator \ttindex{addsplits} |
958 logic. The first of these is the reflexive law expressed as the |
1311 providing a convenient interface for adding split tactics. |
959 equivalence $(a=a)\bimp{\tt True}$; the rewrite rule $a=a$ is clearly useless. |
1312 \begin{ttbox} |
960 \begin{ttbox} |
1313 infix 4 addsplits; |
961 val IFOL_rews = |
1314 fun ss addsplits splits = ss addloop (split_tac splits); |
962 [refl RS P_iff_T] \at conj_rews \at disj_rews \at not_rews \at |
1315 \end{ttbox} |
963 imp_rews \at iff_rews \at quant_rews; |
1316 |
|
1317 The list {\tt IFOL_simps} contains the default rewrite rules for |
|
1318 first-order logic. The first of these is the reflexive law expressed |
|
1319 as the equivalence $(a=a)\bimp{\tt True}$; the rewrite rule $a=a$ is |
|
1320 clearly useless. |
|
1321 \begin{ttbox} |
|
1322 val IFOL_simps = |
|
1323 [refl RS P_iff_T] \at conj_simps \at disj_simps \at not_simps \at |
|
1324 imp_simps \at iff_simps \at quant_simps; |
964 \end{ttbox} |
1325 \end{ttbox} |
965 The list {\tt triv_rls} contains trivial theorems for the solver. Any |
1326 The list {\tt triv_rls} contains trivial theorems for the solver. Any |
966 subgoal that is simplified to one of these will be removed. |
1327 subgoal that is simplified to one of these will be removed. |
967 \begin{ttbox} |
1328 \begin{ttbox} |
968 val notFalseI = int_prove_fun "~False"; |
1329 val notFalseI = int_prove_fun "~False"; |
969 val triv_rls = [TrueI,refl,iff_refl,notFalseI]; |
1330 val triv_rls = [TrueI,refl,iff_refl,notFalseI]; |
970 \end{ttbox} |
1331 \end{ttbox} |
971 % |
1332 % |
972 The basic simpset for intuitionistic \FOL{} starts with \ttindex{empty_ss}. |
1333 The basic simpset for intuitionistic \FOL{} is |
973 It preprocess rewrites using {\tt gen_all}, {\tt atomize} and {\tt |
1334 \ttindexbold{FOL_basic_ss}. It preprocess rewrites using {\tt |
974 mk_meta_eq}. It solves simplified subgoals using {\tt triv_rls} and |
1335 gen_all}, {\tt atomize} and {\tt mk_meta_eq}. It solves simplified |
975 assumptions, and by detecting contradictions. |
1336 subgoals using {\tt triv_rls} and assumptions, and by detecting |
976 It uses \ttindex{asm_simp_tac} to tackle subgoals of |
1337 contradictions. It uses \ttindex{asm_simp_tac} to tackle subgoals of |
977 conditional rewrites. It takes {\tt IFOL_rews} as rewrite rules. |
1338 conditional rewrites. |
978 Other simpsets built from {\tt IFOL_ss} will inherit these items. |
1339 |
979 In particular, {\tt FOL_ss} extends {\tt IFOL_ss} with classical rewrite |
1340 Other simpsets built from {\tt FOL_basic_ss} will inherit these items. |
980 rules such as $\neg\neg P\bimp P$. |
1341 In particular, \ttindexbold{IFOL_ss}, which introduces {\tt |
|
1342 IFOL_simps} as rewrite rules. \ttindexbold{FOL_ss} will later |
|
1343 extend {\tt IFOL_ss} with classical rewrite rules such as $\neg\neg |
|
1344 P\bimp P$. |
981 \index{*setmksimps}\index{*setSSolver}\index{*setSolver}\index{*setsubgoaler} |
1345 \index{*setmksimps}\index{*setSSolver}\index{*setSolver}\index{*setsubgoaler} |
982 \index{*addsimps}\index{*addcongs} |
1346 \index{*addsimps}\index{*addcongs} |
983 \begin{ttbox} |
1347 \begin{ttbox} |
984 fun unsafe_solver prems = FIRST'[resolve_tac (triv_rls \at prems), |
1348 fun unsafe_solver prems = FIRST'[resolve_tac (triv_rls {\at} prems), |
985 atac, etac FalseE]; |
1349 atac, etac FalseE]; |
986 fun safe_solver prems = FIRST'[match_tac (triv_rls \at prems), |
1350 |
|
1351 fun safe_solver prems = FIRST'[match_tac (triv_rls {\at} prems), |
987 eq_assume_tac, ematch_tac [FalseE]]; |
1352 eq_assume_tac, ematch_tac [FalseE]]; |
988 val IFOL_ss = empty_ss setsubgoaler asm_simp_tac |
1353 |
989 setSSolver safe_solver |
1354 val FOL_basic_ss = empty_ss setsubgoaler asm_simp_tac |
990 setSolver unsafe_solver |
1355 addsimprocs [defALL_regroup,defEX_regroup] |
991 setmksimps (map mk_meta_eq o atomize o gen_all) |
1356 setSSolver safe_solver |
992 addsimps IFOL_simps |
1357 setSolver unsafe_solver |
993 addcongs [imp_cong]; |
1358 setmksimps (map mk_meta_eq o atomize o gen_all); |
|
1359 |
|
1360 val IFOL_ss = FOL_basic_ss addsimps (IFOL_simps {\at} int_ex_simps {\at} int_all_simps) |
|
1361 addcongs [imp_cong]; |
994 \end{ttbox} |
1362 \end{ttbox} |
995 This simpset takes {\tt imp_cong} as a congruence rule in order to use |
1363 This simpset takes {\tt imp_cong} as a congruence rule in order to use |
996 contextual information to simplify the conclusions of implications: |
1364 contextual information to simplify the conclusions of implications: |
997 \[ \List{\Var{P}\bimp\Var{P'};\; \Var{P'} \Imp \Var{Q}\bimp\Var{Q'}} \Imp |
1365 \[ \List{\Var{P}\bimp\Var{P'};\; \Var{P'} \Imp \Var{Q}\bimp\Var{Q'}} \Imp |
998 (\Var{P}\imp\Var{Q}) \bimp (\Var{P'}\imp\Var{Q'}) |
1366 (\Var{P}\imp\Var{Q}) \bimp (\Var{P'}\imp\Var{Q'}) |