自指语句及其含义

5 提交 / 0个新回复
最新回复
自指语句及其含义

看来很多人都对那个能够自己打印自己源代码的程序感兴趣,真是感谢这么多朋友的热心帮助,使我们对这个自指过程的深一层次理解。
下面我想说说我提这个问题的原因和意义。

1、如何实现自指悖论?

我现在正在看《歌德尔、艾舍尔、巴赫》这本书的第二遍,这是一本讲自指怪圈的书。我一直试图想明白一个问题就是,究竟什么是自指?我们有多少种创造自指的方法?我们都知道语言中存在着自指,但是为什么计算机程序、元数学中都存在着自指呢?

“这句话是错的”   -  (*)
是一个最简单的自指语句,然而他的含义是什么呢?是把这句话的整个儿作为一个整体放到他自己内部的一部分。

但是,这个自指语句的一个最大缺陷,就是什么是“这句话”呢?我们人类自然能理解它的含义了。然而,转化到计算机语言中是什么呢?也就是说什么是计算机语言中的我的含义呢?你能定义一个变量或者一个函数,它就可以看作是计算机程序的自我吗?

然而,当我看那本书的时候,得知了歌德尔的确找到了这种在数论中谈论自我的方法,这个方法就被称为对角线法,后来的图灵停机问题还有自我繁殖的病毒都是采用了这种方法。具体就是采用下面的方法避开直接的说“这句话”,例如下面的语句:

“放到引文后面得到假句子”放到引文后面|得到假句子 -- AB

注意我在上面那句话的中间打了一个|分成了两部分,前面一部分称为A,后面一部分为B。整句话就是AB,那么A就相当于第一句话中的“这句话”。为什么呢?我们先来看这句话:

“123”放到引文后面  -- C

这句话的含义是得到一个新的句子:“123”123,显然它什么含义都没有。请注意,C这句话实际上包含了主语和谓语两部分,主语是“123”,谓语是放到引文后面。因此求这句话的含义就相当于是谓语对主语进行一次操作得到了C的含义:“123”123

同样的方法把C中的123替换为“放到引文后面得到假句子”,也就是这句话:
“放到引文后面得到假句子”放到引文后面,

那么执行这句话就是:“放到引文后面得到假句子”放到引文后面得到假句子。
看!这里我们得到了与AB一模一样的句子。所以AB这句话的含义就相当于在说:这句话是假的,或者我是假的。所以A其实就相当于是“这句话”这一含糊不清的东西。

2、方法的含义
(1)得到一个两层嵌套的东西
这种避开使用这句话而实现自指的关键就是利用了“放到引文后面”这种动词形式。因为它是动词,所以它就可以在“运行时”执行,也就是把“123”放到引文后面展开。所以一个静态的句子“放到引文后面得到假句子”放到引文后面 中并不包含任何奇妙的东西,但是一旦你执行它,它就经过一次运算而形成了一个自指。

这样一来,自指语句就可以利用机械的方法来构造,也就是可以用计算机生成了。在dapplehou的短小精干的程序:
String a = "String a = ccc a=a.replaceFirst('ccc',a) System.out.println(a)";
a = a.replaceFirst("ccc",a);

这句a = a.replaceFirst("ccc",a);就相当于是“放在引文后面”,而wilddog的main函数,我写的那个Jake(String s)函数都相当于是这个动词。

当然不是任意一个动词或函数都能帮助实现自指。关键就在于这个动词和函数能够生成“两层”世界,即一个引文和正文并存的语句。我们来一个一个地分析。

首先,看"放在引文后面"这个动词,为了叙述方便,我们把它写成函数:F(S)=把S放在引文的后面。其中S为一切带有引号的字符串。那么如果设S="123",那么得到:
"123"123
如果把引号外的123看作是123这个东西的实物,那么引号内的123就相当于是这个实物在引文空间中的影子。所以"123"123就是一个事物和他的影子的并存体。

再来看dapplehou的程序,把a换成一段更简单的,如a="'ccc'okok",那么执行a=a.replaceFirst("ccc",a)得到:a为新的字符串:
"'ccc'okok"okok
同样okok同时出现在了引号里和引号外。(然而ccc在这个例子里不太好处理)

另外我的程序中的Jake(s)函数和wilddog的main函数都是这样一种函数,它的作用是同时打印一个字符串以及该字符串的引文。

我们把放到引文后面和Jake(S)函数和main函数以及a=a.replaceFirst这些函数统统看作是一个可计算的函数F(x)
(2)代入
有了F这个函数我们就相当于具备了制作自指语句的机器,接下来就是要填入适当的材料。首先,F是可计算的函数,这就意味着F自身也可以被编码成一句话或者一段数据。于是我们可以把F的编码代入到F自己里面来形成自指。也就是F(F)就是我们要的自指。
例如,F为放在引文后面,那么F这个函数的编码就是“放在引文后面”这个字符串。于是F(F)就成为了:
“放在引文后面”放在引文后面  (X)

注意,这个结果恰恰就是F(F)的计算结果。当你执行这个语句的时候,你仍然得到他自己,所以它正在谈论它自己!

在程序中也有类似的F(F)这样的结果,也就是把replaceFirst, Jake,Main这样的函数源代码代入F中。
(3)附带
代入的时候我们不仅能把F代入,也可以代入更多的东西,例如“放在引文后面得到假句子”放在引文后面得到假句子这句话,可以写为F+T(F+T),其中T为得到假句子。
再如程序中的print语句,function等等定义都属于这种附带的数据。其结果就是根据不同的附带,我们能够得到更多的逻辑上的自指结果。

3、引申
看来这些结果不仅意味深刻,而且存在着很多的潜能。人们早先用此方法来研究逻辑推理的极限,因而有了歌德尔定理,然而现在我们还可以用这套逻辑构造某种意想不到的东西。例如自我打印、自我复制的程序等等。我们能不能用这种方法定义更多的函数呢?例如能够自我毁灭的函数,能够自我归纳的函数等等。
似乎感觉如果这一点上突破了,那么很多自指相关的现象都可以描述了。