神经系统中的很多子系统都以敌对的方式存在,每个子系统都希望以自己的方式行事,彼此之间常常会陷入拉锯战。例如,我们的各种情感会为了取代对方而不遗余力地相互展开疾风骤雨般的对抗,有时候它们也会结成联盟来阻挠自己的劲敌开展行动。现在我渐渐明白,人类各种情感之间动态的对抗过程,以及情感对我们思想的影响,都是以协调单个神经元相互竞争天赋的神经化学系统为基础的。值得注意的是,不像是那些本质上就极为自私的行动者,比如癌细胞,从一个更广阔的运作范畴来看,神经细胞还算是不错的团队成员。
我记得诺贝尔奖得主、生物学家弗朗索瓦·雅各布(Fran?ois Jacob)曾说过,每个细胞都梦想着能完成分裂变成两个细胞,只有神经元不图繁殖,一心只想着要保持活力、有所作为。按照这种观点,对动物行为的智能控制是一种计算过程,就像在股票市场里完成一次交易那样。但正如神经科学家塞巴斯蒂安·承(Sebastian Seung)所说,神经元也是自私的,它们总是会倾其所能,最大程度地吸纳能在我们的大脑中获得的所有酬劳,这些酬劳以不同的“货币形式”出现。那么神经元利用多巴胺、5-羟色胺还有催产素都买了些什么呢?它们购买的是更加强大的影响力,能让自己在所处的连接网络中变得更加可靠。骡子虽不能生育,但它们仍会努力地营生。同样,神经元也有自我保护的本能,本质上,这是从它们可繁殖的祖先那里遗传下来的。
受神经科学的启发,作为大脑运作的一种模式,那种自下而上的小人儿式机械主义真是让人越看越觉得合理,因为从生物学的视角看,它生成的更加错综复杂也更有竞争性的“计算体系”是更合理的:我们可以看到它整个的发展历程,从胚胎直到成人,在这个过程中不断建构和修改。我们也可以看到,这种复杂的体系结构是如何从简单的神经系统发展而来,由那些未成熟的小人儿组合而成,那些小人儿有着“近似”于感知、标记和记忆的能力。 (34)
21
近似算子
达尔文渐进主义的启示
为
什么我要沉湎于这种对于“近似”(Sorta)的讨论呢?因为一旦要对各层级的功能运作做出分析或综合评价,我们就需要针对那个层级,追问这两个问题:它是什么?它都做些什么?“它是什么”是指其组成部分的结构组织,前提是这些组成部分都能如我们假设的那样发挥它们的功能。“它能做些什么”是指,它可以将一些近似认知的功能实现得很好,让我们能在一个更高的水平上安心工作,因为我们相信脚下踩着的这块基石一定可以很好地发挥自己的功能、被很好地利用。它为“思想怎样由物质机制构成”这一出奇复杂的问题中最难攻克的那部分点出了关键性的一笔。
其实早在计算机发展的黎明时期,当之无愧的计算机创造者阿兰·图灵就展望到了这一幕。他从不掺杂任何智力因素的机制片段入手,将它们组织成能力更强大的机制结构,这些强大的机制结构又可以进化得更为强大,如此下去,看不到尽头。在认知科学中,我们会将近似算子看作是达尔文进化论中渐进主义的一种平行理论(在第五部分中会有更加详尽的阐述)。有细菌之前会先有近似细菌,有哺乳动物之前会先有近似哺乳动物,有狗之前也会先有近似狗的动物出现,如此等等。
要弥补一只猿猴和一个苹果之间的巨大差异,我们需要借助达尔文的渐进主义理论;而要弥补一部人形机器人和一个手动计算器之间的巨大不同,我们需要借助的是图灵的渐进主义理论。构成猿猴和苹果的基础成分都大同小异,不同的是这些成分的构造方式,还有各个层级的功能对它们的开发利用。近似猿和猿在原则上并没有什么明确的划分。人形机器人和手动计算器也是由相似的基础部件组成,它们都是些无思想、无感觉的图灵程序块。把这些程序块视为组成部分,放到更大的功能结构中,再组合成更高层次的结构,以此类推,到最后我们能得到这样一些部件,它们拥有近似智能,能组合成被称为“理解”的那种能力。
而现在,我们从意向立场出发,开始追溯每一层级上近似理性行动者的信念和欲望,或者近似信念和近似欲望,从最简单的细菌到动物,从海星到天文学家,追溯组成大脑的识别、标记、比较和记忆回路。但即使追溯到人类这一层级,我们也没能明确地找到真正形成“理解”的那个点。当那位小朋友说“爸爸是一名医生”时,她近似明白自己所说的那句话,我也近似理解“E =mc 2 ”。某些哲学家抵制这类反本质主义的理论(见第43章):你或者认为雪是白的,或者不那么认为;你或者意识到了,或者意识不到;没有什么所谓近似的心理现象;要么就是,要么就不是。对于这些思想家来说,思想的力量永远神秘莫测,它是“完美的”,绝不是什么仅凭物质机制就能造就出来的东西。
22
神奇组织
不要为逃避难题而求助于“魔法”
李
·西格尔(Lee Siegel)有一部关于印度街头魔法的杰出著作叫作《魔法网:在印度的奇观和欺骗》(Net of Magic: Wonders and Deceptions in India ),他在其中这样写道:
当我说“我正在写一本关于魔法的书”时,便会有人问:“是有关真正的魔法吗?”人们常常将真正的魔法理解为神迹、奇迹般的行为或者超自然的能力。我说:“不,只是些小伎俩,不是真正的魔法。”换句话说,真正的魔法不是真实存在的魔法,那些可现实操作的、真实的魔法不是真正的魔法。(Siegel, 1991, p. 425)
按照定义我们会说,“真正的魔法”不可思议,与自然法则相悖。很多人愿意相信真正的魔法确实存在。但魔术师、怀疑论者、驱魔师神奇兰迪(the Amazing Randi)却成功地复制了尤里·盖勒(Uri Geller)这些自诩巫师者的魔术,他想向世人证明,那些惊人的效果并不源自真正的魔法,它们都只是些戏法而已。不过,这并没有说服所有人。多年前,兰迪在温尼伯曾有过一次演出,在节目之后的问答环节上,一些观众便开始控诉他,说他其实是在双重欺骗:你和盖勒一样都是专业巫师,你拆穿盖勒的魔法,只是想让人们觉得,只有你才是真正的魔法师,这样就可以乘着盖勒的东风收获更多的名誉和财富。这些质疑莫名其妙,但兰迪却很难反驳,除非他能给在座的观众澄清这些戏法的原理。可兰迪尊重魔术界的世界惯例,他不愿意那么做。魔术师组合佩恩和特勒(Penn & Teller)曾经倡导要揭露魔术中的秘密机关,于是顶着魔术师同僚们的谴责,他们在魔术表演的同时,揭露出魔术背后的秘密。
就像很多人热切希望有真正的魔法存在一样,这种希望也折磨着很多人对思想与大脑之间关系的考察。不少神经科学家、心理学家,甚至是哲学家,潜意识里还是会被这样的观念吸引:神经组织中的动态属性可以利用某种科学无法解释的潜在力量,做出一些让你觉得神奇的事情。也许他们的想法没错。但我们不能一开始就这样假设,我们的前提条件必须是:没有什么神奇的组织!
有些东西是可以绝对肯定的:在计算机程序中,没有什么东西是在物理上无法解释的;没有什么难以想象的力场,也没有什么神秘的量子论诡计,更没有什么“生命冲动”(élan vital)。不可否认,计算机中没有神奇组织。我们清楚地知道那些基础任务在计算机中是怎样完成的,我们也知道它们是怎样一步步地组合成为越来越复杂的任务的,在解释这些功能建构时不需要添加任何神秘色彩。现如今,对于计算机表现出的那些精湛技术,我们常常是赞不绝口,但尽管如此,作为一部机器,计算机对我们来说和一个开瓶器并没有什么差别,都一样平凡又熟悉。它里面没有什么“真正的魔法”,都只是些戏法!
这一事实非常重要,我们在下一章还会详细讨论。它的价值在于:无论计算机做出了什么看似神奇的事情,我们都有证据表明它无需借助神奇组织。也许大脑采用的是另外一种运行方式,也许它真会用到一些神奇组织,也许兰迪和盖勒都是真的魔法师,但我们还没有找到合适的证据。所以说,计算机在清楚解释事物方面扮演着非常重要的角色,不管是飓风、房地产泡沫、艾滋病病毒,还是人类意识,在理解事物时,我们有充足的理由要首先去开发它们的计算机模型。
神奇组织这一概念作为一件思考工具,它的功能类似于警察的警棍:你拿警棍惩罚别人,警示他们不要使用不正当的理论。当然,就像你可能滥用警棍一样,你也可能滥用这个概念。神奇组织这件思考工具与“奥卡姆剃刀”有相似的作用,所以它同样会引发一种系统式的保守主义,令人缺乏开创性和前瞻力。现代遗传学的创始人之一威廉·贝特森(William Bateson)清楚地说明了这一点,我很喜欢他的这个例子,以下就是他在1916年说过的那段话,时间还没有过去很久:
生物的特性在某种程度上是依附于它的物质实体的,或者也一定程度地取决于核染色质(染色体)。神奇的是,不管这些物质实体或者染色体粒子有多复杂,它们都拥有传递我们的特征和种族(基因)的力量。我们可以推测,染色体的粒子虽然彼此无法区分,几乎在所有已知的测试中都是同质的,却可以凭借自身的物理特性赋予新生命所有的特性,其能力远远超出了最深得人心的唯物主义理论的解释。
当然,贝特森想不到还有DNA的存在,人体的每一个细胞中都含有包含着三十亿个碱基对的双螺旋,这超出了他的想象。而幸运的是,不是所有的生物学家都如贝特森一般悲观,他们始终在研究,遗传信息是怎样通过一些神奇的微粒代代相传的。在探索道路上,这些生物学家们一直坚持“没有神奇组织”的原则。从遗传学角度看,对于自己研究对象所具备的各种能力他们早已了如指掌,剩下的任务是尽可能地做出一个物理模型,让它也同样具有类似的能力。
如今,我们也面临着同样的任务。实验心理学已经为我们提供了一张有关心灵能力和弱点的十分详细的列表,其中显现出了成功的知觉和失败的错觉,说明了语言学习的步骤,还包括造成注意力分散、欲望、恐惧及欢乐的各种条件。而现在,作为“深信不疑的唯物主义者”,我们需要向大家解释清楚大脑是如何做到这些的,不能借助神奇组织。
随着理解的不断深入,我们对神奇组织的看法也在改变。20世纪80年代中期,“联结主义”和其他一些“神经网络”模型的突然出现 (35) 展现了小束神经元的学习能力和图形识别力,而就在几年前,这根本就是无法想象的。虽然我们仍然不知道大脑是如何产生这些理论模型所展示出的计算能力的,甚至不知道大脑是否真的是像这些理论模型描述的这样工作的,但至少我们现在可以假定神经网络有某种连接能力,只要设定的这种能力不超出应有的界限范围。作为前提,我们无需对此多做解释。兰迪不可能完全照搬盖勒的魔术,但我们可以就此得出结论,兰迪的表演多多少少可以解释盖勒的伎俩,这就给我们更深入地探索实际发生的过程指明了方向。反对神奇组织的主要理由是:它提供给我们的是一种逃避问题的方法,而不是一种解决问题的方法,因为神奇组织预设了这是一个根本无法解决的神秘问题。
23
身陷机器人控制室
初长成的大脑不是一块“白板”
根
据定义来说,机器人没有神奇组织,所以它们可以为思想实验提供一个纯净无干扰的平台,我们可以举出这样的例子。
一天清晨,你醒来后突然发现自己身处在一个没有窗户、非常诡异的房间里,躺在一张从没见过的床上。屋内有两面装满了不同颜色的微型闪光信号灯的墙,另外两面墙上则布满了成千上万的按钮。信号灯和按钮上都写着数字,但没有标记出哪个与哪个相对应。在床边的桌子上,有人给你留下了一张字条:
早上好啊!我们麻醉了你,在你睡着的时候把你绑架到了这里。冰箱里有食物,角落处是盥洗的地方,在这里,你身体的各种需要都能得到满足。你现在是被囚禁在一个巨型机器人的控制室里,每盏亮起的灯都说明了大量有关机器人状态的信息,这些信息是由高度复杂的神经网络分析器根据机器人的高清视频眼、麦克风耳、触摸传感器和嗅觉传感器摄入的原始资料分析得出的。按钮控制着机器人的行动,已经调试好,随时可以使用。
机器人所处的环境非常险恶,危机重重,但也存在机遇。你掌握着它的命运,与此同时,如何控制这个机器人在世界中生存也决定着你的未来。机器人一旦毁灭,你房间里的电力系统也会全线瓦解,电冰箱里不再会有食物,你将面临死亡!祝你好运!
这真让人恶心!你提心吊胆地开始按动按钮,每按一下都要看看有什么事情发生。你按下了编号为4328的黄色按钮,随即,那盏编号为496的蓝色信号灯渐渐熄灭了。这是在让机器人挠痒痒吗?或者是让它闭上眼睛?又或者是让机器人“吃”了些东西,补充它新陈代谢的需要?你第二次按下4328按钮,分散排布的几盏灯亮了。世界会因此发生什么呢?这到底意味着什么?你焦躁不安,你知道这些信号灯蕴含的信息数量庞大,但却不知道哪盏灯与哪条信息对应,也不知道每个按钮都控制着机器人的哪些动作。
要是信号灯上和按钮上都有标注该多好!要是标注用的语言你还都能看懂,那么你就可能摆脱这些困扰。又或者,如果这间屋子有扇窗户,打开它能看到外面,那么在按下按钮后,你至少能看到外部世界相应的变化。这个机器人有胳膊和腿吗?假如有了这扇窗户,你还能试着将外面世界的活动与墙上闪烁的信号灯相互联系起来。而没有这扇窗户,尽管所有的信息也都摆在那里,但它们却不能构成任何解释。你可以让机器人做成百上千个动作,但却无法搞清楚这些动作对世界造成了什么影响。
现在,你进退维谷。因为,不管你有多聪明、多有想象力,即便所有信息资料都任你取用,你也很难说出发生在墙面上的这些到底表示着什么。但是如果你无法解决这个问题,那就很矛盾了,因为现在的困境不也正是大脑所面临的困境吗?大脑也是被困在了一个没有窗户的房间里,也就是你的头盖骨,成千上万的输入线路在忙碌着为它传入外部世界和你身体状态的相关信息,成千上万的输出线路在淡定自若地操控着肌肉的收缩和舒张。大脑当然不会在头盖骨上凿出个窗户,朝外看看周围发生了什么事情。凿开这么一扇窗户到底能让你的大脑得到什么好处呢?它跟你不一样,它没有自己的双眼,只能收容你眼睛接受到的信号或处理过的信息;至于这世上各种事物的样子,它也没有什么先天的记忆。
有些人并不觉得大脑的工作原理有多难,因为在看一只鸭子的时候,我们视觉皮层表面的激活模式,也就等同于那些闪着光的信号灯,就会形成一个鸭子形的图案。 (36) 好吧,但如果你的大脑和你一样,通过学习认识到了鸭子的模样,那请问,它到底是怎样学习到一只鸭子的模样的呢?
如果信号需要“解码”,你的大脑该怎样才能认识到事物呢?解码后的那些信号都变成了些什么?土耳其语?如果你不懂这门语言的话,土耳其语标签对你来说就毫无意义。所以,要从输入资料那里得到些有价值的信息,我们的大脑是不是得先懂得一门语言?之前有过这样一种观点,大脑无需后天学习,它自身就带有一种内部语言:心理语言(Mentalese),也就是思想语言(Fodor, 1975, 2008)。看起来,这个撩人的观点似乎能带领我们往正确的道路上再迈进一步,但是,除非能了解到它最初的成形过程及运作的诸多细节,否则“存在一种内部语言”这个观点只是给问题换了一个名字,并没有将问题解决掉。
我们知道,大脑总是在以某种方式解决问题,它可以果断地为输入信息造成的那些窘况或者机会找出适当的对策并且输出。我们也知道,大脑解决问题的方式绝对不是使用了一门语言,比如英语或者土耳其语,因为这种解决方式并不是像我们小时候学习母语那样学到的。或许大脑内部语言更像是书面语,由记忆在大脑存档中进行书写?又或者,它更像是纯粹的口语?它会有成千上万甚至上亿个“词语”吗?词语的排列顺序和意义有关吗?它有语法吗?大脑的某一区域能够准确地理解其他区域中的信息吗?
如果思想语言指的是封闭控制室里的一个小人儿所明白的那种语言,就像在机器人体内的操纵室里,你能读到信号灯和按钮上的标签一样,那么实际上,它是把“如何在由毫无理解力的部分组成的机制的基础上完成理解和学习过程”这一问题延宕了,根本没有给出回答。而如果将小人儿从思想语言的假设中取消掉,那么不管整个这套系统是什么,都跟语言没有多大的相似度了。而且到目前为止,还没有人对“思想语言是如何运作、如何在发育过程中产生的”这些问题给出过详细的说明,所以,也许我们不该再那样自欺欺人,不该再那样自我安慰地说,我们在这个方向上正在取得进展。其实我们一直都在原地呢!
这个直觉泵是想说明,困在控制室里的大脑和那时受困的你所面临的境况并不全然相同。对于大脑来说,输入的信息是与输出相连接的,大脑本身就拥有一些能力,知道要去认识什么,知道怎样才能使各种连接变得更加合理。这项任务是提前完成了的。这也以另外一种形式证实了那个广为人知的说法,初长成的大脑不是“白板”一块(Pinker, 2002),它已然经历了自然选择的雕琢,自身体现着各式的偏好、预设和衔联,而且,有些合适的连接是提前内置的,无需标注。
在理解产生之前,先要有一些不需要理解的能力出现,这是自然法则。细菌浑身都是超凡的能力,这些能力让它们过得很好,只是细菌无须去理解这些能力,它们是愚蠢的。树也有趋利避害的能力,但它们亦不必知道其中的缘由。自然选择的车轮滚滚向前,一路上造就出了无数精巧能干的事物,这个过程也不包含任何理解。
我们成年人类具有的那种理解能力是进化史近期才出现的一种景象,它是由一些结构组合生成,而这些结构所具有的能力应该也是由鱼或者蠕虫所有的那种类似理解力发展而来的。大部分时间里,这些结构发挥着应有的作用,但它们并不需要知道自己为什么会那样发挥作用。
而认为有一名发育健全的理解者被关在控制室里,面对着墙面上各种各样的输入和输出信息,这种观点注定是行不通的。为什么?因为如果这种理解力无法解释,那么我们就得建立一个神奇组织、一种神秘力量作为理论的基础。但是,如果这种理解力的运行过程是可以清楚解释的,是由一些不具备理解力的过程、活动和能力构成的,那么你又回到了解释理解力如何从其他能力中发展而来的道路上。既然如此,又何必绕这个圈子呢?
第三部分 关于计算机的思考工具
也许你们已经发现,我前面已多次提到计算机,而在后面的章节,我还会写到更多有关它的内容。今天,计算机无疑已经成为了我们最有力的思考工具,这不只是因为它们承担起了单调繁重的苦差事,解放了智力劳动,而且,计算机科学家们发明出的许多概念也凭借着自身的实力成为了极好的思想工具。
如今,我们整日都在计算机术语(例如硬件、软件、带宽或者千兆赫)的浪潮中浸泡着,所以我们想当然地就会认为自已对这类专业术语的理解绝对准确可靠。然而,直到在课堂上真正列出了几个这样的词语时,我才发现,虽然每个孩子也都装模作样地点着头,但他们对这些词的理解程度却实在是参差不齐,有时这些孩子们甚至会将我所传达的意思曲解到几近诡异的地步,以致我自己都被弄糊涂了。那么接下来,我首先想要教给大家的是,怎样为世界上最简单的计算机编写程序。
现在,如果你肯花费时间和精力去掌握一点基础的计算机编程技巧,那么你将会对我下面所说的这些有更深刻的体会,而如果你现在已经是经验丰富的计算机专业人士,那就希望我解释问题的方法能在你向普通人说明问题时发挥一点儿作用,或者跳过这一段也可以。我曾尝试对数百名有“计算机恐惧症”的本科生讲授下面的内容,效果不错:即使是那些宁肯背诵一整页电话号码也不愿意解决一道难题的人也不得不承认,能让一台超级简单的计算机按照我们的意愿做事是一件让人极有成就感的事。而当你完成了下文中的所有练习后,你就将掌握有关计算机能力的7个秘密。
24 计算机施展魔法的7个秘密
部分之和大于总体的最好实例
计算机隐藏的那种巨大能量一定会被几个世纪之前的人们看作神迹,看作“真正的魔法”。不过,尽管很多计算机程序都复杂得吓人,但它们全都是由一些基本的步骤组成的,仅凭几个简单的术语我们就能把这些步骤解释清楚。计算机上的运算从不夹杂任何神秘成分,作为思考工具,这正是它的重要价值之一,而且解释这件事儿本身就是一个很有趣的哲学问题。到底计算机是怎样施展它的“魔法”的?能在一个比较基础的层面上理解这个问题非常必要,这一章会提供给我们一些相关启示。
先从一台我们能想到的最简单的计算机——一台寄存器机开始吧,看看它有什么能力以及为什么它会有这样的能力。然后,我们再去考察图灵机和冯·诺依曼机。其实它们也只是一些更高效率的寄存器机而已,笔记本电脑能做的事情寄存器机也都能做,只是你得用它算上几个世纪。之后,我们才能慢慢地搞清楚,更高级的那些计算机“架构”如何在寄存器机这台本体机上增长了速度、壮大了技能,而人类大脑正是其中最重要也是最有趣的一种架构。
等一下,我从没说过“大脑就是一部庞大的计算机”,没有,一次都没有。我想说明的是,如果大脑真的是一部庞大的计算机,那么我们就一定能够找到一种方法将大脑所有的活动都解释清楚,不留下任何神秘色彩。我们采用的这种方法就是逆向工程:探究一个复杂的系统,分析它能做什么,是怎样做到的。逆向工程让我们知道了,心脏是如何像一个泵那样履行自己的职责,肺又是怎样收集氧气排放二氧化碳的。神经科学是逆向工程应用于大脑研究的一种尝试。我们都知道大脑能做什么:预测、支配、记忆、学习,接下来还需要我们搞清楚的是,大脑是怎样做到这些的。
这是个充满争议的话题。2000年,小说家汤姆·沃尔夫(Tom Wolfe)曾在自己的文章《抱歉,你的灵魂已死》(Sorry, But Your Soul Just Died )中详细描述过这一敏感话题,随即便引起了一场激烈的论辩。如果我们不想把时间都浪费在那些雄辩和谴责上,而是要真正探索这个艰险的领域,我们还需要一些更锐利的思考工具。我们的大脑是否真的具有并利用了计算机永远都无法企及的那些神奇能力呢?要想有根据地解决这个问题,我们首先得知道计算机都能做些什么,它们是怎么做到的。而要想圆满地证明“我们的大脑不是,也不会是一台计算机”,可用的方法是:(1)证明大脑某些“活动部件”所参与的信息处理工作是计算机无法模仿的;或者(2)证明我们平日熟悉和喜爱的那些精神壮举并不能由组合、汇总计算机部件的简单工作或通过任何计算机形式的处理方式来实现。
除了哲学家外,还有神经科学家、心理学家、语言学家,甚至物理学家都认为这种人类大脑的“计算机隐喻”极具误导性,因为大脑显然能够做很多计算机不能做的事情。他们通常(但也不绝对)先对“计算机是什么”或者“应该是什么”这个问题规划出一个很天真的预设,最后就得出了这个明显但又不相干的命题,即大脑可以做很多笔记本电脑不能做的事情,因为笔记本电脑没有充足的传感器和效应器,内存低,运行速度也有限。而事实上,关于“通常情况下计算机能做什么”这个问题,如果真要回答,我想我们需要弄清楚的应该是:在通常情况下,计算机的能力来自哪里,是怎样得以发挥的?
1957年,那还是计算机时代的初期,王浩发明了寄存器机这个神奇的东西。他是逻辑学家,是库尔特·哥德尔的学生,顺便提一句,他也是一位哲学家。寄存器机是一件简洁的思考工具,每个人的工具箱里都该有这么一件,可惜它至今还仍未被大家所熟知。 (37) 寄存器机是理想化的、假想出的计算机,它只是由有限数量的寄存器和一个处理单元构成的,具有十足完美的合理性。
寄存器是一些存储单元,每个寄存器都有自己各自的地址,比如寄存器1、寄存器2、寄存器3,以此类推,它的内容包含一个整数,如0、1、2、3,……。寄存器就像是一个一个的大盒子,里面可以放置任意多的(从0到无限多个)豆子。不管这些盒子有多大,而我们总是希望这些盒子能无穷大,因为那样它们才能装上无限大的整数。但我们对大盒子的这些设定是有目的的。
处理单元只具备三种简单的能力:它只能“遵循”三种“指令”,一次执行一条。每一串指令构成的序列都是一个程序,而每一条指令由一个数字来标记,即给每条指令分配一个ID号。这三条指令分别是:
结束。 表示将自己停止或者关闭。
增量。 将寄存器n中的数字加1,或者说在盒子n中再填入一粒豆子,然后进入下一步,步骤m。
减量。 将寄存器n中的数字减1,或者说从盒子n中拿走一粒豆子,然后进入下一步,步骤m。
减量指令与增量指令的运行原理基本相同,只是减量指令中多了一个非常重要的难点:如果寄存器n中的数字是0该怎么办?我们已经无法再从中减1,因为寄存器中不能持有负的整数,正如你无法从一个空盒子中再拿走一粒豆子,面临如此窘境只得另寻它路。办法是:跳转到其他地方运行下一步指令。每一个减量指令都需要在程序中列出那个接受跳转的位置,以应对当前寄存器数字为0的情况。所以,减量的完整定义应该是:
减量。 将寄存器n中的数字减1,如果可以执行则继续进行步骤m,如果寄存器n不能减1,则跳转至步骤p。
一部寄存器机能做的所有工作,简单表示就是:结束、增量、减量(或者跳转)。
乍一看,你会觉得这台机器的工作实在有些无聊,只做着一些把一粒豆子放进盒子里或者从盒子里拿出一粒豆子的工作(只要它能找到一粒豆子的话,如果找不到,它会跳转到另一条指令)。但事实上,它可以完成一台计算机能做的所有运算。
让我们从简单的相加开始吧。假设你想让寄存器机将某一个寄存器(比如寄存器1)里的数字加到另一个寄存器(寄存器2)里的数字上。如果寄存器1中的数字是“3”,寄存器2中的数字是“4”,那么,我们要设计出的程序就是:相加结束后,寄存器2中的数字为“7”,因为3+4=7。这个程序用简单的RAP(Register Assembly Programming,寄存器汇编程序)语言编写出来就是:
程序1:相加[1,2]
前两个指令构成了一个循环,寄存器1每减一次,寄存器2就加一次,直至寄存器1中的值变成0,处理单元能“注意”到寄存器中数值为0这一点,继而会将运行步骤跳转到3,即寄存器机停止工作。处理单元并不知道寄存器中的数字,它只能识别出寄存器中数字为0的情况。用盒子和豆子来打个比方:把处理单元想象成是一个盲人,它看不见盒子(寄存器)里面有多少豆子,但是通过探测,它可以识别出盒子空了。所以,尽管事实上处理单元不知道寄存器里确切的内容,但只要步骤1开始运行,寄存器1的内容(不管寄存器1中的数字是几)就会累加到寄存器2里(不管寄存器2中的数字是几),然后停止。(你能知道它为什么会这样运作吗?多试几个例子看看。)我们甚至可以这样说:即使不知道哪两个数相加,不知道数字是什么,甚至也不知道加法是什么,寄存器机也能完美地完成累加计算!
练习1
a.运用程序1,想一下寄存器机需要几步可以计算出2+5=7?(“结束”也算是一步。)
b.要计算出5+2=7需要几步完成?(你从中可以得出什么结论?) (38)
有一种图解可以很好地说明这一运算过程,我们称之为流程图。圆圈中的数字代表将要接受运算的寄存器的地址(它不是寄存器中的内容),“+”代表增量,“-”代表减量。程序从α(alpha)开始,至Ω(omega)处停止。箭头表示进入下一指令。请注意,每个减量指令处都会向外引出两个箭头,可以减量时有箭头指向一个步骤,而无法减量时(当寄存器中的内容为0时,遇0跳转)则有另一个箭头指向另外一个步骤。
现在,我们就来编写一个程序,将一个寄存器中的内容移动至另外一个寄存器中。
程序2:移动[4,5]
流程图如下所示:
可以看到,第一个循环是清空寄存器5。这样一来,不管一开始寄存器5中的数字是多少,它都不会影响到在第二个循环中要移进来的内容——第二个循环正是增量运算的环节,将寄存器4中的内容添加到已清空的寄存器5中去。这种初始化步骤被称作寄存器清零。它是一项非常有用的标准化运算,我们会不断用到它,好让寄存器能重新投入使用。
第三个程序是,简单地将一个寄存器中的内容复制到另一个寄存器中,被复制的那个寄存器中的内容保持不变。仔细观察这个流程图,思考它的程序设计:
程序3:复制[1,3]
显然,这是完成拷贝的一条迂回路线。首先,我们要将寄存器1中的内容移动到寄存器3中,同时比照3中的内容做一个副本,将它复制到寄存器4中。最后,再将寄存器4中的内容重新移动到寄存器1中——也就是将寄存器4中的内容复制回了寄存器1。程序就这样按部就班地运作,不管一开始寄存器1、3、4中的内容是什么,到程序结束时,寄存器1中一定保留着自己原来的内容,复制的内容保存在了寄存器3中。
如果你认为自己对这个程序的运作方式还不是很清楚,那么你可以尝试“手动模拟”整个过程。取出几个杯子充当寄存器(用铅笔在每个杯子上写一个数字,这是它们各自的地址),再找一些硬币或是豆子。在每个寄存器里都放置几枚硬币,然后记录下寄存器1和寄存器3中硬币的数目。接下来,依照程序按部就班地执行完毕,你会发现,寄存器1中硬币的数量与先前一致,而寄存器3中也拥有了与寄存器1数目相同的硬币。能将累加寄存器的基本运作过程都吸收内化是非常有必要的,我们得做到无需再去费劲思量它们。那么现在,就让我们先用几分钟去变成一部寄存器机吧(就像一个演员要去饰演哈姆雷特那样),因为接下来还要用到这种技能。
我发现好多学生常会犯这样的错误:他们认为,在做寄存器减量时,硬币从一个寄存器里取出之后就一定得放入到另一个寄存器中去。这是不对的。减量取出的硬币只需放回到那一大堆硬币中去即可,在简单的加减法套路中,有“无限多”的硬币可供你使用。
掌握了移动、复制还有归零这些技能之后,我准备重新回到之前的加法程序,对它进行改进。之所以要这样做是因为,程序1虽然成功地将加法运算的结果存进了寄存器2中,但在运行过程中,寄存器1和寄存器2中原有的内容却受到了破坏。我要设计出一个更加专业的加法程序,它能保留住原有的那些数值以备后用,将得出的结果放到另外一个地方。现在就让我们来思考这个程序,将寄存器1的内容与寄存器2的内容相加,两个寄存器中的数值保持不变,将结果显示在寄存器3中。
下面是完成这一程序的流程图:
现在,我们就来分析一下各个循环,看看每一步是怎样运行的。首先我们要将显示最终答案的寄存器3归零,同时清零那个空闲的寄存器4,让它充当临时的接受器或者缓冲器。然后,我们把寄存器1中的内容复制到寄存器3和寄存器4中,随后将寄存器4,也就是缓存器中的内容再次移动到寄存器1,让它恢复原有的数据;在这个过程中,作为缓冲器的寄存器4再次被清零,以备后用。接下来,我们将上一步的寄存器1替换为寄存器2再执行一遍,将寄存器2的数据加到寄存器3的数据上。待整个操作完成后,缓存器(寄存器4)清零,加法答案显示在寄存器3中,同时,我们选用的两个加数也保留在了原来的出处——寄存器1和寄存器2里。
将这套由13个步骤构成的RAP程序改写成下面的流程图,可供处理单元读录:
程序4:无损加法[1,2,3]
我不建议你拿杯子和硬币去手动模拟这个程序。人生苦短,一旦你把这些基本步骤都刻入脑海,那就可以切实享受一下“义肢”给你带来的便利了,这副义肢叫RodRego,你可以从网站http://sites.tufts.edu/rodrego/上下载到这部寄存器机。
最初的寄存器机RodRego的网站首页,1986年。
RodRego有PC、Mac (39) 两个版本可在您的计算机上运行。20多年前,我和乔治在课程软件工作室里研发了这件思考工具,如今,成百上千的学生和其他行业的人员通过它成为了熟练的寄存器机思考者。你可以将自己编写的RAP程序键入电脑,观察它们如何运行,不管寄存器中的内容是数字还是豆子。另外,有的多媒体软件还可以顺着流程图将处理单元的程序路径淋漓尽致地展现出来,让你可以清楚地看到RAP指令与流程图各环节之间的相互对应。
接下来,我们再来看看减法。这是我的第一次尝试,从寄存器1中减掉寄存器2中的内容,将答案显示在寄存器4中。你能看出我这个流程图存在的问题吗?
这个流程图只有在寄存器1中的内容大于寄存器2的内容时才能正常工作。但如果实际情况不是这样,又该怎么办呢?寄存器1在不断减量的过程之中就已被“清零”,那接下来会发生什么?此时我们不能中止电脑运行,因为那样的话,寄存器4中会留下一个错误的答案“0”。事实上,在寄存器1归零时,我们可以开启一个新的程序,它会先倒退半个循环,将寄存器2中最后减去的1再加回来。此时,将寄存器2中(而不是寄存器1)的数字转化成负数,所得的结果就是正确答案。所以我们只需把此时寄存器2中的数字移动至寄存器4中(之前,其中的内容已清零),再将答案标注为负数即可。我们还需要另外一个寄存器,比如说寄存器3。与寄存器4一样,寄存器3也要首先清零,然后,通过程序设计,它要像一面“旗帜”那样为答案做标记,内容为0时表示正号“+”,为1时表示负号“-”。下面就是这个程序的流程图,各个循环和步骤都有相关注释。(这些注释也可以写入RAP程序中供你以及其他人参考阅读,你要用“#”在其首尾做出标记,这样RodRego就会自动忽略掉它们)。
练习2
a.请为这个流程图写出它的RAP程序。(请注意,由于程序有不同的分支,你可以采用不同的顺序为各步骤编号,只要“下一步”对应的步骤编号填写正确即可。)
b.如果从3中减3,或者从4中减4,这个程序会出现哪些不同?
c.将寄存器3在第三步之前就清零而不是推延到完成第四步之后,这样会避免哪些可能的错误?
熟练掌握了加法和减法的编程以后,再设计乘除运算就易如反掌了。n乘以m表示m个n相加。我们可以这样来设计程序:用一个寄存器作为计数器,从m递减到0,每完成一次加n的运算就减去1。
练习3
a.画一个流程图或者写一个RAP程序,让寄存器1中的数字与寄存器3中的数字相乘,将答案显示在寄存器5中。
b.(可选) (40) 利用复制和移动改进你上面写出的乘法编程,使寄存器1与寄存器3在程序停止后都能保持原有的内容,方便你在运算完成后清楚地检查输出和输入的内容正确与否。
c.(可选)画一个流程图或者写一个RAP程序,要求它能识别寄存器1与寄存器3中的内容(同时保证这些内容不受损坏),将内容较大的寄存器地址(1或3)显示于寄存器2;当两个寄存器中的内容相等时,寄存器2中显示2。(程序完成后,寄存器1和寄存器3中的内容要保持不变,寄存器2显示出所含数字较大的寄存器地址,当内容大小相等时,寄存器2将报出数字2。)
与乘法类似,除法运算只需要从被除数中一次一次不断地减去除数并记录下相减的次数即可。如果有余数,我们可以留出一个专门的寄存器储存它。另外,我们还要小心地添加一个必要的检查项目:看看除数是不是0(0不能作除数,请问这是为什么?)。所以,在进行除法运算之前,我们得对除数作一个简单的核查——看看它能否被减量。如果可以,我们还必须再安排一次增量,以便使除数恢复原值,让除法运算继续进行。如果在进行减量核查时,除数真的是0,那就需要拉响警报了。为此,我们可以专门准备一个寄存器负责报错:寄存器5里如果有1出现就表示,“快!我就要除以0了!”
下面就是一个除法流程图,用寄存器1中的内容除以寄存器2中的内容,将答案写入寄存器3,余数显示在寄存器4,醒目的寄存器5用来提示“错误信息”(显示1表示“我将要除以0”)。
顺着这幅流程图梳理,你就能看到“除数为0”是如何中止掉整个运算的,报错的旗帜究竟是如何竖起的。另外还需要注意的是,寄存器4身兼双重职责,不仅要复制并恢复除数数据,以便下次继续成功地减量,而且,还要时刻准备着成为一个余数寄存器。如果在寄存器4将自己的内容倾倒回寄存器2以备下次减量之前,寄存器1中的内容就已经为0,那么留在寄存器4中的数字就是余数,它也正好显示在了余数寄存器中。
秘密1
发挥能力,无需理解力:有些东西——如一台寄存器机——它能完成精密的运算,但无需理解自己在做什么。
寄存器机没有头脑,因而它不能理解。但因为一碰上增量、减量、停这三条“指令”,它就会老老实实地执行,所以我们也有理由说,寄存器机是近似于明白这三件事情的。不过这三条指令不是真正的指令——它们只对于我们来说像是指令,但对于寄存器机,它们只是近似于指令而已。