/
lec11.tex
208 lines (193 loc) · 13.5 KB
/
lec11.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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
% Филипп Вадлерasdasd
\subsection{\texorpdfstring{Линейные типы}{Linear types}}
%Пусть у нас есть некоторые набор переменных $x$, $y$, $z$ и некоторый набор термов $s$, $t$, $u$, $v$, $w$.
Определим грамматику для нашего $\lambda$-исчисления:
\begin{bnf}
\begin{alignat*}{2}
s ::= &\ x \\
| &\ \lambda\pair{x}.s | s\pair{s} \\
| &\ \oc s | \caseb{s}{\oc x \to s} \\
| &\ \pair{s,s} | \caseb{s}{\pair{x,x} \to s} \\
| &\ \ppair{s,s} | \fst \pair{s} | \snd \pair{s} \\
| &\ \inl \pair{s} | \inr \pair{s}|
\casec{s}{\inl \pair{x} \to s}{\inr \pair{x} \to s}
\end{alignat*}
\end{bnf}
Будем типизировать это $\lambda$-исчисление линейными высказываниями. Выпишем аксиомы:
\begin{@empty}
\inferspacing
\begin{gather*}
\infer[]
{[\Gamma]\vdash \oc s : \oc A}
{[\Gamma]\vdash s : A} \qquad
\infer[]
{\Gamma, \Delta\vdash \caseb{s}{\oc x \to t} : B}
{\Gamma\vdash s : \oc A && \Delta, [x : A]\vdash t : B} \\
\infer[]
{\Gamma, \Delta\vdash \pair{s, t} : A \otimes B}
{\Gamma \vdash s : A && \Delta\vdash t : B} \qquad
\infer[]
{\Gamma, \Delta \vdash \caseb{s}{\pair{x, y} \to t} : C}
{\Gamma\vdash s : A \otimes B && \Delta, \pair{x : A}, \pair{y : B} \vdash t : C} \\
\infer[]{\Gamma \vdash \ppair{s, t} : A \with B}{\Gamma \vdash s : A && \Gamma \vdash t : B} \qquad
\infer[]{\Gamma \vdash \fst \pair{s} : A}{\Gamma \vdash s : A \with B} \qquad
\infer[]{\Gamma \vdash \snd \pair{s} : B}{\Gamma \vdash s : A \with B} \\
\infer[]{\Gamma, \lambda\pair{x}.u : A \multimap B}{\Gamma, \pair{x : A} \vdash u : B} \qquad
\infer[]{\Gamma, \Delta \vdash s \pair{t} : B}{\Gamma \vdash s : A \multimap B && \Delta \vdash t : A} \\
\infer[]{\Gamma \vdash \inl \pair{s} : A \oplus B}{\Gamma \vdash s : A} \qquad
\infer[]{\Gamma \vdash \inr \pair{s} : A \oplus B}{\Gamma \vdash s : B} \\
\infer[]
{\Gamma, \Delta \vdash \casec{s}{\inl \pair{x} \to t}{\inr \pair{y} \to v} : C}
{\Gamma \vdash s : A \oplus B && \Delta, \pair{x : A} \vdash t : C && \Delta, \pair{y : B} \vdash v : C}
\end{gather*}
\end{@empty}
Вложим просто типизируемое $\lambda$-исчисление в линейные типы.
\begin{align*}
\lambda x.s &= \lambda\pair{x'}.\caseb{x'}{\oc x \to s} \\
st &= s\pair{\oc t}
\end{align*}
\begin{example}[Ломаем линейные типы]
Пусть у нас есть выражения $f$, $g$ типа $A \multimap B$.
Возьмем $h = \lambda x.\pair{f\pair{x}, g\pair{x}} : \oc A \multimap B \otimes B$.
Докажем, что $h$ действительно существует в линейных типах:
\[
\infer[]{[f : A \multimap B], [g : A\multimap B]\vdash \lambda x.\pair{f\pair{x}, g\pair{x}} : \oc A \multimap B \otimes B}{
\infer[]{
[f : A \multimap B], [g : A \multimap B], \pair{x' : \oc A}
\vdash \caseb{x'}{\oc x \to \pair{f\pair{x}, g\pair{x}} : B \otimes B}
}{
\infer[]{
\pair{x' : \oc A}, [f : A \multimap B], [g : A \multimap B]
\vdash \caseb{x'}{\oc x \to \pair{f\pair{x}, g\pair{x}} : B \otimes B}
}{
\pair{x' : \oc A} \vdash x' : A &&
\infer[]{[f : A \multimap B], [g : A \multimap B], [x : A]\vdash \pair{f\pair{x}, g\pair{x}} : B \otimes B}{
\infer[]{\vdots}{
\infer[]{[x : A], [f : A \multimap B], [x : A], [g : A \multimap B]\vdash \pair{f\pair{x}, g\pair{x}} : B \otimes B}{
\infer[]{[x : A], [f : A \multimap B]\vdash f\pair{x} : B}{[f : A \multimap B] \vdash f : A \multimap B}
&&
\infer[]{[x : A], [g : A \multimap B]\vdash g\pair{x} : B}{[g : A \multimap B] \vdash g : A \multimap B}
}
}
}
}
}
}
\]
В функции $h$ обьект $A$ был интуционистким, но функции $f$ и $g$ работают с ним, как с линейным.
Как мы видим линейный тип не дает нам размножать обьект (получить несколько ссылок на него в разных местах),
но при этом у нас нет гарантий того, что до этого этот обьект не был размножен.
\end{example}
\subsection{\texorpdfstring{Уникальные типы}{Unique types}}
\newcommand{\ruleVarU}[0]{\mathtt{Var^\odot}}
\newcommand{\ruleVarS}[0]{\mathtt{Var^\otimes}}
\newcommand{\ruleAbs}[0]{\mathtt{Abs}}
\newcommand{\ruleApp}[0]{\mathtt{App}}
\begin{definition}[Род]
Родом будем называть выражение, удовлетворяющие следующей граммтике:
%\begin{bnf}
\begin{alignat*}{3}
\kappa ::= &\ \comb T && \qquad \text{Базовый тип} \\
| &\ \comb U && \qquad \text{Аттрибут уникальности} \\
| &\ * && \qquad \text{Тип} \\
| &\ \kappa \to \kappa
\end{alignat*}
%\end{bnf}
\end{definition}
\begin{definition}[Типовые константы]\ \\
\begin{tabular}{llll}
$\mathtt{Int}$, $\mathtt{Bool}$ & :: & $\comb T$ & Базовые типы \\
$\to$ & :: & $* \to * \to \comb T$ & Коструктор функций \\
$\bullet, \times$ & :: & $\comb U$ & Уникальный, не уникальный \\
$\vee, \wedge$ & :: & $\comb U \to \comb U \to \comb U$ & Дизьюнкия, коньюнкция аттрибутов \\
$\neg$ & :: & $\comb U \to \comb U$ & Отрицание аттрибута \\
$\mathtt{Attr}$ & :: & $\comb T \to \comb U \to *$ & Конструктор типа
\end{tabular}
\end{definition}
С помощью типовых констант мы можем делать различные типы разных родов.
Тип (рода $*$) состоит из базового типа (рода $\comb T$) и аттрибута уникальности (это тоже тип, только рода $\comb U$).
Аттрибут показывает обязан ли обьект этого типа быть уникальным (всего на этот обьект может существовать только одна ссылка) "--- $\bullet$,
или это не обязательно "--- $\times$.
На аттрибутах заданы различные булевы операции, которые выполняются так, будто $\bullet \equiv true$, $\times \equiv false$.
Немного сахара:
\[
\attr{t}{u} \equiv t^u \qquad \attr{(a \to b)}{u} \equiv a \xrightarrow{u} b
\]
Грамматика выражений будет похожа на классическую грамматику выражений, за исключением того,
что у переменных будет указываться аттрибут ($x^\odot$), если на переменную есть только 1 ссылка,
или аттрибут ($x^\otimes$), если на переменную имеется несколько ссылок.
\begin{bnf}
\[
e ::= \lambda x.e | ee | x^\odot | x^\otimes
\]
\end{bnf}%
В доказательствах будем использовать следующую нотацию: $\Gamma \vdash e : \tau |_{\fv}$.
$\Gamma$ и $\fv$ отображают переменные в типы.
Разница заключается в том, что $\Gamma$ отображает в типы рода $*$,
а $\fv$ отображает в типы рода $\comb U$.
Введём правила вывода. Эти правила похожи на правила из системы типов Хиндли-Милнера,
за исключением того, что они будут также нести информацию о уникальности типов и переменных.
\[
\infer[\ruleVarU]{\Gamma, x : t^u \vdash x^\odot : t^u |_{x:u}}{} \qquad
\infer[\ruleVarS]{\Gamma, x : t^\times \vdash x^\otimes : t^\times |_{x:\times}}{}
\]
В обоих правилах мы вводим в контекст новую переменную.
В $\ruleVarU$ мы вводим уникальную перемменную, а в $\ruleVarS$ "--- расшаренную.
Заметим, что в $\ruleVarU$ хоть переменная и уникальна, тип ее может быть и не уникальным,
так как потом эта переменная может перестать быть уникальной (например, её скопировали в процессе программы).
В $\ruleVarS$ тип переменной обязан быть не уникальным.
\[
\infer[\ruleAbs]
{\Gamma \vdash \lambda x.e : a \xrightarrow{\vee \fv'} b |_{\fv'}}
{\Gamma, x : a \vdash e : b |_{\fv} && \fv' \equiv \fuck_x \fv} \\
\]
Операция $\fuck_x \fv$ выкидывает из отображения $\fv$ все пары $x : \comb U$.
Запись $\vee \fv'$ означает дизьюнкцию всех типов из отоборажения $\fv'$.
Рассмотрим правило $\ruleAbs$.
В замыкании функции $\lambda x.e$ находятся все свободные переменные из выражения $e$, за исключением связанной переменной $x$.
Если в замыкании функции находится уникальная переменная, то функция должна быть уникальна, следовательно,
атрибут уникальности функции вычисляется так: $\vee \left( \fuck_x \fv \right)$, что и написано в правиле.
\[
\infer[\ruleApp]
{\Gamma \vdash e_1e_2 : b |_{\fv_1 \cup \fv_2}}
{\Gamma \vdash e_1 : a \xrightarrow{u} b |_{\fv_1} \qquad \Gamma \vdash e_2 : a |_{\fv_2}}
\]
Тут обычная аппликация Хиндли-Милнера, в которой мы запоминаем уникальность свободных переменных из обоих ветвей.
Уникальность функции нам не интересна так как мы можем вычислять функции вне зависимости от их уникальности.
\begin{example}
Рассмотрим функцию $\mathtt{dup} \equiv \lambda x.\pair{x^\otimes, x^\otimes}$ типа $a^\times \xrightarrow{\times} a^\times \with^u a^\times$.
Покажем, что такая функция существует в нашей системе типов:
\[
\infer[\ruleAbs]
{\vdash \lambda x.\pair{x^\otimes, x^\otimes} :a^\times \xrightarrow{\times} a^\times \with^u a^\times |}
{
\infer[]
{x : a^\times \vdash \pair{x^\otimes, x^\otimes} : a^\times \with^u a^\times | x : \times}
{
\infer[\ruleVarS]{x : a^\times \vdash x^\otimes : x : \times}{} \qquad
\infer[\ruleVarS]{x : a^\times \vdash x^\otimes : x : \times}{}
}
}
\]
Так как функция $\mathtt{dup}$ дублирует аргументы, она принимает переменную неуникального типа.
Компилятор это может легко проверить, так как в теле функции есть 2 ссылки на $x$,
и именно поэтому она помечена как $\otimes$.
Также функция $\mathtt{dup}$ полиморфна по аттрибуту уникальности возвращаемого значения,
так как мы можем попросить у функции как и уникальную пару, так и расшаренную.
\end{example}
\begin{example}
Давайте по другому определим функцию
$\mathtt{dup'}~x \equiv \left(\lambda f. \pair{f^\otimes \perp, f^\otimes \perp} \right) \left(\mathtt{const}~x^\odot \right)$.
Очевидно, она делает тоже самое, что и функция $\mathtt{dup}$.
Давайте установим тип функции $\mathtt{const}$.
Сначала запишем ее тип без указания аттрибутов уникальности над стрелочками: $t^u \to s^v \to t^u$.
Если мы частично применим функцию $\mathtt{const}$, передав в нее переменную уникального типа,
то мы должны получить функцию $(\mathtt{const}~x)$ уникального типа.
Если бы это было не так, то мы смогли бы полученную функцию применить в нескольких местах, и,
следственно, смогли получить несколько ссылок на результат функции.
Но это противоречит типовой системе, так как результат (он же первый аргумент исходной функции) "--- уникален.
Значит, полный тип функции $\mathtt{const}$ равен $t^u \xrightarrow{\times} s^v \xrightarrow{u} t^u$.
В первой части функции $\mathtt{dup'}$ лямбда-выражение принимает расшаренную функцию.
То есть функция $(\mathtt{const}~x)$ не уникальна. Значит тип переменной $x$ не уникален.
Это является примером того, когда уникальная переменная имеет неуникальный тип.
\end{example}