11 % |
11 % |
12 \isatagtheory |
12 \isatagtheory |
13 \isacommand{theory}\isamarkupfalse% |
13 \isacommand{theory}\isamarkupfalse% |
14 \ Classes\isanewline |
14 \ Classes\isanewline |
15 \isakeyword{imports}\ Main\isanewline |
15 \isakeyword{imports}\ Main\isanewline |
16 \isakeyword{begin}\isanewline |
16 \isakeyword{begin}% |
17 % |
|
18 \endisatagtheory |
17 \endisatagtheory |
19 {\isafoldtheory}% |
18 {\isafoldtheory}% |
20 % |
19 % |
21 \isadelimtheory |
20 \isadelimtheory |
|
21 \isanewline |
22 % |
22 % |
23 \endisadelimtheory |
23 \endisadelimtheory |
24 % |
24 % |
25 \isadelimML |
25 \isadelimML |
|
26 \isanewline |
26 % |
27 % |
27 \endisadelimML |
28 \endisadelimML |
28 % |
29 % |
29 \isatagML |
30 \isatagML |
|
31 \isacommand{ML}\isamarkupfalse% |
|
32 \ {\isacharverbatimopen}\isanewline |
|
33 CodegenSerializer{\isachardot}code{\isacharunderscore}width\ {\isacharcolon}{\isacharequal}\ {\isadigit{7}}{\isadigit{4}}{\isacharsemicolon}\isanewline |
|
34 {\isacharverbatimclose}\isanewline |
30 % |
35 % |
31 \endisatagML |
36 \endisatagML |
32 {\isafoldML}% |
37 {\isafoldML}% |
33 % |
38 % |
34 \isadelimML |
39 \isadelimML |
35 % |
40 % |
36 \endisadelimML |
41 \endisadelimML |
37 % |
42 % |
|
43 \isadelimML |
|
44 % |
|
45 \endisadelimML |
|
46 % |
|
47 \isatagML |
|
48 % |
|
49 \endisatagML |
|
50 {\isafoldML}% |
|
51 % |
|
52 \isadelimML |
|
53 % |
|
54 \endisadelimML |
|
55 % |
38 \isamarkupchapter{Haskell-style classes with Isabelle/Isar% |
56 \isamarkupchapter{Haskell-style classes with Isabelle/Isar% |
39 } |
57 } |
40 \isamarkuptrue% |
58 \isamarkuptrue% |
41 % |
59 % |
42 \isamarkupsection{Introduction% |
60 \isamarkupsection{Introduction% |
43 } |
61 } |
44 \isamarkuptrue% |
62 \isamarkuptrue% |
45 % |
63 % |
46 \begin{isamarkuptext}% |
64 \begin{isamarkuptext}% |
47 The well-known concept of type classes |
65 Type classes were introduces by Wadler and Blott \cite{wadler89how} |
48 \cite{wadler89how,peterson93implementing,hall96type,Nipkow-Prehofer:1993,Nipkow:1993,Wenzel:1997} |
66 into the Haskell language, to allow for a reasonable implementation |
49 offers a useful structuring mechanism for programs and proofs, which |
67 of overloading\footnote{throughout this tutorial, we are referring |
50 is more light-weight than a fully featured module mechanism. Type |
68 to classical Haskell 1.0 type classes, not considering |
51 classes are able to qualify types by associating operations and |
69 later additions in expressiveness}. |
52 logical properties. For example, class \isa{eq} could provide |
70 As a canonical example, a polymorphic equality function |
53 an equivalence relation \isa{{\isacharequal}} on type \isa{{\isasymalpha}}, and class |
71 \isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} which is overloaded on different |
54 \isa{ord} could extend \isa{eq} by providing a strict order |
72 types for \isa{{\isasymalpha}}, which is achieves by splitting introduction |
55 \isa{{\isacharless}} etc. |
73 of the \isa{eq} function from its overloaded definitions by means |
56 |
74 of \isa{class} and \isa{instance} declarations: |
57 Isabelle/Isar offers Haskell-style type classes, combining operational |
75 |
58 and logical specifications.% |
76 \medskip\noindent\hspace*{2ex}\isa{class\ eq\ where}\footnote{syntax here is a kind of isabellized Haskell} \\ |
59 \end{isamarkuptext}% |
77 \hspace*{4ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} |
60 \isamarkuptrue% |
78 |
61 % |
79 \medskip\noindent\hspace*{2ex}\isa{instance\ nat\ {\isasymColon}\ eq\ where} \\ |
62 \isamarkupsection{A simple algebra example \label{sec:example}% |
80 \hspace*{4ex}\isa{eq\ {\isadigit{0}}\ {\isadigit{0}}\ {\isacharequal}\ True} \\ |
63 } |
81 \hspace*{4ex}\isa{eq\ {\isadigit{0}}\ {\isacharunderscore}\ {\isacharequal}\ False} \\ |
64 \isamarkuptrue% |
82 \hspace*{4ex}\isa{eq\ {\isacharunderscore}\ {\isadigit{0}}\ {\isacharequal}\ False} \\ |
65 % |
83 \hspace*{4ex}\isa{eq\ {\isacharparenleft}Suc\ n{\isacharparenright}\ {\isacharparenleft}Suc\ m{\isacharparenright}\ {\isacharequal}\ eq\ n\ m} |
66 \begin{isamarkuptext}% |
84 |
67 We demonstrate common elements of structured specifications and |
85 \medskip\noindent\hspace*{2ex}\isa{instance\ {\isacharparenleft}{\isasymalpha}{\isasymColon}eq{\isacharcomma}\ {\isasymbeta}{\isasymColon}eq{\isacharparenright}\ pair\ {\isasymColon}\ eq\ where} \\ |
68 abstract reasoning with type classes by the algebraic hierarchy of |
86 \hspace*{4ex}\isa{eq\ {\isacharparenleft}x{\isadigit{1}}{\isacharcomma}\ y{\isadigit{1}}{\isacharparenright}\ {\isacharparenleft}x{\isadigit{2}}{\isacharcomma}\ y{\isadigit{2}}{\isacharparenright}\ {\isacharequal}\ eq\ x{\isadigit{1}}\ x{\isadigit{2}}\ {\isacharampersand}{\isacharampersand}\ eq\ y{\isadigit{1}}\ y{\isadigit{2}}} |
|
87 |
|
88 \medskip\noindent\hspace*{2ex}\isa{class\ ord\ extends\ eq\ where} \\ |
|
89 \hspace*{4ex}\isa{less{\isacharunderscore}eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\ |
|
90 \hspace*{4ex}\isa{less\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} |
|
91 |
|
92 \medskip Type variables are annotated with (finitly many) classes; |
|
93 these annotations are assertions that a particular polymorphic type |
|
94 provides definitions for overloaded functions. |
|
95 |
|
96 Indeed, type classes not only allow for simple overloading |
|
97 but form a generic calculus, an instance of order-sorted |
|
98 algebra \cite{Nipkow-Prehofer:1993,Nipkow:1993,Wenzel:1997}. |
|
99 |
|
100 From a software enigineering point of view, type classes |
|
101 correspond to interfaces in object-oriented languages like Java; |
|
102 so, it is naturally desirable that type classes do not only |
|
103 provide functions (class operations) but also state specifications |
|
104 implementations must obey. For example, the \isa{class\ eq} |
|
105 above could be given the following specification: |
|
106 |
|
107 \medskip\noindent\hspace*{2ex}\isa{class\ eq\ where} \\ |
|
108 \hspace*{4ex}\isa{eq\ {\isasymColon}\ {\isasymalpha}\ {\isasymRightarrow}\ {\isasymalpha}\ {\isasymRightarrow}\ bool} \\ |
|
109 \hspace*{2ex}\isa{satisfying} \\ |
|
110 \hspace*{4ex}\isa{refl{\isacharcolon}\ eq\ x\ x} \\ |
|
111 \hspace*{4ex}\isa{sym{\isacharcolon}\ eq\ x\ y\ {\isasymlongleftrightarrow}\ eq\ x\ y} \\ |
|
112 \hspace*{4ex}\isa{trans{\isacharcolon}\ eq\ x\ y\ {\isasymand}\ eq\ y\ z\ {\isasymlongrightarrow}\ eq\ x\ z} |
|
113 |
|
114 \medskip From a theoretic point of view, type classes are leightweight |
|
115 modules; indeed, Haskell type classes may be emulated by |
|
116 SML functors \cite{classes_modules}. |
|
117 Isabelle/Isar offers a discipline of type classes which brings |
|
118 all those aspects together: |
|
119 |
|
120 \begin{enumerate} |
|
121 \item specifying abstract operations togehter with |
|
122 corresponding specifications, |
|
123 \item instantating those abstract operations by a particular |
|
124 type |
|
125 \item in connection with a ``less ad-hoc'' approach to overloading, |
|
126 \item with a direct link to the Isabelle module system (aka locales). |
|
127 \end{enumerate} |
|
128 |
|
129 Isar type classes also directly support code generation |
|
130 in as Haskell like fashion. |
|
131 |
|
132 This tutorial demonstrates common elements of structured specifications |
|
133 and abstract reasoning with type classes by the algebraic hierarchy of |
69 semigroups, monoids and groups. Our background theory is that of |
134 semigroups, monoids and groups. Our background theory is that of |
70 Isabelle/HOL \cite{Nipkow-et-al:2002:tutorial}, which uses fairly |
135 Isabelle/HOL \cite{Nipkow-et-al:2002:tutorial}, for which some |
71 standard notation from mathematics and functional programming. We |
136 familiarity is assumed. |
72 also refer to basic vernacular commands for definitions and |
137 |
73 statements, e.g.\ \isa{{\isasymDEFINITION}} and \isa{{\isasymLEMMA}}; |
138 Here we merely present the look-and-feel for end users. |
74 proofs will be recorded using structured elements of Isabelle/Isar |
|
75 \cite{Wenzel-PhD,Nipkow:2002}, notably \isa{{\isasymPROOF}}/\isa{{\isasymQED}} and \isa{{\isasymFIX}}/\isa{{\isasymASSUME}}/\isa{{\isasymSHOW}}. |
|
76 |
|
77 Our main concern are the new \isa{{\isasymCLASS}} |
|
78 and \isa{{\isasymINSTANCE}} elements used below. |
|
79 Here we merely present the |
|
80 look-and-feel for end users, which is quite similar to Haskell's |
|
81 \texttt{class} and \texttt{instance} \cite{hall96type}, but |
|
82 augmented by logical specifications and proofs; |
|
83 Internally, those are mapped to more primitive Isabelle concepts. |
139 Internally, those are mapped to more primitive Isabelle concepts. |
84 See \cite{haftmann_wenzel2006classes} for more detail.% |
140 See \cite{haftmann_wenzel2006classes} for more detail.% |
85 \end{isamarkuptext}% |
141 \end{isamarkuptext}% |
|
142 \isamarkuptrue% |
|
143 % |
|
144 \isamarkupsection{A simple algebra example \label{sec:example}% |
|
145 } |
86 \isamarkuptrue% |
146 \isamarkuptrue% |
87 % |
147 % |
88 \isamarkupsubsection{Class definition% |
148 \isamarkupsubsection{Class definition% |
89 } |
149 } |
90 \isamarkuptrue% |
150 \isamarkuptrue% |
117 \isa{mult} and a proof for the specification of \isa{assoc}.% |
177 \isa{mult} and a proof for the specification of \isa{assoc}.% |
118 \end{isamarkuptext}% |
178 \end{isamarkuptext}% |
119 \isamarkuptrue% |
179 \isamarkuptrue% |
120 \ \ \ \ \isacommand{instance}\isamarkupfalse% |
180 \ \ \ \ \isacommand{instance}\isamarkupfalse% |
121 \ int\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline |
181 \ int\ {\isacharcolon}{\isacharcolon}\ semigroup\isanewline |
122 \ \ \ \ \ \ \ \ mult{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymAnd}i\ j\ {\isacharcolon}{\isacharcolon}\ int{\isachardot}\ i\ {\isasymotimes}\ j\ {\isasymequiv}\ i\ {\isacharplus}\ j{\isachardoublequoteclose}\isanewline |
182 \ \ \ \ \ \ mult{\isacharunderscore}int{\isacharunderscore}def{\isacharcolon}\ {\isachardoublequoteopen}{\isasymAnd}i\ j\ {\isacharcolon}{\isacharcolon}\ int{\isachardot}\ i\ {\isasymotimes}\ j\ {\isasymequiv}\ i\ {\isacharplus}\ j{\isachardoublequoteclose}\isanewline |
123 % |
183 % |
124 \isadelimproof |
184 \isadelimproof |
125 \ \ \ \ % |
185 \ \ \ \ % |
126 \endisadelimproof |
186 \endisadelimproof |
127 % |
187 % |
128 \isatagproof |
188 \isatagproof |
129 \isacommand{proof}\isamarkupfalse% |
189 \isacommand{proof}\isamarkupfalse% |
130 \isanewline |
190 \isanewline |
131 \ \ \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
191 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
132 \ i\ j\ k\ {\isacharcolon}{\isacharcolon}\ int\ \isacommand{have}\isamarkupfalse% |
192 \ i\ j\ k\ {\isacharcolon}{\isacharcolon}\ int\ \isacommand{have}\isamarkupfalse% |
133 \ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isacharplus}\ j{\isacharparenright}\ {\isacharplus}\ k\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j\ {\isacharplus}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse% |
193 \ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isacharplus}\ j{\isacharparenright}\ {\isacharplus}\ k\ {\isacharequal}\ i\ {\isacharplus}\ {\isacharparenleft}j\ {\isacharplus}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse% |
134 \ simp\isanewline |
194 \ simp\isanewline |
135 \ \ \ \ \ \ \ \ \isacommand{then}\isamarkupfalse% |
195 \ \ \ \ \ \ \isacommand{then}\isamarkupfalse% |
136 \ \isacommand{show}\isamarkupfalse% |
196 \ \isacommand{show}\isamarkupfalse% |
137 \ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymotimes}\ j{\isacharparenright}\ {\isasymotimes}\ k\ {\isacharequal}\ i\ {\isasymotimes}\ {\isacharparenleft}j\ {\isasymotimes}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
197 \ {\isachardoublequoteopen}{\isacharparenleft}i\ {\isasymotimes}\ j{\isacharparenright}\ {\isasymotimes}\ k\ {\isacharequal}\ i\ {\isasymotimes}\ {\isacharparenleft}j\ {\isasymotimes}\ k{\isacharparenright}{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
138 \ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse% |
198 \ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{{\isachardot}}\isamarkupfalse% |
139 \isanewline |
199 \isanewline |
140 \ \ \ \ \isacommand{qed}\isamarkupfalse% |
200 \ \ \ \ \isacommand{qed}\isamarkupfalse% |
359 \ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline |
429 \ n\ {\isacharcolon}{\isacharcolon}\ nat\isanewline |
360 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
430 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
361 \ {\isachardoublequoteopen}n\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ n{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
431 \ {\isachardoublequoteopen}n\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ n{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
362 \ neutral{\isacharunderscore}nat{\isacharunderscore}def\ mult{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse% |
432 \ neutral{\isacharunderscore}nat{\isacharunderscore}def\ mult{\isacharunderscore}nat{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse% |
363 \ simp\isanewline |
433 \ simp\isanewline |
364 \ \ \ \ \isacommand{qed}\isamarkupfalse% |
434 \ \ \ \ \isacommand{next}\isamarkupfalse% |
365 % |
|
366 \endisatagproof |
|
367 {\isafoldproof}% |
|
368 % |
|
369 \isadelimproof |
|
370 \isanewline |
|
371 % |
|
372 \endisadelimproof |
|
373 \isanewline |
|
374 \ \ \ \ \isacommand{instance}\isamarkupfalse% |
|
375 \ int\ {\isacharcolon}{\isacharcolon}\ monoid\isanewline |
|
376 % |
|
377 \isadelimproof |
|
378 \ \ \ \ % |
|
379 \endisadelimproof |
|
380 % |
|
381 \isatagproof |
|
382 \isacommand{proof}\isamarkupfalse% |
|
383 \isanewline |
435 \isanewline |
384 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
436 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
385 \ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline |
437 \ k\ {\isacharcolon}{\isacharcolon}\ int\isanewline |
386 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
438 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
387 \ {\isachardoublequoteopen}k\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ k{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
439 \ {\isachardoublequoteopen}k\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ k{\isachardoublequoteclose}\ \isacommand{unfolding}\isamarkupfalse% |
388 \ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse% |
440 \ neutral{\isacharunderscore}int{\isacharunderscore}def\ mult{\isacharunderscore}int{\isacharunderscore}def\ \isacommand{by}\isamarkupfalse% |
389 \ simp\isanewline |
441 \ simp\isanewline |
390 \ \ \ \ \isacommand{qed}\isamarkupfalse% |
442 \ \ \ \ \isacommand{next}\isamarkupfalse% |
391 % |
|
392 \endisatagproof |
|
393 {\isafoldproof}% |
|
394 % |
|
395 \isadelimproof |
|
396 \isanewline |
|
397 % |
|
398 \endisadelimproof |
|
399 \isanewline |
|
400 \ \ \ \ \isacommand{instance}\isamarkupfalse% |
|
401 \ list\ {\isacharcolon}{\isacharcolon}\ {\isacharparenleft}type{\isacharparenright}\ monoid\isanewline |
|
402 % |
|
403 \isadelimproof |
|
404 \ \ \ \ % |
|
405 \endisadelimproof |
|
406 % |
|
407 \isatagproof |
|
408 \isacommand{proof}\isamarkupfalse% |
|
409 \isanewline |
443 \isanewline |
410 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
444 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
411 \ xs\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ list{\isachardoublequoteclose}\isanewline |
445 \ xs\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}{\isasymalpha}\ list{\isachardoublequoteclose}\isanewline |
412 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
446 \ \ \ \ \ \ \isacommand{show}\isamarkupfalse% |
413 \ {\isachardoublequoteopen}xs\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline |
447 \ {\isachardoublequoteopen}xs\ {\isasymotimes}\ {\isasymone}\ {\isacharequal}\ xs{\isachardoublequoteclose}\isanewline |
533 use. This local theorem is also lifted to the global one \isa{group{\isachardot}left{\isacharunderscore}cancel{\isacharcolon}} \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z{\isacharcolon}{\isacharcolon}{\isasymalpha}{\isacharcolon}{\isacharcolon}group{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}. Since type \isa{int} has been made an instance of |
584 use. This local theorem is also lifted to the global one \isa{group{\isachardot}left{\isacharunderscore}cancel{\isacharcolon}} \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z{\isacharcolon}{\isacharcolon}{\isasymalpha}{\isacharcolon}{\isacharcolon}group{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}. Since type \isa{int} has been made an instance of |
534 \isa{group} before, we may refer to that fact as well: \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z{\isacharcolon}{\isacharcolon}int{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}.% |
585 \isa{group} before, we may refer to that fact as well: \isa{{\isachardoublequote}{\isasymAnd}x\ y\ z{\isacharcolon}{\isacharcolon}int{\isachardot}\ x\ {\isasymotimes}\ y\ {\isacharequal}\ x\ {\isasymotimes}\ z\ {\isasymlongleftrightarrow}\ y\ {\isacharequal}\ z{\isachardoublequote}}.% |
535 \end{isamarkuptext}% |
586 \end{isamarkuptext}% |
536 \isamarkuptrue% |
587 \isamarkuptrue% |
537 % |
588 % |
538 \isamarkupsubsection{Additional subclass relations% |
589 \isamarkupsection{Further issues% |
539 } |
590 } |
540 \isamarkuptrue% |
591 \isamarkuptrue% |
541 % |
592 % |
542 \begin{isamarkuptext}% |
593 \isamarkupsubsection{Code generation% |
543 Any \isa{group} is also a \isa{monoid}; this |
594 } |
544 can be made explicit by claiming an additional subclass relation, |
595 \isamarkuptrue% |
545 together with a proof of the logical difference:% |
596 % |
546 \end{isamarkuptext}% |
597 \begin{isamarkuptext}% |
547 \isamarkuptrue% |
598 Turning back to the first motivation for type classes, |
548 \ \ \ \ \isacommand{instance}\isamarkupfalse% |
599 namely overloading, it is obvious that overloading |
549 \ group\ {\isacharless}\ monoid\isanewline |
600 stemming from \isa{{\isasymCLASS}} and \isa{{\isasymINSTANCE}} |
550 % |
601 statements naturally maps to Haskell type classes. |
551 \isadelimproof |
602 The code generator framework \cite{isabelle-codegen} |
552 \ \ \ \ % |
603 takes this into account. Concerning target languages |
553 \endisadelimproof |
604 lacking type classes (e.g.~SML), type classes |
554 % |
605 are implemented by explicit dictionary construction. |
555 \isatagproof |
606 As example, the natural power function on groups:% |
556 \isacommand{proof}\isamarkupfalse% |
607 \end{isamarkuptext}% |
557 \ {\isacharminus}\isanewline |
608 \isamarkuptrue% |
558 \ \ \ \ \ \ \isacommand{fix}\isamarkupfalse% |
609 \ \ \ \ \isacommand{fun}\isamarkupfalse% |
559 \ x\isanewline |
|
560 \ \ \ \ \ \ \isacommand{from}\isamarkupfalse% |
|
561 \ invl\ \isacommand{have}\isamarkupfalse% |
|
562 \ {\isachardoublequoteopen}x\isactrlloc {\isasymdiv}\ \isactrlloc {\isasymotimes}\ x\ {\isacharequal}\ \isactrlloc {\isasymone}{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse% |
|
563 \ simp\isanewline |
|
564 \ \ \ \ \ \ \isacommand{with}\isamarkupfalse% |
|
565 \ assoc\ {\isacharbrackleft}symmetric{\isacharbrackright}\ neutl\ invl\ \isacommand{have}\isamarkupfalse% |
|
566 \ {\isachardoublequoteopen}x\isactrlloc {\isasymdiv}\ \isactrlloc {\isasymotimes}\ {\isacharparenleft}x\ \isactrlloc {\isasymotimes}\ \isactrlloc {\isasymone}{\isacharparenright}\ {\isacharequal}\ x\isactrlloc {\isasymdiv}\ \isactrlloc {\isasymotimes}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse% |
|
567 \ simp\isanewline |
|
568 \ \ \ \ \ \ \isacommand{with}\isamarkupfalse% |
|
569 \ left{\isacharunderscore}cancel\ \isacommand{show}\isamarkupfalse% |
|
570 \ {\isachardoublequoteopen}x\ \isactrlloc {\isasymotimes}\ \isactrlloc {\isasymone}\ {\isacharequal}\ x{\isachardoublequoteclose}\ \isacommand{by}\isamarkupfalse% |
|
571 \ simp\isanewline |
|
572 \ \ \ \ \isacommand{qed}\isamarkupfalse% |
|
573 % |
|
574 \endisatagproof |
|
575 {\isafoldproof}% |
|
576 % |
|
577 \isadelimproof |
|
578 % |
|
579 \endisadelimproof |
|
580 % |
|
581 \isamarkupsection{Code generation% |
|
582 } |
|
583 \isamarkuptrue% |
|
584 % |
|
585 \begin{isamarkuptext}% |
|
586 Code generation takes account of type classes, |
|
587 resulting either in Haskell type classes or SML dictionaries. |
|
588 As example, we define the natural power function on groups:% |
|
589 \end{isamarkuptext}% |
|
590 \isamarkuptrue% |
|
591 \ \ \ \ \isacommand{function}\isamarkupfalse% |
|
592 \isanewline |
610 \isanewline |
593 \ \ \ \ \ \ pow{\isacharunderscore}nat\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}monoidl\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}monoidl{\isachardoublequoteclose}\ \isakeyword{where}\isanewline |
611 \ \ \ \ \ \ pow{\isacharunderscore}nat\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}nat\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}monoidl\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}monoidl{\isachardoublequoteclose}\ \isakeyword{where}\isanewline |
594 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline |
612 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isadigit{0}}\ x\ {\isacharequal}\ {\isasymone}{\isachardoublequoteclose}\isanewline |
595 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x{\isachardoublequoteclose}\isanewline |
613 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}nat\ {\isacharparenleft}Suc\ n{\isacharparenright}\ x\ {\isacharequal}\ x\ {\isasymotimes}\ pow{\isacharunderscore}nat\ n\ x{\isachardoublequoteclose}\isanewline |
596 % |
|
597 \isadelimproof |
|
598 \ \ \ \ \ \ % |
|
599 \endisadelimproof |
|
600 % |
|
601 \isatagproof |
|
602 \isacommand{by}\isamarkupfalse% |
|
603 \ pat{\isacharunderscore}completeness\ auto% |
|
604 \endisatagproof |
|
605 {\isafoldproof}% |
|
606 % |
|
607 \isadelimproof |
|
608 \isanewline |
|
609 % |
|
610 \endisadelimproof |
|
611 \ \ \ \ \isacommand{termination}\isamarkupfalse% |
|
612 \ pow{\isacharunderscore}nat% |
|
613 \isadelimproof |
|
614 \ % |
|
615 \endisadelimproof |
|
616 % |
|
617 \isatagproof |
|
618 \isacommand{by}\isamarkupfalse% |
|
619 \ {\isacharparenleft}auto{\isacharunderscore}term\ {\isachardoublequoteopen}measure\ fst{\isachardoublequoteclose}{\isacharparenright}% |
|
620 \endisatagproof |
|
621 {\isafoldproof}% |
|
622 % |
|
623 \isadelimproof |
|
624 % |
|
625 \endisadelimproof |
|
626 \isanewline |
|
627 \ \ \ \ \isacommand{declare}\isamarkupfalse% |
|
628 \ pow{\isacharunderscore}nat{\isachardot}simps\ {\isacharbrackleft}code\ func{\isacharbrackright}\isanewline |
|
629 \isanewline |
614 \isanewline |
630 \ \ \ \ \isacommand{definition}\isamarkupfalse% |
615 \ \ \ \ \isacommand{definition}\isamarkupfalse% |
631 \isanewline |
616 \isanewline |
632 \ \ \ \ \ \ pow{\isacharunderscore}int\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}int\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}group\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}group{\isachardoublequoteclose}\isanewline |
617 \ \ \ \ \ \ pow{\isacharunderscore}int\ {\isacharcolon}{\isacharcolon}\ {\isachardoublequoteopen}int\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}group\ {\isasymRightarrow}\ {\isacharprime}a{\isasymColon}group{\isachardoublequoteclose}\ \isakeyword{where}\isanewline |
633 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ k\ {\isachargreater}{\isacharequal}\ {\isadigit{0}}\isanewline |
618 \ \ \ \ \ \ {\isachardoublequoteopen}pow{\isacharunderscore}int\ k\ x\ {\isacharequal}\ {\isacharparenleft}if\ k\ {\isachargreater}{\isacharequal}\ {\isadigit{0}}\isanewline |
634 \ \ \ \ \ \ \ \ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\isanewline |
619 \ \ \ \ \ \ \ \ then\ pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ k{\isacharparenright}\ x\isanewline |
635 \ \ \ \ \ \ \ \ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}\isanewline |
620 \ \ \ \ \ \ \ \ else\ {\isacharparenleft}pow{\isacharunderscore}nat\ {\isacharparenleft}nat\ {\isacharparenleft}{\isacharminus}\ k{\isacharparenright}{\isacharparenright}\ x{\isacharparenright}{\isasymdiv}{\isacharparenright}{\isachardoublequoteclose}\isanewline |
636 \isanewline |
621 \isanewline |
637 \ \ \ \ \isacommand{definition}\isamarkupfalse% |
622 \ \ \ \ \isacommand{definition}\isamarkupfalse% |
638 \isanewline |
623 \isanewline |
639 \ \ \ \ \ \ example\ {\isacharcolon}{\isacharcolon}\ int\isanewline |
624 \ \ \ \ \ \ example\ {\isacharcolon}{\isacharcolon}\ int\ \isakeyword{where}\isanewline |
640 \ \ \ \ \ \ {\isachardoublequoteopen}example\ {\isacharequal}\ pow{\isacharunderscore}int\ {\isadigit{1}}{\isadigit{0}}\ {\isacharparenleft}{\isacharminus}{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}% |
625 \ \ \ \ \ \ {\isachardoublequoteopen}example\ {\isacharequal}\ pow{\isacharunderscore}int\ {\isadigit{1}}{\isadigit{0}}\ {\isacharparenleft}{\isacharminus}{\isadigit{2}}{\isacharparenright}{\isachardoublequoteclose}% |
641 \begin{isamarkuptext}% |
626 \begin{isamarkuptext}% |
642 \noindent Now we generate and compile code for SML:% |
627 \noindent This maps to Haskell as:% |
643 \end{isamarkuptext}% |
628 \end{isamarkuptext}% |
644 \isamarkuptrue% |
629 \isamarkuptrue% |
645 \ \ \ \ \isacommand{code{\isacharunderscore}gen}\isamarkupfalse% |
630 \isacommand{code{\isacharunderscore}gen}\isamarkupfalse% |
646 \ example\ {\isacharparenleft}SML\ {\isacharminus}{\isacharparenright}% |
631 \ example\ {\isacharparenleft}Haskell\ {\isachardoublequoteopen}code{\isacharunderscore}examples{\isacharslash}{\isachardoublequoteclose}{\isacharparenright}% |
647 \begin{isamarkuptext}% |
632 \begin{isamarkuptext}% |
648 \noindent The result is as expected:% |
633 \lsthaskell{Thy/code_examples/Classes.hs} |
649 \end{isamarkuptext}% |
634 |
650 \isamarkuptrue% |
635 \noindent (we have left out all other modules). |
651 % |
636 |
652 \isadelimML |
637 \noindent The whole code in SML with explicit dictionary passing:% |
653 \ \ \ \ % |
638 \end{isamarkuptext}% |
654 \endisadelimML |
639 \isamarkuptrue% |
655 % |
640 \isacommand{code{\isacharunderscore}gen}\isamarkupfalse% |
656 \isatagML |
641 \ example\ {\isacharparenleft}SML\ {\isachardoublequoteopen}code{\isacharunderscore}examples{\isacharslash}classes{\isachardot}ML{\isachardoublequoteclose}{\isacharparenright}% |
657 \isacommand{ML}\isamarkupfalse% |
642 \begin{isamarkuptext}% |
658 \ {\isacharverbatimopen}\isanewline |
643 \lstsml{Thy/code_examples/classes.ML}% |
659 \ \ \ \ \ \ if\ ROOT{\isachardot}Classes{\isachardot}example\ {\isacharequal}\ {\isachartilde}{\isadigit{2}}{\isadigit{0}}\ then\ {\isacharparenleft}{\isacharparenright}\ else\ error\ {\isachardoublequote}Wrong\ result{\isachardoublequote}\isanewline |
644 \end{isamarkuptext}% |
660 \ \ \ \ {\isacharverbatimclose}% |
645 \isamarkuptrue% |
661 \endisatagML |
|
662 {\isafoldML}% |
|
663 % |
|
664 \isadelimML |
|
665 % |
|
666 \endisadelimML |
|
667 \isanewline |
|
668 % |
646 % |
669 \isadelimtheory |
647 \isadelimtheory |
670 \isanewline |
|
671 % |
648 % |
672 \endisadelimtheory |
649 \endisadelimtheory |
673 % |
650 % |
674 \isatagtheory |
651 \isatagtheory |
675 \isacommand{end}\isamarkupfalse% |
652 \isacommand{end}\isamarkupfalse% |