上下文是句法概念。上下文是其中有一个洞的术语。(有时存在多个孔上下文,在这种情况下会给出明确的定义。)上下文的语法是通过采用术语的语法并允许一个子术语成为孔而不是术语来定义的。在BNF中(我使用lambda演算作为示例,没有布尔值,并且if语句对示例没有任何影响。):
[]
C::=[]∣x∣tC∣Ct∣λx.C
与上下文的定义一起出现的是将术语置于上下文中的定义。如果是上下文并且是项,则是通过将放入hole在中的语法树中获得的项。这基本上是一种替换,其中保证该变量只发生一次(但请注意,被替换的“变量”是元级别的变量,而不是lambda微积分或术语其他语言中的变量))。C[]tC[t]t[]C[t][]t
上下文用于表达语义中的各种定义。一个常见的示例是,大多数评估概念都涉及定义可以执行评估的上下文。例如,考虑lambda演算。评估的基本概念由beta减少规则给出:
其中是替代施加到。
(λx.M)N→βM{x←N}
M{x←N}x↦NM
这不是beta归约的完整定义:给定项,如果存在子项和以及变量使得 x。M,则它可以beta归约。但是更普遍的是,如果存在子项使得则可以beta减少。表示这种情况的另一种方式是,如果存在上下文以及某些项和以及变量,使得,则可以beta减少tMNxt=(λx.M)Ntt′t′=(λx.M)NtCMNxt=C[(λx.M)N]。当有这样的减少时,右侧为。要使用正式的符号,应通过以下扣除规则定义beta减少:
通过使所有种类的上下文都明确可以表达相同的定义:
C[M{x←N}]
(λx.M)N→βM{x←N}(β)M→βNC[M]→βC[N](γ)
(λx.M)N→βM{x←N}(β)M→βNλx.M→βλx.N(Cλ)M→βNMP→βNP(C@<)M→βNPM→βPN(C@>)
此定义产生beta减少,即允许减少任何子项的评估概念。用编程语言执行的计算通常不允许在函数内部归约子条件:归约规则只能在应用程序的顶层或左侧或右侧使用。我们可以通过定义一种不允许所有语法形式的新上下文来表达这一点:
我们可以使用此语法来定义语义概念部分评估的结果:
我们也可以通过扩展此定义来呈现此定义,就像上面为减少完整beta所做的一样:
D::=[]∣x∣tD∣Dt
(λx.M)N→npM{x←N}M→npND[M]→npD[N]
(λx.M)N→npM{x←N}(β)M→npNMP→npNP(C@<)M→npNPM→npPN(C@>)
D之所以称为评估上下文,是因为它用于定义评估的概念。评估上下文不是一种特殊的上下文;确切地说,
将其称为评估上下文取决于上下文用于什么。
我将再提供一个上下文示例。让我们根据以下语法定义值:
现在让我们定义另一种上下文:
与上面的相比,如果应用程序的参数为,则孔可以位于应用程序的函数侧一个值。然后定义以下归约概念:
V
V::=xV1…Vn∣λx.M
E::=[]∣ME∣EV
D(λx.M)V→cbvaM{x←V}(βcbva)M→βNE[M]→cbvaE[N](γcbva)
由于函数的参数必须是第一条规则中的值并且lambda抽象不是上下文的限制,我们正在定义按值调用评估策略。由于参数在函数之前求值的进一步限制,这是按值的应用顺序调用。