utlc/lambda API
utlc/lambda 包是基于共享命名语法 @syntax.Term[T] 的无类型 lambda 演算:抽象与应用的构造器、β 规则与 η 规则,以及有界的正规序范式化器。它是本库的参考操作语义。
import {
"Luna-Flow/type_theory/core",
"Luna-Flow/type_theory/syntax",
"Luna-Flow/type_theory/rewrite",
"Luna-Flow/type_theory/utlc/lambda",
}
默认别名为 @lambda。在 lambda 项中,Bind(x, b) 是 ,Apply(f, [a]) 是 ,Value(v) 是不透明常量。这些规则在 utlc/lambda 设计中有说明。
构造器
abstraction
abstraction 构建 。
pub fn[T] abstraction(@core.Name, @syntax.Term[T]) -> @syntax.Term[T]
它返回 Bind(parameter, body)。
application
application 构建一元应用 。
pub fn[T] application(@syntax.Term[T], @syntax.Term[T]) -> @syntax.Term[T]
它返回 Apply(function, [argument])。
test "build (λx. x) y" {
let x = @core.Name::new("x")
let y = @core.Name::new("y")
let id : @syntax.Term[Int] = @lambda.abstraction(x, Variable(x))
let term = @lambda.application(id, Variable(y))
assert_eq(term, Apply(Bind(x, Variable(x)), [Variable(y)]))
}
规则
beta_rule
beta_rule 收缩项根部的 β 可约式。
pub fn[T] beta_rule(@syntax.Term[T]) -> @syntax.Term[T]?
对于 Apply(Bind(x, body), [a, ..rest]),它返回避免捕获的代换 body[x := a],当 rest 非空时再将其应用于 rest。对于其他所有项,它返回 None。它适用于任意领域类型 T,因为值从不被检查。
eta_rule
eta_rule 收缩项根部的 η 可约式。
pub fn[T] eta_rule(@syntax.Term[T]) -> @syntax.Term[T]?
对于 x 在 f 中不自由的 Bind(x, Apply(f, [Variable(x)])),它返回 f;否则返回 None。只有一元应用才是 η 可约式:Bind(x, Apply(f, [a, Variable(x)])) 不会被收缩。
beta_eta_rule
beta_eta_rule 先尝试 beta_rule,若不适用再尝试 eta_rule。
pub fn[T] beta_eta_rule(@syntax.Term[T]) -> @syntax.Term[T]?
一个项不可能在根部既是 β 可约式又是 η 可约式(一个是 Apply,另一个是 Bind),因此顺序只是说明优先级。
test "beta and eta at the root" {
let x = @core.Name::new("x")
let y = @core.Name::new("y")
let f = @core.Name::new("f")
let k : @syntax.Term[Int] = Bind(x, Bind(y, Variable(x)))
let expected : @syntax.Term[Int] = Bind(@core.Name::new("y_1"), Variable(y))
assert_eq(@lambda.beta_rule(Apply(k, [Variable(y)])), Some(expected))
let eta_redex : @syntax.Term[Int] = Bind(x, Apply(Variable(f), [Variable(x)]))
assert_eq(@lambda.eta_rule(eta_redex), Some(Variable(f)))
let not_eta : @syntax.Term[Int] = Bind(x, Apply(Variable(x), [Variable(x)]))
assert_eq(@lambda.beta_eta_rule(not_eta), None)
}
范式化
normalize
normalize 在步数上限内用正规序归约把项归约到 beta-eta 范式。
pub fn[T] normalize(@syntax.Term[T], Int) -> @rewrite.NormalizationResult[T]
它就是 @eval.evaluate(term, "beta_eta", beta_eta_rule, NormalOrder, max_steps):每一步收缩项中任意位置(包括绑定子之下)最左最外的 beta 或 eta 可约式。NormalForm(t, n) 表示 t 没有 beta 或 eta 可约式(按上文的一元意义),且在 n 步内得到;StepLimitReached 表示步数上限已用完。发散项(例如 )总是以 StepLimitReached 结束。
test "normalize (λx. λy. x y) y" {
let x = @core.Name::new("x")
let y = @core.Name::new("y")
let inner : @syntax.Term[Int] = Bind(y, Apply(Variable(x), [Variable(y)]))
let term : @syntax.Term[Int] = Apply(Bind(x, inner), [Variable(y)])
assert_eq(@lambda.normalize(term, 10), NormalForm(term=Variable(y), steps=2))
}
第一步是 beta,得到 ;第二步是 eta。