该OISC基于福克的X组合器,其定义如下:
X=λf .f (λg h x .g x (h x)) (λa b c .a)
如果我们承认SKI演算是图灵完成的,则上述组合器也就是图灵完成的。这是因为S,K和I可以用X表示,如下所示:XSKIX
SKI=S K K=X (X X)=X X=X (X X) (X X) (X X)
XOISC如何工作
XOISC内部具有一个(最初为空)堆栈,从那里开始,以为参数的指令执行以下操作:n
- 从堆栈中弹出元素(函数f 1 … f N),然后按f 1(nf1…fNf1 (f2 (…(fN X)…))
一旦没有更多的指令,XOISC会将所有命令行参数(如果有的话)推入堆栈,例如:
[s1,…, sMstack before, a1,…, aNarguments]
最终计算将为。(…((…(s1 s2)…) sM) a1)…)aN
由于XOISC中的一条指令仅采用一个参数(内存偏移量),因此没有理由甚至为该指令使用名称。因此,有效的源文件将仅由用换行符或空格分隔的整数组成,例如:
0 0 2 0 1 0 1
在线尝试!
例
让我们以上面的示例为例(堆栈向右扩展):
0020101pop 0 and apply (ie. push single X):again simply push X:pop 2 (a,b) and push a (b X):simply push X:pop 1 (a) and push a X:simply push X:pop 1 (a) and push a X:[X][X, X][X (X X)][X (X X), X][X (X X), X X][X (X X), X X, X][X (X X), X X, X X]
最后评估堆栈:或带较少括号的X (X X )(X X )(X X )((X (X X)) (X X)) (X X)X (X X) (X X) (X X),我们认为这是旧的标识功能。S K K
图灵完整性
证明思想
为了使XOISC完全图灵化,我们需要能够翻译任何(有效)括号和组合符的交织。这是可能的,因为在弹出,应用和推动时,它是以右关联的方式进行的(功能应用是左关联的)。X
要转换任何这样的表达式,有一个简单的方法:总是弹出尽可能多的元素,以便从当前括号级别的开头开始只剩下一个元素。X
例如,先前使用的表达式:((X (X X)) (X X)) (X X)
- 要获得,我们只需要一个X
0
- 下一步,我们将圆括号放到新的高度,因此我们只需要一个
0
- 现在两个圆括号都关闭了,所以我们需要弹出2个元素:
2
- 同样,我们处于新的括号级别,因此我们需要
0
- 两个括号,再次闭合
2
- 并再次相同
因此,我们最终得到了一个不同的(但在语义上等效的)XOISC程序:
0 0 2 0 2 0 2
在线尝试!
如果我们坚持这种策略,我们可以轻松地转换任何由X组成的表达式X坚持组合器为XOISC程序,该程序仅在堆栈上保留一个函数。
正式证明
鉴于SKI演算已经完成了Turing,我们需要展示两件事:
- 在X -combinator是用于SKI-演算的基础
- XOISC能够表示由组合器形成的任何表达式X
第一部分-证明引言中的三个相等性-非常繁琐且占用空间,也不是很有趣。因此,您可以在此处找到*。
第二部分可以通过结构归纳来证明,尽管更容易证明一个稍微强一点的语句:即,对于形成的任何表达式X组合器都有一个程序可以将该表达式作为单个表达式保留在堆栈中:
XXf gfg:
0
XF1…FNG1…GKfgf g
F1…FN G1…GK−1 (GK+1)fggff g留在堆栈上。∎
口译员
输入项
由于无类型的lambda演算需要我们为所需的所有内容定义自己的数据类型,因此解释器意识到教会数字很麻烦。 -这意味着当您提供输入时,它将自动将数字转换为相应的教堂数字。
例如,下面是一个将两个数字相乘的程序:在线尝试!
您也可以使用De Bruijn索引(例如,S
组合器\\\(3 1 (2 1))
(或λλλ(3 1 (2 1))
))将函数作为参数提供。然而,它也承认S
,K
,I
当然X
组合子。
输出量
默认情况下,解释器检查输出是否编码为整数,如果输出,它将输出相应的数字(除结果外)。为了方便起见,有一个-b
标志告诉告诉解释器尝试匹配布尔值(请参见最后一个示例)。
组装工
当然,任何低级语言都需要将高级语言转换为该语言的汇编器,您可以简单地使用任何输入(请参见上文),并通过使用-a
标志将其转换为XOISC程序,然后在线尝试!**
*如果链接断开,这篇文章中会有一个副本作为HTML注释。
**这会产生一个测试素数的程序,请在线尝试!