是否通常将变量包装在无用的`id`调用中以避免证明上的eta转换问题?

时间:2017-01-28 02:23:01

标签: haskell functional-programming lambda-calculus

使用类似于Morte / CoC的语言,我试图证明简单的陈述there are lists of arbitrary lengths。为此,我写了以下类型:

∀ n:Nat ->
(ThereIs (List Nat)
  (Equal Nat 
    (List.length Nat l) 
    n)))

ThereIs是依赖对(Sigma)。一切都是教会编码的。为证明这一点,我写了以下证据:

λ n:Nat ->
(ThereIs.this (List Nat)
  (λ l:(List Nat) -> (Equal Nat (List.length Nat l) n))
  (List.replicate Nat n Nat.Zero)
  (Equal.refl Nat n))

奇怪的是,我在d(即Nat类型的自由变量)和λ c:* -> λ b:(c -> c) -> λ a:c -> (d c b a)之间出现了类型不匹配错误。但是那个后期,当eta减少时,只是d!由于我没有准备好eta-reducer,我反而做了以下"无用的识别"功能:

λ n: Nat ->

λ Nat:* ->
λ Succ: (Nat -> Nat) ->
λ Zero: Nat ->

(n Nat Succ Zero)

现在,通过将这个无用的id应用到n的每个出现,I" un-eta"它,导致证据检查。我想对这里发生的事情有所了解。这是"无用的id"在编写证据时使用已知/使用的模式?如果没有这么小的帮助,为什么没有能够打字的结构微积分检查这个证据呢?这种现象背后是否存在任何深层次的推理,或者说这是没有特殊原因的事情?

1 个答案:

答案 0 :(得分:4)

您需要在转化检查算法中添加eta。这可以通过几种方式完成,最简单的两种方式

  • 按照Ulf Norell's thesis第22页的类型导向并在Agda中使用
  • 在Coq AFAIK
  • 中使用的无类型

函数完成了无类型的eta转换,它比我们的情况下的类型版本更简单,更快(不需要在中性应用程序中重新计算或缓存类型)。算法如下:

我们首先检查这两个值是否像往常一样是lambda的情况。但是,之后我们检查另外两个案例,当时只有一边是lambda。在这些情况下,我们将lambda主体应用于新的通用变量(像往常一样),并将另一个术语应用于同一个变量,并检查结果值的相等性。

这就是全部!它实际上非常简单,并且没有太多的性能成本。请注意,我们不需要实现eta减少或强eta标准化,因为eta转换检查很容易在飞行中对弱头正常值进行。