lambda演算中堆栈数据结构的定义及其主要操作

lambda演算中堆栈数据结构的定义及其主要操作,lambda,functional-programming,lambda-calculus,combinators,y-combinator,Lambda,Functional Programming,Lambda Calculus,Combinators,Y Combinator,我试图在lambda演算中定义一个堆栈数据结构,使用定点组合器。我试图定义两个操作,插入和删除,因此,推和弹出,但我唯一能够定义的操作,插入,工作不正常。我不知道如何定义删除 这是我对push操作的方法,以及我对堆栈的定义: Stack definition: STACK = \y.\x.(x y) PUSH = \s.\e.(s e) 我的堆栈用一个元素初始化以指示底部;我在这里使用的是0: stack = STACK 0 = \y.\x.(x y) 0 = \x.(x 0) /

我试图在lambda演算中定义一个
堆栈
数据结构,使用定点组合器。我试图定义两个操作,
插入
删除
,因此,
弹出
,但我唯一能够定义的操作,插入,工作不正常。我不知道如何定义删除

这是我对
push
操作的方法,以及我对
堆栈的定义:

Stack definition:
STACK = \y.\x.(x y)
PUSH = \s.\e.(s e)
我的堆栈用一个元素初始化以指示底部;我在这里使用的是
0

stack = STACK 0 = \y.\x.(x y) 0 = \x.(x 0)       // Initialization
stack = PUSH stack 1 = \s.\e.(s e) stack 1 =     // Insertion
    = \e.(stack e) 1 = stack 1 = \x.(x 0) 1 =
    = (1 0)
但现在,当我尝试插入另一个元素时,它不起作用,因为我的初始结构已被解构

如何修复
堆栈
定义或
推送
定义,以及如何定义
弹出
操作?我想我将不得不应用一个组合符,以允许递归,但我不知道如何做到这一点

参考:


对于lambda演算中数据结构定义的任何进一步解释或示例,我们将不胜感激。

通过定义一个组合符,它:

定义为一个没有自由变量的lambda项,因此根据定义,任何组合子都已经是一个lambda项

例如,您可以通过以下方式定义列表结构:

Y = (list definition in lambda calculus)
Y LIST = (list definition in lambda calculus) LIST
Y LIST = (element insertion definition in lambda calculus)

直观地,使用定点组合器,一个可能的定义是——考虑= lambda:

  • 列表要么为空,后跟一个尾随元素,比如
    0
  • 或者列表由元素
    x
    形成,该元素可能是前一个列表中的另一个列表
由于它是用一个组合子定义的——定点组合子——因此不需要执行进一步的应用程序,下面的抽象本身就是一个lambda术语

Y = \f.\y.\x.f (x y)
现在,将其命名为列表:

Y LIST = (*\f*.\y.\x.*f* (x y)) *LIST* -- applying function name
LIST = \y.\x.LIST (x y), and adding the trailing element "0"
LIST = (\y.\x.LIST (x y) ) 0
LIST = (*\y*.\x.LIST (x *y*) ) *0*
LIST = \x.LIST (x 0), which defines the element insertion abstraction.

不动点组合器<代码> y>代码>,或者简单的组合器,允许您考虑列表的定义已经是一个有效成员,没有自由变量,所以不需要减少。 然后,您可以通过执行以下操作附加/插入元素,例如1和2:

LIST = (\x.LIST (x 0)) 1 2 =
    = (*\x*.LIST (*x* 0)) *1* 2 =
    = (LIST (1 0)) 2 =
但是在这里,我们知道列表的定义,所以我们扩展它:

    = (LIST (1 0)) 2 =
    = ((\y.\x.LIST (x y)) (1 0)) 2 =
    = ((*\y*.\x.LIST (x *y*)) *(1 0)*) 2 =
    = ( \x.LIST (x (1 0)) ) 2 =
现在,插入elemenet
2

    = ( \x.LIST (x (1 0)) ) 2 =
    = ( *\x*.LIST (*x* (1 0)) ) *2* =
    = LIST (2 (1 0))
由于列表是一个lambda术语,由一个组合词定义,因此,在新插入的情况下,它既可以扩展,也可以保持原样

为将来的插入扩展:

    = LIST (2 (1 0)) =
    = (\y.\x.LIST (x y)) (2 (1 0)) =
    = (*\y*.\x.LIST (x *y*)) *(2 (1 0))* =
    = \x.LIST (x (2 (1 0))) =
    = ( \x.LIST (x (2 (1 0))) ) (new elements...)
我真的很高兴我自己能够推导出这个公式,但我很确定,在定义堆栈、堆或更奇特的结构时,一定有一些很好的附加条件

尝试推导堆栈插入/移除的抽象——不需要所有的分步步骤:

Y = \f.\y.\x.f (x y)
Y STACK 0 = \x.STACK (x 0)
STACK = \x.STACK (x 0)
要对其执行操作,让我们命名一个空堆栈——分配一个变量(:

我们再次将这个结果命名为pop元素:

stack = \x.STACK x (3 (2 (1 0)))

// Removal -- POP STACK -> STACK
POP = \s.(\y.s (y (\t.\b.b)))
stack = POP stack =
    = ( \s.(\y.s y (\t.\b.b)) ) stack =
    = \y.(stack (y (\t.\b.b))) = but we know the exact expansion of "stack", so:
    = \y.((\x.STACK x (3 (2 (1 0))) ) (y (\t.\b.b))) =
    = \y.STACK y (\t.\b.b) (3 (2 (1 0))) = no problem if we rename y to x (:
    = \x.STACK x (\t.\b.b) (3 (2 (1 0))) =
    = \x.STACK x (\t.\b.b) (3 (2 (1 0))) = someone guide me here, if i'm wrong
    = \x.STACK x (\b.b) (2 (1 0)) =
    = \x.STACK x (2) (1 0) =
    = \x.STACK x (2 (1 0))
为了什么,我们希望有元素
3
弹出


我自己也尝试过推导,所以,如果lambda演算中有任何我没有遵循的限制,请指出。

lambda演算中的堆栈只是一个单链表。单链表有两种形式:

nil  = λz. λf. z
cons = λh. λt. λz. λf. f h (t z f)
这是,列表表示为其。重要的是,您根本不需要固定点组合器。在该视图中,堆栈(或列表)是一个函数,它为
nil
情况取一个参数,为
cons
情况取一个参数。例如,列表
[a,b,c]
表示如下:

cons a (cons b (cons c nil))
空堆栈
nil
相当于SKI演算的
K
组合器。
cons
构造函数是您的
push
操作。给定一个头部元素
h
和另一个尾部元素
t
,结果是一个新堆栈,元素
h
位于前端

pop
操作只需将列表拆分为首尾两部分。您可以通过一对函数来完成此操作:

head = λs. λe. s e (λh. λr. h)
tail = λs. λe. s e (λh. λr. r nil cons)
其中,
e
是处理空堆栈的东西,因为弹出空堆栈是未定义的。可以很容易地将它们转换为一个函数,返回

pop = λs. λe. s e (λh. λr. λf. f h (r nil cons))

同样,对是Church编码的。对只是一个高阶函数。对
(A,b)
表示为高阶函数
λf.fab
。它只是一个函数,给定另一个函数
f
,它将
f
应用于
a
b

,类似地,我们如何定义堆栈和队列???@AnupamTamrakar我已经添加了
堆栈插入/删除;请检查它。尊敬!一个单独链接的列表不是一个完美的堆栈吗?
push
=
cons
pop
=
head/tail
?我提出这个问题是因为单独链接的列表已经做了一千次了,而且可能更容易思考。@delnan这接近我在回答中提出的方法,因为我已经使用了
l的一部分ist
定义定义
堆栈
。感谢您的回复;这种方法与我在sml中看到的方法非常接近。考虑到我的方法,正如您所指出的,这可能不是必需的,但使用定点组合器,我已经达到了一些看起来确实有效的效果。它是错误的吗?还是根本不是标准?以及,如果没有错,你介意看看我在赏金消息中指出的应用程序吗?尊敬!我不认为你的
Y
实现在任何方面都是错误的,它只是不必要的复杂。
Y
组合器严格来说比你需要的更强大,因为它允许你构造无界(无限)的堆栈。啊,这就是我一直在寻找的确认!非常感谢您的耐心,我完全同意我编写函数的方式变得更加混乱。我将等待任何进一步的评论,直到
pop = λs. λe. s e (λh. λr. λf. f h (r nil cons))