完全可以在不使用评估上下文的情况下为我的语言编写评估规则。我的语义完全是按值进行调用,并且不允许该术语在lambda内部逐步进行。尽管如此,我所看到的所有资源都以某种方式使用了减少上下文。是否有充分的理由使用我缺少的背景?
答案 0 :(得分:3)
简短回答:你没有,但对他们来说更容易。
答案很长:几乎所有你都会使用评估上下文,你可以在缩减关系中使用不同的缩减规则,它会变得更加令人讨厌,特别是当你对除了最小的语言之外的任何东西进行建模时。 / p>
假设你想用值lambda演算来模拟调用。它的语言(没有评估上下文)将是:
(define-language Lv
(v (λ (x) e))
(e v
(e e))
(x variable-not-otherwise-mentioned)
#:binding-forms
(λ (x) e #:refers-to x))
(此处,最后两行用于利用Redex的capture avoiding substitution。
现在,让我们尝试在不使用评估上下文的情况下为这种语言制作语义。有两个地方我们可以扩展子表达式,操作符和函数应用程序的操作数。因此,包括正常β减少的那些给我们:
(define red
(reduction-relation
Lv
(--> (e_1 e_2)
(v_1 e_2)
(where v_1 ,(first (apply-reduction-relation red (term e_1)))))
(--> (v_1 e_2)
(v_1 v_2)
(where v_2 ,(first (apply-reduction-relation red (term e_2)))))
(--> ((λ (x) e) e_2)
(substitute e x e_2))))
这不是太糟糕,但请记住,我们必须为每个可以评估子表达式的地方添加一个额外的规则。因此,如果需要自己的规则等,那么就需要自己的规则。请记住,这是基于每种形式的规则。
更简单的方法是使用评估上下文,它允许我们指定哪些表达式具有可以采取步骤的子表达式,以及它们应该发生的顺序。所以让我们尝试重写我们的{{1}语言与评估上下文:
Lv
现在它的行数增加了三行,但是这告诉redex我们将在评估上下文(define-language Lv2
(v (λ (x) e))
(e v
(e e))
(x variable-not-otherwise-mentioned)
(E hole
(E e)
(v E))
#:binding-forms
(λ (x) e #:refers-to x))
中评估我们的表达式,并且当它完成对表达式的评估时,将它放入上下文中(其中{{1}可以这么说是顶级的上下文。因此,我们可以将减少关系减少到只有一个规则,β减少:
E
在这里,我们使用hole
表示我们位于(define red2
(reduction-relation
Lv2
(--> (in-hole E ((λ (x) e) e_2))
(in-hole E (substitute e x e_2)))))
之后的一个洞中,如上所示。这遵循值语义调用,因为空洞只能在应用程序中从左到右显示。
你可以想象,如果你有一个包含许多子表达式的更大的计算,这将使你免于编写大量的约简规则。
所以,回顾一下,你不需要,它只会使你的模型更短。