75 of explicit records are simplified automatically:% |
75 of explicit records are simplified automatically:% |
76 \end{isamarkuptext}% |
76 \end{isamarkuptext}% |
77 \isamarkuptrue% |
77 \isamarkuptrue% |
78 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline |
78 \isacommand{lemma}\ {\isachardoublequote}Xcoord\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ a{\isachardoublequote}\isanewline |
79 \ \ \isamarkupfalse% |
79 \ \ \isamarkupfalse% |
80 \isamarkupfalse% |
80 \isacommand{by}\ simp\isamarkupfalse% |
81 % |
81 % |
82 \begin{isamarkuptext}% |
82 \begin{isamarkuptext}% |
83 The \emph{update}\index{update!record} operation is functional. For |
83 The \emph{update}\index{update!record} operation is functional. For |
84 example, \isa{p{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}} is a record whose \isa{Xcoord} |
84 example, \isa{p{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}} is a record whose \isa{Xcoord} |
85 value is zero and whose \isa{Ycoord} value is copied from~\isa{p}. Updates of explicit records are also simplified automatically:% |
85 value is zero and whose \isa{Ycoord} value is copied from~\isa{p}. Updates of explicit records are also simplified automatically:% |
86 \end{isamarkuptext}% |
86 \end{isamarkuptext}% |
87 \isamarkuptrue% |
87 \isamarkuptrue% |
88 \isacommand{lemma}\ {\isachardoublequote}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}\ {\isacharequal}\isanewline |
88 \isacommand{lemma}\ {\isachardoublequote}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ {\isadigit{0}}{\isasymrparr}\ {\isacharequal}\isanewline |
89 \ \ \ \ {\isasymlparr}Xcoord\ {\isacharequal}\ {\isadigit{0}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isachardoublequote}\isanewline |
89 \ \ \ \ {\isasymlparr}Xcoord\ {\isacharequal}\ {\isadigit{0}}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}{\isachardoublequote}\isanewline |
90 \ \ \isamarkupfalse% |
90 \ \ \isamarkupfalse% |
91 \isamarkupfalse% |
91 \isacommand{by}\ simp\isamarkupfalse% |
92 % |
92 % |
93 \begin{isamarkuptext}% |
93 \begin{isamarkuptext}% |
94 \begin{warn} |
94 \begin{warn} |
95 Field names are declared as constants and can no longer be used as |
95 Field names are declared as constants and can no longer be used as |
96 variables. It would be unwise, for example, to call the fields of |
96 variables. It would be unwise, for example, to call the fields of |
229 \end{isamarkuptext}% |
229 \end{isamarkuptext}% |
230 \isamarkuptrue% |
230 \isamarkuptrue% |
231 \isacommand{lemma}\ {\isachardoublequote}{\isacharparenleft}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharprime}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharprime}{\isasymrparr}{\isacharparenright}\ {\isacharequal}\isanewline |
231 \isacommand{lemma}\ {\isachardoublequote}{\isacharparenleft}{\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ a{\isacharprime}{\isacharcomma}\ Ycoord\ {\isacharequal}\ b{\isacharprime}{\isasymrparr}{\isacharparenright}\ {\isacharequal}\isanewline |
232 \ \ \ \ {\isacharparenleft}a\ {\isacharequal}\ a{\isacharprime}\ {\isasymand}\ b\ {\isacharequal}\ b{\isacharprime}{\isacharparenright}{\isachardoublequote}\isanewline |
232 \ \ \ \ {\isacharparenleft}a\ {\isacharequal}\ a{\isacharprime}\ {\isasymand}\ b\ {\isacharequal}\ b{\isacharprime}{\isacharparenright}{\isachardoublequote}\isanewline |
233 \ \ \isamarkupfalse% |
233 \ \ \isamarkupfalse% |
234 \isamarkupfalse% |
234 \isacommand{by}\ simp\isamarkupfalse% |
235 % |
235 % |
236 \begin{isamarkuptext}% |
236 \begin{isamarkuptext}% |
237 The following equality is similar, but generic, in that \isa{r} |
237 The following equality is similar, but generic, in that \isa{r} |
238 can be any instance of \isa{{\isacharprime}a\ point{\isacharunderscore}scheme}:% |
238 can be any instance of \isa{{\isacharprime}a\ point{\isacharunderscore}scheme}:% |
239 \end{isamarkuptext}% |
239 \end{isamarkuptext}% |
240 \isamarkuptrue% |
240 \isamarkuptrue% |
241 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isacharcomma}\ Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isachardoublequote}\isanewline |
241 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharcomma}\ Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isacharcomma}\ Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isachardoublequote}\isanewline |
242 \ \ \isamarkupfalse% |
242 \ \ \isamarkupfalse% |
243 \isamarkupfalse% |
243 \isacommand{by}\ simp\isamarkupfalse% |
244 % |
244 % |
245 \begin{isamarkuptext}% |
245 \begin{isamarkuptext}% |
246 We see above the syntax for iterated updates. We could equivalently |
246 We see above the syntax for iterated updates. We could equivalently |
247 have written the left-hand side as \isa{r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}}. |
247 have written the left-hand side as \isa{r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isasymlparr}Ycoord\ {\isacharcolon}{\isacharequal}\ b{\isasymrparr}}. |
248 |
248 |
251 by the values of its fields.% |
251 by the values of its fields.% |
252 \end{isamarkuptext}% |
252 \end{isamarkuptext}% |
253 \isamarkuptrue% |
253 \isamarkuptrue% |
254 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isasymrparr}{\isachardoublequote}\isanewline |
254 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isasymrparr}{\isachardoublequote}\isanewline |
255 \ \ \isamarkupfalse% |
255 \ \ \isamarkupfalse% |
256 \isamarkupfalse% |
256 \isacommand{by}\ simp\isamarkupfalse% |
257 % |
257 % |
258 \begin{isamarkuptext}% |
258 \begin{isamarkuptext}% |
259 The generic version of this equality includes the pseudo-field |
259 The generic version of this equality includes the pseudo-field |
260 \isa{more}:% |
260 \isa{more}:% |
261 \end{isamarkuptext}% |
261 \end{isamarkuptext}% |
262 \isamarkuptrue% |
262 \isamarkuptrue% |
263 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ point{\isachardot}more\ r{\isasymrparr}{\isachardoublequote}\isanewline |
263 \isacommand{lemma}\ {\isachardoublequote}r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord\ r{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord\ r{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ point{\isachardot}more\ r{\isasymrparr}{\isachardoublequote}\isanewline |
264 \ \ \isamarkupfalse% |
264 \ \ \isamarkupfalse% |
265 \isamarkupfalse% |
265 \isacommand{by}\ simp\isamarkupfalse% |
266 % |
266 % |
267 \begin{isamarkuptext}% |
267 \begin{isamarkuptext}% |
268 \medskip The simplifier can prove many record equalities |
268 \medskip The simplifier can prove many record equalities |
269 automatically, but general equality reasoning can be tricky. |
269 automatically, but general equality reasoning can be tricky. |
270 Consider proving this obvious fact:% |
270 Consider proving this obvious fact:% |
271 \end{isamarkuptext}% |
271 \end{isamarkuptext}% |
272 \isamarkuptrue% |
272 \isamarkuptrue% |
273 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline |
273 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline |
274 \ \ \isamarkupfalse% |
274 \ \ \isamarkupfalse% |
275 \isamarkupfalse% |
275 \isacommand{apply}\ simp{\isacharquery}\isanewline |
276 \isamarkupfalse% |
276 \ \ \isamarkupfalse% |
|
277 \isacommand{oops}\isamarkupfalse% |
277 % |
278 % |
278 \begin{isamarkuptext}% |
279 \begin{isamarkuptext}% |
279 Here the simplifier can do nothing, since general record equality is |
280 Here the simplifier can do nothing, since general record equality is |
280 not eliminated automatically. One way to proceed is by an explicit |
281 not eliminated automatically. One way to proceed is by an explicit |
281 forward step that applies the selector \isa{Xcoord} to both sides |
282 forward step that applies the selector \isa{Xcoord} to both sides |
282 of the assumed record equality:% |
283 of the assumed record equality:% |
283 \end{isamarkuptext}% |
284 \end{isamarkuptext}% |
284 \isamarkuptrue% |
285 \isamarkuptrue% |
285 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline |
286 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isanewline |
286 \ \ \isamarkupfalse% |
287 \ \ \isamarkupfalse% |
287 \isamarkupfalse% |
288 \isacommand{apply}\ {\isacharparenleft}drule{\isacharunderscore}tac\ f\ {\isacharequal}\ Xcoord\ \isakeyword{in}\ arg{\isacharunderscore}cong{\isacharparenright}\isamarkupfalse% |
288 \isamarkuptrue% |
289 % |
289 \isamarkupfalse% |
290 \begin{isamarkuptxt}% |
290 \isamarkupfalse% |
291 \begin{isabelle}% |
|
292 \ {\isadigit{1}}{\isachardot}\ Xcoord\ {\isacharparenleft}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}{\isacharparenright}\ {\isacharequal}\ Xcoord\ {\isacharparenleft}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}{\isacharparenright}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}% |
|
293 \end{isabelle} |
|
294 Now, \isa{simp} will reduce the assumption to the desired |
|
295 conclusion.% |
|
296 \end{isamarkuptxt}% |
|
297 \ \ \isamarkuptrue% |
|
298 \isacommand{apply}\ simp\isanewline |
|
299 \ \ \isamarkupfalse% |
|
300 \isacommand{done}\isamarkupfalse% |
291 % |
301 % |
292 \begin{isamarkuptext}% |
302 \begin{isamarkuptext}% |
293 The \isa{cases} method is preferable to such a forward proof. We |
303 The \isa{cases} method is preferable to such a forward proof. We |
294 state the desired lemma again:% |
304 state the desired lemma again:% |
295 \end{isamarkuptext}% |
305 \end{isamarkuptext}% |
296 \isamarkuptrue% |
306 \isamarkuptrue% |
297 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isamarkupfalse% |
307 \isacommand{lemma}\ {\isachardoublequote}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}\ {\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}{\isachardoublequote}\isamarkupfalse% |
298 \isamarkuptrue% |
308 % |
299 \isamarkupfalse% |
309 \begin{isamarkuptxt}% |
300 \isamarkuptrue% |
310 The \methdx{cases} method adds an equality to replace the |
301 \isamarkupfalse% |
311 named record term by an explicit record expression, listing all |
302 \isamarkupfalse% |
312 fields. It even includes the pseudo-field \isa{more}, since the |
|
313 record equality stated here is generic for all extensions.% |
|
314 \end{isamarkuptxt}% |
|
315 \ \ \isamarkuptrue% |
|
316 \isacommand{apply}\ {\isacharparenleft}cases\ r{\isacharparenright}\isamarkupfalse% |
|
317 % |
|
318 \begin{isamarkuptxt}% |
|
319 \begin{isabelle}% |
|
320 \ {\isadigit{1}}{\isachardot}\ {\isasymAnd}Xcoord\ Ycoord\ more{\isachardot}\isanewline |
|
321 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }{\isasymlbrakk}r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isasymrparr}\ {\isacharequal}\ r{\isasymlparr}Xcoord\ {\isacharcolon}{\isacharequal}\ a{\isacharprime}{\isasymrparr}{\isacharsemicolon}\isanewline |
|
322 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ \ }r\ {\isacharequal}\ {\isasymlparr}Xcoord\ {\isacharequal}\ Xcoord{\isacharcomma}\ Ycoord\ {\isacharequal}\ Ycoord{\isacharcomma}\ {\isasymdots}\ {\isacharequal}\ more{\isasymrparr}{\isasymrbrakk}\isanewline |
|
323 \isaindent{\ {\isadigit{1}}{\isachardot}\ \ \ \ }{\isasymLongrightarrow}\ a\ {\isacharequal}\ a{\isacharprime}% |
|
324 \end{isabelle} Again, \isa{simp} finishes the proof. Because \isa{r} is now represented as |
|
325 an explicit record construction, the updates can be applied and the |
|
326 record equality can be replaced by equality of the corresponding |
|
327 fields (due to injectivity).% |
|
328 \end{isamarkuptxt}% |
|
329 \ \ \isamarkuptrue% |
|
330 \isacommand{apply}\ simp\isanewline |
|
331 \ \ \isamarkupfalse% |
|
332 \isacommand{done}\isamarkupfalse% |
303 % |
333 % |
304 \begin{isamarkuptext}% |
334 \begin{isamarkuptext}% |
305 The generic cases method does not admit references to locally bound |
335 The generic cases method does not admit references to locally bound |
306 parameters of a goal. In longer proof scripts one might have to |
336 parameters of a goal. In longer proof scripts one might have to |
307 fall back on the primitive \isa{rule{\isacharunderscore}tac} used together with the |
337 fall back on the primitive \isa{rule{\isacharunderscore}tac} used together with the |
384 comparison on type \isa{point}.% |
414 comparison on type \isa{point}.% |
385 \end{isamarkuptext}% |
415 \end{isamarkuptext}% |
386 \isamarkuptrue% |
416 \isamarkuptrue% |
387 \isacommand{lemma}\ {\isachardoublequote}cpt{\isadigit{1}}\ {\isacharequal}\ cpt{\isadigit{2}}{\isachardoublequote}\isanewline |
417 \isacommand{lemma}\ {\isachardoublequote}cpt{\isadigit{1}}\ {\isacharequal}\ cpt{\isadigit{2}}{\isachardoublequote}\isanewline |
388 \ \ \isamarkupfalse% |
418 \ \ \isamarkupfalse% |
389 \isamarkupfalse% |
419 \isacommand{apply}\ {\isacharparenleft}simp\ add{\isacharcolon}\ cpt{\isadigit{1}}{\isacharunderscore}def\ cpt{\isadigit{2}}{\isacharunderscore}def\ point{\isachardot}defs\ cpoint{\isachardot}defs{\isacharparenright}\isamarkupfalse% |
390 \isamarkuptrue% |
420 % |
391 \isamarkupfalse% |
421 \begin{isamarkuptxt}% |
392 \isamarkupfalse% |
422 \begin{isabelle}% |
|
423 \ {\isadigit{1}}{\isachardot}\ Xcoord\ pt{\isadigit{1}}\ {\isacharequal}\ {\isadigit{9}}{\isadigit{9}}{\isadigit{9}}\ {\isasymand}\ Ycoord\ pt{\isadigit{1}}\ {\isacharequal}\ {\isadigit{2}}{\isadigit{3}}% |
|
424 \end{isabelle}% |
|
425 \end{isamarkuptxt}% |
|
426 \ \ \isamarkuptrue% |
|
427 \isacommand{apply}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def{\isacharparenright}\isanewline |
|
428 \ \ \isamarkupfalse% |
|
429 \isacommand{done}\isamarkupfalse% |
393 % |
430 % |
394 \begin{isamarkuptext}% |
431 \begin{isamarkuptext}% |
395 In the example below, a coloured point is truncated to leave a |
432 In the example below, a coloured point is truncated to leave a |
396 point. We use the \isa{truncate} function of the target record.% |
433 point. We use the \isa{truncate} function of the target record.% |
397 \end{isamarkuptext}% |
434 \end{isamarkuptext}% |
398 \isamarkuptrue% |
435 \isamarkuptrue% |
399 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}truncate\ cpt{\isadigit{2}}\ {\isacharequal}\ pt{\isadigit{1}}{\isachardoublequote}\isanewline |
436 \isacommand{lemma}\ {\isachardoublequote}point{\isachardot}truncate\ cpt{\isadigit{2}}\ {\isacharequal}\ pt{\isadigit{1}}{\isachardoublequote}\isanewline |
400 \ \ \isamarkupfalse% |
437 \ \ \isamarkupfalse% |
401 \isamarkupfalse% |
438 \isacommand{by}\ {\isacharparenleft}simp\ add{\isacharcolon}\ pt{\isadigit{1}}{\isacharunderscore}def\ cpt{\isadigit{2}}{\isacharunderscore}def\ point{\isachardot}defs{\isacharparenright}\isamarkupfalse% |
402 % |
439 % |
403 \begin{isamarkuptext}% |
440 \begin{isamarkuptext}% |
404 \begin{exercise} |
441 \begin{exercise} |
405 Extend record \isa{cpoint} to have a further field, \isa{intensity}, of type~\isa{nat}. Experiment with generic operations |
442 Extend record \isa{cpoint} to have a further field, \isa{intensity}, of type~\isa{nat}. Experiment with generic operations |
406 (using polymorphic selectors and updates) and explicit coercions |
443 (using polymorphic selectors and updates) and explicit coercions |