-
Notifications
You must be signed in to change notification settings - Fork 6
/
lec06.tex
187 lines (165 loc) · 11.4 KB
/
lec06.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
\subsection*{\texorpdfstring{Экзистенциальные типы}{Existential types}}
Допустим, у нас есть абстрактный тип данных "<стек"> $\alpha$ и операции над ним: \\
\begin{tabular}{l l}
$\func{empty}$ & $: \alpha$ \\
$\func{push}$ & $: \alpha\with\nu\to\alpha$ \\
$\func{pop}$ & $: \alpha\to\alpha\with\nu$ \\
\end{tabular} \\
Можно попробовать сказать это так: $\mathtt{stack} =
\alpha \with (\alpha\with\nu\to\alpha) \with (\alpha\to\alpha\with\nu)$, где вместо $\alpha$ будет описание хранилища для стека.
Однако, проблема в том, что мы можем захотеть скрыть полный тип $\alpha$, так как в нём будут описаны детали реализации.
Нам хотелось бы дать только интерфейс стека. Это можно сказать так:
$\exists \alpha . \alpha \with (\alpha\with\nu\to\alpha) \with (\alpha\to\alpha\with\nu)$.
То есть существует какое-то $\alpha$, реализующее описанный интерфейс.
По аналогии с правилом удаления квантора существования, можно определить правила вывода для выражений экзистенциальных типов:
\[
\infer{\Gamma\vdash (\pack{M, \theta}{\exists \alpha . \varphi}) : \exists \alpha.\varphi}
{\Gamma \vdash M : \varphi[\alpha := \theta]} \qquad
\infer[(\alpha \notin \FV(\Gamma, \psi))]
{\Gamma \vdash \abstype{\alpha}{x:\varphi}{M}{N:\psi}}
{\Gamma \vdash M : \exists \alpha . \varphi && \Gamma, x : \varphi \vdash N : \psi}
\]
Если вспомнить, что квантор существования выразим через квантор всеобщности, то можно записать выражения
\texttt{pack} и \texttt{abstype} без расширения языка:
\begin{gather*}
\pack{M, \theta}{\exists \alpha . \varphi} =
\Lambda \beta . \lambda x^{\forall \alpha . \varphi \to \beta} . x \theta M \\
\abstype{\alpha}{x : \varphi}{M}{N}:\psi =
M \psi (\Lambda \alpha . \lambda x ^ \varphi . N)
\end{gather*}
Покажем, что $\abstype{\alpha}{x:\varphi}{(\pack{M,\theta}{\exists\alpha .\varphi})}{N}$
редуцируется в $N[\alpha\coloneqq\theta][x\coloneqq M]$:
\begin{align*}
\abstype{\alpha}{x:\varphi}{(\pack{M,\theta}{\exists\alpha .\varphi})}{N}
&= (\reduction{\Lambda \beta} . \lambda x^{\forall \alpha . \varphi \to \beta} . x \theta M)
\reduction{\psi} (\Lambda \alpha . \lambda x ^ \varphi . N) \\
&\to_\beta (\reduction{\lambda x^{\forall \alpha . \varphi \to \psi}} . x \theta M)
\reduction{(\Lambda \alpha . \lambda x ^ \varphi . N)} \\
&\to_\beta (\reduction{\Lambda \alpha} . \lambda x^\varphi . N) \reduction\theta M \\
&\to_\beta (\reduction{\lambda x^\varphi} . N)[\alpha\coloneqq\theta] \reduction M \\
&\to_\beta N[\alpha\coloneqq\theta][x\coloneqq M]
\end{align*}
\begin{example} \todo буде незабаром.
\end{example}
\begin{statement}
$F$ неразрешима.
\end{statement}
Ни одна из задач $\lambda$-исчисления в системе $F$ не разрешима, даже задача проверки типизации.
Доказать это можно через сведение к проблеме останова.
Итак, мы попытались добавить к типизированному $\lambda$-исчислению полиморфизм и абстрактные типы данных и получили слишком сложный язык.
Давайте попробуем немного его упростить, чтобы с ним можно было работать.
\subsection{\texorpdfstring{Типовая система Хиндли-Милнера}{Hindley and Milner’s type system}}
\begin{definition}[ранг типа]
\[
\rank(\tau) =
\begin{cases}
\max(\rank(\sigma)+1, \rank(\rho)) & \tau \equiv \sigma \to \rho\text{, если }\sigma\text{ содержит }\forall \\
\rank(\rho) & \tau \equiv \sigma \to \rho\text{, если }\sigma \text{ не содержит } \forall \\
0 & \tau \equiv \alpha \\
\max(\rank(\rho), 1) & \tau \equiv \forall \alpha . \rho
\end{cases}
\]
\end{definition}
\begin{example} Ранг экзистенциального типа:
\begin{align*}
\rank(\exists \alpha . \beta) &= \rank(\forall \gamma . (\forall \alpha . \beta \to \gamma) \to \gamma) \\
&= \max(\rank((\forall \alpha . \beta \to \gamma) \to \gamma), 1) \\
&= \max(\max(\rank(\forall \alpha . \beta \to \gamma) + 1, \rank(\gamma)), 1) \\
&= \max(\max(2, 0), 1) = 2
\end{align*}
\end{example}
\begin{definition}[тип в системе Хиндли-Милнера] \ \\
Тип (монотип) "--- выражение в грамматике $ \begin{bnf} \tau ::= \alpha | \tau \to \tau | (\tau) \end{bnf} $. \\
Типовая схема (политип) "--- выражение в грамматике $ \begin{bnf} \sigma ::= \tau | \forall \alpha . \sigma \end{bnf} $.
\end{definition}
$\forall\alpha.\alpha\to\alpha$ "--- политип, $\forall\alpha.\alpha\to\forall\beta.\beta$ "--- некорректный в системе Хиндли-Милнера тип.
\begin{statement}
$\rank(\tau) = 0$, $\rank(\sigma) = 1$.
\end{statement}
\begin{definition}[подтип]
$\sigma_1$ "--- подтип $\sigma_2$, если существует такая подстановка
$[\alpha_1 \coloneqq \theta_1, \alpha_2 \coloneqq \theta_2 \ldots \alpha_n \coloneqq \theta_n]$, что:
\begin{enumerate}
\item $\sigma_1 = \forall \beta_1 \ldots \forall \beta_k . \tau [\alpha_1 \coloneqq \theta_1 \ldots \alpha_n := \theta_n]$,
$\alpha_i$ не входит свободно в $\theta_j$
\item $\sigma_2 = \forall \alpha_1 \ldots \forall \alpha_n \tau$
\end{enumerate}
\end{definition}
\begin{definition}[система Хиндли-Милнера] Грамматика:
\begin{bnf}
\[
\Lambda ::= x | \lambda x . \Lambda | \Lambda \Lambda | (\Lambda) | \lett{x=\Lambda}{\Lambda}
\]
\end{bnf}%
Будем обозначать контекст $\Gamma$ без типа $x$ как $\Gamma_x$.
Правила вывода:
\inferspacing
\begin{gather*}
\infer[\text{(Тавтология, $x : \sigma \in \Gamma$)}]{\Gamma \vdash x : \sigma}{} \qquad
\infer[\text{(Уточнение, $\sigma'$ "--- подтип $\sigma$)}]{\Gamma \vdash e : \sigma'}{\Gamma \vdash e : \sigma} \\
\infer[\text{(Обобщение, $\alpha\notin\FV(\Gamma)$)}]{\Gamma \vdash e : \forall \alpha . \sigma}{\Gamma \vdash e : \sigma} \qquad
\infer[\text{(Абстракция)}]{\Gamma \vdash \lambda x . e : \tau' \to \tau}{\Gamma_x, x : \tau' \vdash e : \tau} \\
\infer[\text{(Применение)}]
{\Gamma \vdash e e' : \tau}{\Gamma \vdash e : \tau' \to \tau && \Gamma \vdash e' : \tau'} \qquad
\infer[\text{(Let)}]
{\Gamma \vdash \lett{x=e}{e':\tau}}
{\Gamma \vdash e : \sigma && \Gamma_x, x : \sigma \vdash e' : \tau}
\end{gather*}
\end{definition}
Мы существенно ограничили набор возможных типов в нашем языке, однако, он всё ещё вполне сильный.
В нём всё ещё есть полиморфизм.
Хотя в системе Хиндли-Милнера (как и во всех рассматриваемых нами типовых системах) нельзя типизировать $\comb Y$-комбинатор,
можно добавить его, расширив язык.
Давайте определим его как $\comb Y f = f \left(\comb Y f\right)$.
Какой у него должен быть тип? Пусть $\comb Y$ принимает $f$ типа $\alpha$, и возвращает нечто типа $\beta$,
то есть $\comb Y : \alpha\to\beta$.
Функция $f$ должна принимать то же, что возвращает $\comb Y$, так как результат $\comb Y$ передаётся в $f$,
и возвращать она должна то же, что возвращает $\comb Y$, так как тип выражений с обоих сторон равенства должен быть одинаковый,
то есть $f : \beta\to\beta$.
Кроме того, $\alpha$ и тип $f$ это одно и то же, $\alpha=\beta\to\beta$.
После подстановки и заключения свободной переменной под квантор получаем $\comb Y : \forall\beta.(\beta\to\beta)\to\beta$.
Через такой $\comb Y$ можно определять рекурсивные функции, и они будут типизироваться.
\subsection{\texorpdfstring{Вывод типа}{Type inference}}
\begin{statement}
Задача вывода типа в системе Хиндли-Милнера разрешима.
\end{statement}
Приведём алгоритм, решающий эту задачу.
Он будет принимать выражение $e$ в контексте $\Gamma$ и возвращать такую подстановку $S$ и тип $\tau$, что
\[
S(\Gamma) \vdash e : \tau
\]
В алгоритме будем пользоваться \hyperref[unificator]{унификацией} ($U(\tau_1, \tau_2)$ "--- унификатор $\tau_1$ и $\tau_2$),
определим замыкание всех несвязанных типовых переменных в контексте:
\[
\overline{\Gamma}(\tau) = \forall \alpha_1 \ldots \forall \alpha_n . \tau
\]
где $\alpha_i \in \FV(\tau)$ и $\alpha_i \notin \FV(\Gamma)$.
Алгоритм описан в таблице \ref{algorithm-w}.
Если какие-то условия не могут быть соблюдены, то тип выражения не может быть выведен.
%\begin{center}
\begin{table}[ht]
\centering
\begin{tabular}{Sl Sl Sl} \toprule
Вид $e$ & Условия & $W(\Gamma, e)$ \\ \midrule
$x$
& $x : \forall \alpha_1 \ldots \alpha_k . \tau' \in \Gamma$ & $S =\mathrm{id}$ \\
& $\beta_i$ "--- новые переменные & $\tau = \tau'[\alpha_i \coloneqq \beta_i]$ \\
\midrule
$e_1 e_2$
& $W(\Gamma, e_1) = (S_1, \tau_1)$ & $S = V \circ S_1 \circ S_2$ \\
& $W(S_1(\Gamma), e_2) = (S_2, \tau_2)$ & $\tau = S(\beta)$ \\
& $U(S_2(\tau_1), \tau_2 \to \beta) = V$, $\beta$ "--- новый тип & \\ \midrule
$\lambda x . e$
& $W(\Gamma_x \cup \set{x : \beta}, e) = (S_1, \tau_1)$ & $S = S_1$ \\
& $\beta$ "--- новый тип & $\tau = S(\beta) \to \tau_1$ \\ \midrule
$\lett{x=e_1}{e_2}$
& $W(\Gamma, e_1) = (S_1, \tau_1)$ & $S = S_2 \circ S_1$ \\
& $W(S_1 \Gamma_x \cup \set{x : \overline{S_1 \Gamma} (\tau_1)}, e_2) = (S_2, \tau_2)$ & $\tau = \tau_2$ \\ \bottomrule
\end{tabular}
\caption{Алгоритм $W$.}
\label{algorithm-w}
\end{table}
%\end{center}
\begin{example}
\todo
\end{example}