63026
|
1 |
theory Typeclass_Hierarchy
|
|
2 |
imports Setup
|
|
3 |
begin
|
|
4 |
|
|
5 |
section \<open>Introduction\<close>
|
|
6 |
|
|
7 |
text \<open>
|
|
8 |
The {Isabelle/HOL} type-class hierarchy entered the stage
|
|
9 |
in a quite ancient era -- first related \emph{NEWS} entries date
|
|
10 |
back to release {Isabelle99-1}. Since then, there have been
|
|
11 |
ongoing modifications and additions, leading to ({Isabelle2016})
|
|
12 |
more than 180 type-classes. This sheer complexity makes access
|
|
13 |
and understanding of that type-class hierarchy difficult and
|
|
14 |
involved, let alone maintenance.
|
|
15 |
|
|
16 |
The purpose of this primer is to shed some light on this,
|
|
17 |
not only on the mere ingredients, but also on the design
|
|
18 |
principles which have evolved and proven useful over time.
|
|
19 |
\<close>
|
|
20 |
|
|
21 |
section \<open>Foundations\<close>
|
|
22 |
|
|
23 |
subsection \<open>Locales and type classes\<close>
|
|
24 |
|
|
25 |
text \<open>
|
|
26 |
Some familiarity with the Isabelle module system is assumed:
|
|
27 |
defining locales and type-classes, interpreting locales and
|
|
28 |
instantiating type-classes, adding relationships between
|
|
29 |
locales (@{command sublocale}) and type-classes
|
|
30 |
(@{command subclass}). Handy introductions are the
|
|
31 |
respective tutorials \cite{isabelle-locale}
|
|
32 |
\cite{isabelle-classes}.
|
|
33 |
\<close>
|
|
34 |
|
|
35 |
subsection \<open>Strengths and restrictions of type classes\<close>
|
|
36 |
|
|
37 |
text \<open>
|
|
38 |
The primary motivation for using type classes in {Isabelle/HOL}
|
|
39 |
always have been numerical types, which form an inclusion chain:
|
|
40 |
|
|
41 |
\begin{center}
|
|
42 |
@{typ nat} @{text \<sqsubset>} @{typ int} @{text \<sqsubset>} @{typ rat}
|
|
43 |
@{text \<sqsubset>} @{typ real} @{text \<sqsubset>} @{typ complex}
|
|
44 |
\end{center}
|
|
45 |
|
|
46 |
\noindent The inclusion @{text \<sqsubset>} means that any value of the numerical
|
|
47 |
type to the left hand side mathematically can be transferred
|
|
48 |
to the numerical type on the right hand side.
|
|
49 |
|
|
50 |
How to accomplish this given the quite restrictive type system
|
|
51 |
of {Isabelle/HOL}? Paulson \cite{paulson-numerical} explains
|
|
52 |
that each numerical type has some characteristic properties
|
|
53 |
which define an characteristic algebraic structure; @{text \<sqsubset>}
|
|
54 |
then corresponds to specialization of the corresponding
|
|
55 |
characteristic algebraic structures. These algebraic structures
|
|
56 |
are expressed using algebraic type classes and embeddings
|
|
57 |
of numerical types into them:
|
|
58 |
|
|
59 |
\begin{center}\begin{tabular}{lccc}
|
|
60 |
@{term of_nat} @{text "::"} & @{typ nat} & @{text \<Rightarrow>} & @{typ [source] "'a::semiring_1"} \\
|
|
61 |
& @{text \<sqinter>} & & @{text \<up>} \\
|
|
62 |
@{term of_int} @{text "::"} & @{typ int} & @{text \<Rightarrow>} & @{typ [source] "'a::ring_1"} \\
|
|
63 |
& @{text \<sqinter>} & & @{text \<up>} \\
|
|
64 |
@{term of_rat} @{text "::"} & @{typ rat} & @{text \<Rightarrow>} & @{typ [source] "'a::field_char_0"} \\
|
|
65 |
& @{text \<sqinter>} & & @{text \<up>} \\
|
|
66 |
@{term of_real} @{text "::"} & @{typ real} & @{text \<Rightarrow>} & @{typ [source] "'a::real_algebra_1"} \\
|
|
67 |
& @{text \<sqinter>} \\
|
|
68 |
& @{typ complex}
|
|
69 |
\end{tabular}\end{center}
|
|
70 |
|
|
71 |
\noindent @{text "d \<leftarrow> c"} means that @{text c} is subclass of @{text d}.
|
|
72 |
Hence each characteristic embedding @{text of_num} can transform
|
|
73 |
any value of type @{text num} to any numerical type further
|
|
74 |
up in the inclusion chain.
|
|
75 |
|
|
76 |
This canonical example exhibits key strengths of type classes:
|
|
77 |
|
|
78 |
\<^item> Sharing of operations and facts among different
|
|
79 |
types, hence also sharing of notation and names: there
|
|
80 |
is only one plus operation using infix syntax @{text "+"},
|
|
81 |
only one zero written @{text 0}, and neutrality
|
|
82 |
(@{thm add_0_left [all, no_vars]} and
|
|
83 |
@{thm add_0_right [all, no_vars]})
|
|
84 |
is referred to
|
|
85 |
uniformly by names @{fact add_0_left} and @{fact add_0_right}.
|
|
86 |
|
|
87 |
\<^item> Proof tool setups are shared implicitly:
|
|
88 |
@{fact add_0} and @{fact add_0_right} are simplification
|
|
89 |
rules by default.
|
|
90 |
|
|
91 |
\<^item> Hence existing proofs about particular numerical
|
|
92 |
types are often easy to generalize to algebraic structures,
|
|
93 |
given that they do not depend on specific properties of
|
|
94 |
those numerical types.
|
|
95 |
|
|
96 |
Considerable restrictions include:
|
|
97 |
|
|
98 |
\<^item> Type class operations are restricted to one
|
|
99 |
type parameter; this is insufficient e.g. for expressing
|
|
100 |
a unified power operation adequately (see \secref{sec:power}).
|
|
101 |
|
|
102 |
\<^item> Parameters are fixed over the whole type class
|
|
103 |
hierarchy and cannot be refined in specific situations:
|
|
104 |
think of integral domains with a predicate @{term is_unit};
|
|
105 |
for natural numbers, this degenerates to the much simpler
|
|
106 |
@{term [source] "HOL.equal (1::nat)"} but facts
|
|
107 |
refer to @{term is_unit} nonetheless.
|
|
108 |
|
|
109 |
\<^item> Type classes are not apt for meta-theory. There
|
|
110 |
is no practically usable way to express that the units
|
|
111 |
of an integral domain form a multiplicative group using
|
|
112 |
type classes. But see session @{text "HOL-Algebra"}
|
|
113 |
which provides locales with an explicit carrier.
|
|
114 |
\<close>
|
|
115 |
|
|
116 |
|
|
117 |
subsection \<open>Navigating the hierarchy\<close>
|
|
118 |
|
|
119 |
text \<open>
|
|
120 |
An indispensable tool to inspect the class hierarchy is
|
|
121 |
@{command class_deps} which displays the graph of classes,
|
|
122 |
optionally showing the logical content for each class also.
|
|
123 |
Optional parameters restrict the graph to a particular segment
|
|
124 |
which is useful to get a graspable view. See
|
|
125 |
the Isar reference manual \cite{isabelle-isar-ref} for details.
|
|
126 |
\<close>
|
|
127 |
|
|
128 |
|
|
129 |
section \<open>The hierarchy\<close>
|
|
130 |
|
|
131 |
subsection \<open>Syntactic type classes\<close>
|
|
132 |
|
|
133 |
text \<open>
|
|
134 |
At the top of the hierarchy there are a couple of syntactic type
|
|
135 |
classes, ie. classes with operations but with no axioms,
|
|
136 |
most notably:
|
|
137 |
|
|
138 |
\<^item> @{class plus} with @{term [source] "(a::'a::plus) + b"}
|
|
139 |
|
|
140 |
\<^item> @{class zero} with @{term [source] "0::'a::zero"}
|
|
141 |
|
|
142 |
\<^item> @{class times} with @{term [source] "(a::'a::times) * b"}
|
|
143 |
|
|
144 |
\<^item> @{class one} with @{term [source] "1::'a::one"}
|
|
145 |
|
|
146 |
\noindent Before the introduction of the @{command class} statement in
|
|
147 |
Isabelle \cite{Haftmann-Wenzel:2006:classes} it was impossible
|
|
148 |
to define operations with associated axioms in the same class,
|
|
149 |
hence there were always pairs of syntactic and logical type
|
|
150 |
classes. This restriction is lifted nowadays, but there are
|
|
151 |
still reasons to maintain syntactic type classes:
|
|
152 |
|
|
153 |
\<^item> Syntactic type classes allow generic notation to be used
|
|
154 |
regardless of a particular logical interpretation; e.g.
|
|
155 |
although multiplication @{text "*"} is usually associative,
|
|
156 |
there are examples where it is not (e.g. octonions), and
|
|
157 |
leaving @{text "*"} without axioms allows to re-use this
|
|
158 |
syntax by means of type class instantiation also for such
|
|
159 |
exotic examples.
|
|
160 |
|
|
161 |
\<^item> Type classes might share operations but not necessarily
|
|
162 |
axioms on them, e.g. @{term gcd} (see \secref{sec:gcd}).
|
|
163 |
Hence their common base is a syntactic type class.
|
|
164 |
|
|
165 |
\noindent However syntactic type classes should only be used with striking
|
|
166 |
cause. Otherwise there is risk for confusion if the notation
|
|
167 |
suggests properties which do not hold without particular
|
|
168 |
constraints. This can be illustrated using numerals
|
|
169 |
(see \secref{sec:numerals}): @{lemma "2 + 2 = 4" by simp} is
|
|
170 |
provable without further ado, and this also meets the typical
|
|
171 |
expectation towards a numeral notation; in more ancient releases
|
|
172 |
numerals were purely syntactic and @{prop "2 + 2 = 4"} was
|
|
173 |
not provable without particular type constraints.
|
|
174 |
\<close>
|
|
175 |
|
|
176 |
end
|