lambda表达式的自由变量列表

时间:2012-12-09 00:14:01

标签: ocaml lambda-calculus free-variable

我刚刚为即将到来的OCaml测试做了一些功课,我遇到了一些麻烦。

考虑由以下抽象语法定义的λ术语(其中x是变量):

t ::= x | t t | λx. t  

写一个类型术语来表示λ术语。假设变量表示为字符串。

好的,男孩。

# type t = Var of string | App of (t*t) | Abs of string*t;;
type t = Var of string | App of (t * t) | Abs of (string * t)

术语t的自由变量fv(t)由归纳法定义如下:

fv(x) = {x}  
fv(t t') = fv(t) ∪ fv(t')  
fv(λx. t) = fv(t) \ {x}

当然可以。

# let rec fv term = match term with
Var x -> [x]
  | App (t, t') -> (List.filter (fun y -> not (List.mem y (fv t'))) (fv t)) @ (fv t')
  | Abs (s, t') -> List.filter (fun y -> y<>s) (fv t');;
      val fv : t -> string list = <fun>

例如,

fv((λx.(x (λz.y z))) x) = {x,y}.

让我们检查一下。

# fv (App(Abs ("x", App (Abs ("z", Var "y"), Var "z")), Var "x"));;
- : string list = ["y"; "z"; "x"]

我已经检查了一百万次,我确信结果应该包含“z”变量。你能安慰我吗?

1 个答案:

答案 0 :(得分:3)

在对OP的评论中,@ PasqualCuoq指出,lambda演算中的λ与OCaml中的fun相同。也就是说,术语t in λx.t被贪婪地评估(参见http://en.wikipedia.org/wiki/Lambda_calculus#Notation)。

这意味着(λz.y z)实际上是(λz.(y z)),并且上面的函数是正确的,但是为示例表达式(λx.(x (λz.y z))) x提供的翻译不是,因为它应该已经

(App(Abs("x", App(Var "x", Abs("z", App(Var "y", Var "z")))), Var "x"))

取代

(App(Abs ("x", App (Abs ("z", Var "y"), Var "z")), Var "x"))

这是一个名为Stack Overflow的绝佳地方!