这些打字规则出现在"On the expressivity of elementary linear logic: characterizing Ptime and an exponential time hierarchy"纸上:
从“What part of Milner-Hindley do you not understand?” Stack Overflow问题,我可以阅读一些英文版本,但仍然很难弄清楚如何制作类型检查器。这是我尝试阅读前4条规则:
Ax :作为公理,如果x的类型为A,那么x的类型为A. (不是很明显吗?)
剪切:如果上下文Γ
证明t has type A
,另一个上下文∆
,使用断言x has type A
扩展,证明u has type B
,然后这两个上下文一起证明x
中t
的{{1}}所有出现的u
替换为B
类型。 (这意味着什么呢?为什么有两个上下文,额外的一个来自哪里?另外,这似乎是一个替代规则,但如果替换不是一个术语,而是一个操作?经典的Milner-Hindley没有这样的东西;它对App只有一个非常简单的规则。)
弱:如果上下文证明t has type A
,则使用语句x has type B
扩展的上下文仍然证明t has type A
。 (再次,不是那么明显吗?)
Contr :如果使用x1 has type !A
和x2 has type !A
扩展的上下文证明t has type B
,则使用x has type !A
扩展的上下文证明将x1
中x2
和x
的所有匹配项替换为t
中的B
类型!
。 (替换的另一个规则似乎是?但为什么上面有两个术语,下面有一个术语?另外,为什么那些ani cdate
7076419812 2016-10-12 00:00:00.000
9168919394 2016-10-12 00:00:00.000
6282358407 2016-10-12 00:00:00.000
9168834643 2016-10-12 00:00:00.000
?这些都出现在类型检查器上?)
我非常了解这些规则想要说的内容,但是在它真正点击之前我错过了一些东西,并且我能够实现相应的类型检查器。我该如何理解这些规则?
答案 0 :(得分:8)
这有点过于宽泛,但是根据你的评论,我猜你缺乏一些线性类型系统的基础知识。这个系统有弱化(线性逻辑通常不允许),所以它实际上对应于仿射直觉逻辑。
关键的想法是:您可以使用您拥有的每个值(例如变量)最多一次。
类型A (x) B
(张量积)大致代表对值的类型,您可以从中计算出A
值和B
值。
类型A -o B
代表线性函数,消耗值A
(请记住:最多使用一次!)并生成一个B
。
你可以拥有,例如\x.x : A -o A
但您不能拥有任何字词: A -o (A (x) A)
,因为这需要您使用该参数两次。
类型!A
(“当然是A!”)代表A
类型的值,可以按原样复制 - 正如您在非线性lambda演算中通常所做的那样。这是通过收缩规则完成的。
例如,!A -o !B
代表一个普通函数:它需要一个值(在无限量的副本中)并产生一个值(在无限量的副本中)。您可以按如下方式编写函数!A -o (!A (x) !A)
:
\a. (a (x) a)
请注意,每个具有多个前提的线性类型规则必须在前提之间拆分环境变量(例如,一个获取Gamma,另一个达到Delta),而不重叠。否则,您可以复制线性变量。因此,Cut有两种情况。非线性切割将是:
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
不可用。