Ответ 1
Это немного слишком широко, но из ваших комментариев я предполагаю, что вам не хватает базовых систем линейного типа. Эта система ослабевает (обычно не допускается в линейной логике), поэтому она фактически соответствует аффинной интуиционистской логике.
Основная идея: вы можете использовать каждое значение, которое у вас есть (например, переменные) не более одного раза.
Тип A (x) B
(тензорный продукт) примерно соответствует типу значений пары, из которого вы можете проецировать как значение A
, так и значение B
.
Тип A -o B
обозначает линейную функцию, которая потребляет значение A
(помните: не более одного использования!) и выдает один B
.
У вас может быть, например, \x.x : A -o A
, но вы не можете иметь какой-либо термин : A -o (A (x) A)
, поскольку для этого потребуется дважды использовать аргумент.
Тип !A
( ", конечно, A!" ) означает значения типа A
, которые можно дублировать, как и будет, - как это обычно бывает в нелинейных лямбда-исчислениях. Это выполняется по правилу сокращения.
Например, !A -o !B
представляет собой обычную функцию: она требует значения (в неограниченном количестве копий) и создает значение (в неограниченном количестве копий). Вы можете написать функцию !A -o (!A (x) !A)
следующим образом:
\a. (a (x) a)
Обратите внимание, что каждое правило линейного типирования с несколькими помещениями должно разбивать переменные среды между помещениями (например, один получает Gamma, другая Delta), без перекрытия. В противном случае вы можете дублировать линейные переменные. Из-за этого у Сократа есть два контекста. Нелинейным разрезом будет:
G |- t: A G, x:A |- u: B
--------------------------------
G |- u[t/x]: B
но здесь оба термина t
и u
могут использовать переменные в G
, поэтому u[t/x]
может использовать переменные дважды - нехорошо. Вместо этого линейный разрез
G1 |- t: A G2, x:A |- u: B
--------------------------------
G1,G2 |- u[t/x]: B
заставляет вас разделять переменные между двумя помещениями: то, что вы используете в t
, недоступно для u
.