宇宙的零成本分裂

非肯定性计算,就是科幻小说里的平行宇宙。反过来讲更合理一些。不过,以为一上来就说非肯定性运算,颇有气质……html

Murphis 手里的红药丸与蓝药丸,Neo 选择了前者。这是单个宇宙里的计算。对于平行宇宙而言,当 Neo 选了红药丸的那一瞬间,宇宙分裂成了两个,在另外一个宇宙里,Neo 选了蓝药丸。git

在两个宇宙里的 Neo 选了不一样颜色的药丸以后,他们接下来还要作更多的选择,就会致使宇宙不断分裂。假若从 Neo 选择药丸的那一刻开始,结果会获得一棵根深叶茂的宇宙树。github

之前我说过,只要有选择,这就意味着选择者已经落入了一个已经编制好的程序里了 [1]。既然是程序,那就得有运行结果,不然就是死循环。所以从根宇宙开始,向叶宇宙走,位于最长的路径末端的叶宇宙是笑到最后的宇宙,它能够做为这个程序的运行结果。这个叶宇宙,就是咱们看过好几遍的《黑客帝国》。segmentfault

这就是宇宙规模的非肯定性计算。函数

因为我不相信我活在一个编制好的程序里,因此平行宇宙就的话题就此为止。不过,非肯定性计算倒是一个值得探究的话题。透彻地理解它,至少对于任何单机游戏的通关有帮助。由于基于非肯定性运算,可以算出单机游戏通关的全部路径。有了这个技能,也能够在街头摆个摊,给那些认为本身生活在一个单机游戏里的人算算命。code

为了更为直观且精确地表现非肯定性计算,须要构造一个例子。先来看一个肯定性的计算过程:htm

if (Neo 选了红药丸)
  《黑客帝国》
else
  导演不拍了

这个计算过程是,假若 Neo 选了红药丸,咱们就有《黑客帝国》能够看,不然导演无法拍,拍了也没人看。游戏

如今,咱们将计算过程倒过来,就是电影是必定要拍出来的,而后让 Neo 按照这个要求去选药丸:事件

if (Neo 从 (红药丸,蓝药丸) 做选择)
  《黑客帝国》
else
  导演不拍了

这样一来,对于 Neo 而言,他面临的就是一个非肯定性计算的问题。他要解决这个问题,就只能让宇宙去分裂……咱们不关心 Neo 如何选择,只要他做出的选择可以保证拍出《黑客帝国》这部电影便可。get

假若对续延 [2] 有所了解,如今想必在上述代码中已经看到了续延:

if ([])
  《黑客帝国》
else
  导演不拍了

续延里的洞是个黑洞。包含这种洞的代码结构会掉进这个洞里,再从洞里掉出来一个值。因为咱们要求必须得拍出《黑客帝国》这部电影,所以从这个洞里掉出来的必须是《黑客帝国》。洞外之物决定了洞内的 Neo 的选择。假若 Neo 选了蓝药丸,洞外之物决定了他的选择会致使导演不拍了,因此 Neo 就试着再选择红药丸,因而《黑客帝国》就拍出来了。

因此,黑洞未必真黑。外围的世界彻底能够决定黑洞里面的事。为了展示这一点,我须要用 Scheme 语言从新描述上述过程:

(if ([])
    《黑客帝国》
    导演不拍了)

接下来,看一下洞里必须发生的事是什么:

(if ((call/cc
      (lambda (cc)
        (if ((cc '蓝药丸) 《黑客帝国》)
            《黑客帝国》
            (cc '红药丸)) 
        )))
    《黑客帝国》
    导演不拍了)

在介绍阴阳谜题 [3] 的时候,已经说过了 call/cc 的做用,它能够在表达式里挖一个黑洞,再在这个黑洞里布置一个函数来处理掉入洞中的东西。

call/cc 布置的黑洞里,Neo 必须对药丸们逐一进行选择,而后看看续延的求值结果是否是《黑客帝国》。这里因为只有两种选择,因此,黑洞里只须要用 if 语句就能够涵盖它们。

洞内发生的计算就是非肯定性计算。虽然它在形式上与一开始的肯定性计算没有本质上的不一样,可是它却很好的模拟了「宇宙分裂」。不少人以为随便一我的选择是吃米饭仍是吃面条这种破事就让宇宙分裂一次,成本过高了。如今看到了吧,有了续延,这种事基本上是零成本的。

续延不只下降了宇宙分裂的成本,并且它还能响应洞外的事件的变化。例如,如今要求 Neo 选择蓝药丸才能拍出《黑客帝国》,上述代码不用修改,依然可用。由于咱们一开始就已经假设了,无论洞内发生了什么计算,反正得知足洞外的需求。

有了上述认识,接下来再去看 [4],可能就不那么一头雾水了。


[1] 红药丸,仍是蓝药丸
[2] 续延,有什么难的……
[3] 三生万物
[4] Scheme 里的非肯定性运算

相关文章
相关标签/搜索