资源描述
Inception:一场层层调用的函数大战(发表时间:2023-09-09 18:14:17) 收藏(0)
· 标签: 原创 意识 电影 计算机
· 分类:心理
就有这么凑巧的事:上周还在看侯世达 (Hofstadter)先生的《集异璧》,这周就在电影院里看到了书中概念的演绎版——哈,说的当然是日前火爆酷炫的高分电影Inception啦。废话少说,赶紧剧透。还没看过的同学们海涵了,虽说透穿了剧情也不会影响你观影的效果。
Inception抓人眼球的是它“梦中做 梦”和盗梦的情节设计。在层层进一步的梦境里,人的意识逐步放松警惕,入侵者便可以趁机盗走储存在大脑中的信息。控制梦中的意识,“我做你的梦”,两个 人的思想在同一个大脑中争斗……这都是令人看得过瘾的狂野想象。然而身为一个业余程序员和《集异璧》忠实读者,看到人在梦里死了掉进迷失域(limbo) 再也出不来,我第一反映还是忍不住叫出来:“哇,堆栈溢出!”
堆栈是一个计算机术语,我看来看去,觉得Cobb这群人在剧中完毕任务的方法就像出自程序员的手笔。你看每个梦,都是同样的一组人物,抱着同样的目的,只是换到了不同的场景里。这多像一个函数调用的过程啊。
也许你没听说过函数调用,但你也许炒过青菜。 通常我们会先热锅、放油,然后爆炒、加盐、出锅。那么从热锅到出锅的一整套动作就可以写一个名为“炒”的函数。假如我们为白菜调用这个函数,就完毕了“炒 白菜”的任务;假如为空心菜调用这个函数,就完毕了“炒空心菜”这个任务。你还可以自由发挥,为各种包菜、韭菜、胡萝卜调用同一个函数,就把它们都炒了。
Cobb先生当然不在乎炒的是什么菜,他的任 务是在Fisher的脑中播种下拆分公司的念头。他为Fisher先生设计的函数就是梦,让Fisher的潜意识崩溃的梦。在计算机程序中,一个函数内部 可以调用另一个函数,在第二层函数运营的过程中,第一层的函数就在等待,直到第二层函数返回了运算结果,第一层函数再运用这个返回的值来继续它自身的运 算。这么一比较,Cobb的精心设计事实上就是用一个梦去调用另一个梦,上一层梦境中熟睡的人们都在等待下一层梦境中的人完毕任务。一旦成功,就用音乐或失去平衡的方式返还(在迷失域则是死亡),来结束上一层梦境。
就像程序员喜欢在函数中调用函数来使问题步步细化,这些嵌套在一起的梦也起到了步步逼近Fisher内心深处的作用。但是这样层层的调用也有个风险,万一信息链被破坏,函数不知道自己身处的是哪一层,事情就要乱套。这样就使得“堆栈”这个概念变得重要了。
在计算机语言里,“栈”是内存中的存储区,它保存着正在运营中的程序的临时信息,在程序完毕后就被新的程序信息覆盖。“堆栈”就是向这些存储区写入信息,好让系统知道现在哪个函数在等待返回值,以及返回来的值要到哪里去读取。
但是计算机的内存容量是有限的。当函数调用的 层数过多,新调用的函数信息在写入内存的时候空间不够,就把一些老的信息覆盖了。麻烦的是,被覆盖的那层函数还在等待下层函数的返回值来完毕暂停的任务。 这样虽然新的函数成功运营,老函数却没法对的找到返回值,整个程序就犯错了。这种由于空间不够而产生的错误覆盖,就是开头提到的堆栈溢出。
这和情节有什么联系呢?当然有啊,Cobb的 老婆Mal不就是堆栈犯错的受害者嘛。根据影片情节设计,Mal在迷失域中就由于待得太久而失去了对现实的记忆。她一直在最底层的函数里,却认为活在最顶层的现实,不需要返回到任何地方。而Cobb的“栈”还是完好的,他还记得 现实中的孩子,知道应当返回到顶层去。
这个时候,假如Cobb直接带着Mal卧轨, 不和她说那些有的没的,两人也许就安全地从底层返还了。但是Cobb犯了个错误,他对Mal的潜意识进行了修改,这就相称于故旨在Mal的“栈”里放置了 错误的但是故意义的数据。这样当Mal回到最顶层的现实时,本来整个大程序应当宣告结束,但由于她的“栈”被改写了,这个程序就错误地认为自己并不在顶 层。于是Mal就失去了对梦境和现实的分辨力,觉得自己应当再死一次才回到现实。
“悲剧啊!”看见Mal坠下高楼,我不由叹息,一出内存犯错的惨剧。
与其说这是一部关于梦的科学幻想,倒不如说是 运用人类的算法对意识进行的一次设计。据说影片的灵感有部分来自侯世达先生的《集异璧》。这是本涉及甚广的奇书,试图综合各学科的知识来探讨意识的机制。 侯先生虽然也不能完全回答自己提出的这个问题,但他猜想意识的关键之处在于“我”这个概念的产生。而这个概念来自自我和外界的区分,来自人类和外界不断的 信息交流。于是对“我”的认知从出生时起就一层层叠进脑内,这种交流积累终其一生循环往复。书中曾把这个过程类比于函数对自身进行循环调用,那么影片中的 故事设计与计算机原理相似的情况倒也不太出乎人意料。
咦,那么有没有也许,导演在试图把计算机科学的知识植入到我们的潜意识里面?银幕前面的你,被他的Inception施中了吗?
========
注:已发于《开啦》电子杂志,此处为修改版。写作过程中参考了凍啡走甜的博文,Albert_JIAO和白鸟老师提供了非常好的修改建议,特此感谢。
附:《盗梦空间》,这编剧是个程序员吧?(发表时间:2023-09-13 15:26:56) 收藏(0)
· 标签:
· 分类:无
在看片子之前就看到了松鼠会的那篇文章(《Inception:一场层层调用的函数大战》),当时觉得这个角度挺新奇。周末去看了片子之后发现,从这个角度去解读相称合理,这个编剧整个就是个程序员嘛,片子中的很多东西都可以用程序概念去解读。
用函数调用的概念来理解层层叠加的梦境,用异常解决的概念来理解迷失域的存在,用事件模型来理解kick的传递……在程序员眼中,《盗梦空间》是个挺精彩的程序世界。
=======================================================================
为了避免后面讨论时出现歧义,先定义一下各个层面。现实,称为第0层或者顶层。从现实进入的梦境,称为第1层,从第1层进入的梦境,叫第2层,接下来从第2层进入的叫第3层……
此外有一个特殊的梦境limbo,这个不按照层面来定义,这个后面会此外说。
每一层面要有一个人负责建造出整个梦境,这个人我们称为造梦者。关于造梦者,有几个事实:
● 每一层面要有一个人负责建造出整个梦境,这个人我们称为造梦者。
● 造梦者一旦离开这一层面(比如返回上一层),本层立刻开始崩溃。
● 造梦者也不能离开这一层面进入下一层,这是上一个结论的自然推论(要留下来维护本层面不崩溃)。
关于退出某层梦境,按照片子里情节来整理,有以下方法:
● 镇定剂时间到,自然醒来。这可以参照cobb带着女人进行第一次梦境课程的情况。这就是程序运营结束自然退出。
● 在梦境中死亡(有前提条件),强行退出本层梦境。这种情况片中多次出现,比如cobb带着女人进行第二次梦境课程,女人就被mal杀掉而强行退出。用程序设计的观点来看,这不就是函数内在满足特定条件时提前return么?
● 造梦者本人是可以积极控制退出的(不是很明显,可以参照第一次出现双层梦时的第一层退出方式。以及女人自作主张进入cobb梦境之后他们从宾馆房间场景逃回现实的情形)。同时,造梦者一旦退出,梦境里的所有人会同时跟着退出。但是有一个前提,即造梦者退出时梦境里的所有人其积极意识必须都在本层面才干正常跟着退出,否则会导致很可怕的结果。片子里似乎没有明确说明,应当是掉进limbo。
==========================================================================
好了,下面进入正题。
一方面层层梦境可以当作层层函数调用来解决,这个松鼠会那文已经展开不少了,不反复。
==========================================================================
但是单纯从这个角度会有一些问题不好解释,比如说,limbo迷失域。
迷失域这个地方一方面明显不受层次限制,seito在第1层中枪,其别人说他死了会进入limbo。而事实上seito和fishche都是死在第3层,但是他们还是进入了limbo。
迷失域的返回情况也很奇怪。fishche和救他去的女人从迷失域返回都是到了第3层,而cobb与seito显然不是,由于其别人返回第一层的时候cobb还没返回(这时候第2层和第3层早已经消失,由于造梦者已经退出了),而最后cobb和seito返回现实的时候其别人都是清醒的,也就是说他们早就回来了(也就等于第1层也已经消失)。这就意味着cobb和seito绝对不是层层返回的,而是直接从limbo回到现实的。
在梦中死亡也会有不同的结果,大部分时候会自动回到上一层,但是seito和fishche的结果他们又掉进了limbo?这个区别自身可以用栈来解释, 正常情况下梦中死亡会自行按照栈信息返回,但是最后那个多层梦中由于镇定剂太猛了,梦中死亡后没有积极意识去维持栈信息,潜意识又抵抗但是镇定剂,于是死 了之后栈信息就消失了,无法正常返回。但是这个结果很奇怪——缺少栈信息为什么掉进limbo,而不是更简朴的直接返回?
该怎么办呢?
这里可以用程序设计的此外一个重要概念来帮助解释,那就是Exception,异常。
我们可以认为,在梦境里假如死亡了又无法正常强行返回(缺少栈信息)时就会抛出一个异常,而limbo,就是默认的异常解决模块。
这样事情解释起来就很简朴了。异常的抛出与捕获都不受调用层次的影响,无论在哪一层抛出,捕获后都丢进同一个异常解决模块去解决。这就解释了为什么seito无论死在那一层,都是进入limbo。
异常解决机制捕获异常并启动异常解决模块解决完毕之后一般就直接退出程序,而不会再尝试从发生异常的地方再层层返回。这可以解释为什么最后cobb和seito可以直接回现实,由于seito是从异常解决模块返回的。(cobb是正常进入的,但是只要他清楚自己在干什么,也可以直接返回现实,写程序也有exit语句不是?)
异常解决模块自身也是一个模块,所以也可以积极去调用,并按照正常的调用模式返回。这就是cobb带着女人最后去救fishche的那码子事,所以fishche获救之后是返回到第三层而不是同seito同样直接回现实。积极调用也也许不按正常模式层层返回,cobb就是,他直接exit跳出了。
在综合假如不加干预就会在limbo里出不来这个情况,甚至可以把这个异常解决模块的重要执行逻辑都构建出来:
while(!知道自己在梦境中){
继续做梦;
}
做自己认为需要在limbo梦境中完毕的事情;
return;
哈哈,我真无聊。但是这个执行逻辑可以解释为什么cobb和女人进入limbo之后都可以正常返回,由于他们自己知道自己在梦境中。为什么他们可以让mal与fishche与seito返回,由于想办法让他们知道了他们是在梦境中,从而打破了前面的那个无限循环,然后就可以返回。
=========================================================================
然后来看kick。总结影片内容之后可以发现:
● kick可以用来从上层往下层传递信息。
● kick不一定会导致下层里的人返回。
● 下层的人一般接到kick之后会做出一些反映,最常见的就是退出,返回上层。
● kick不一定会逐层传递下去。
这些特性是不是很眼熟呢?程序员们应当会注意到,这主线就是个事件系统嘛,kick自身就是一类event,其实上层发生的各种事情都可以看作event,比如播放音乐、身体有移动,甚至镇定剂时间到……
event产生了之后就会传递到下层,那么下层的人接受到这个event之后可以又不同的反映,比如:
● 忽略之(第一层撞破护栏的时候)
● 退出返回(最常见的)
● 传递event(有也许是新的event)到下层去(注意到最后的音乐同步问题了吗?音乐为什么不受层层时间速率放大叠加的影响?由于每层都是重新传递的)
● 其他……
所以kick并不是直接唤醒下一层的人,只是传递了一个足够强的事件进去,让下一层的人知道情况紧急,必须返回。因此在第三层爆炸之后,limbo里的女人还需要跳楼,而cobb又可以继续留下,前者是选择执行了返回操作,后者则选择了忽略。
===========================================================================
到这里,重要的事情已经说完了。下面是一些其他关于这片子的唠叨。关于这个片子的讨论很多,其中绝大部分都不是问题,至少我认为都可以解释的通,并且其中绝大部分片子里都有给出隐藏的线索交代。比如seito和cobb在梦中相遇的年龄问题;失重从第一层传递到第二层但是为什么没有传递到第三层之类的。这些不是本文的重点,不罗嗦了。哪天假如又无聊了我也许会写个《答疑》之类的补充……
唯一想说一下的就是结局。
最后是现实还是梦境?
基于实证主义原则,只要和已有证据无冲突,任何说法都是对的的。而唯一可以确诊的证据在结尾没有呈现出来(陀螺是否倒了?)所以可以认为两种说法都是对的的,看你喜欢哪个。庄周梦蝶式的哲学讨论不是我所喜欢的……
但是全片总体来说在逻辑上相称严密,假如认可这一点,那么最后的结局合乎逻辑的推论就应当是,cobb回到了现实。好在有此外一个很有趣的原则:奥卡姆剃刀!
所以,我认为,最后是现实。
一个线索暗示,也是一个巨大的剧透:抛掉cobb在第一层梦境中对女人讲述他与mal之间发生了什么时的那段回忆情节不考虑,以及最后有争议的回到飞机后那一部分,其他部分(也就是所有“现在”所发生的事情),都遵循统一的规律:在梦中的时候cobb戴着婚戒,而现实中不戴。假如认可这个不是偶尔,那么再去对照最后情节中cobb的手,就可以得出结论。
展开阅读全文