Friday, September 17, 2010

闲话GEB

按:
研究生课程里学了半年的C++, 自以为各种语法钻得很细, 一些巧妙的算法花一定功夫也能琢磨出来. 但实习的时候真正开始写大的project的时候就傻眼了. 现在看来, 编程的一方面乐趣可以叫做:规则, 这教会我们怎样从基本的语句和各种元素发展成庞大的工程; 另一方面乐趣逆过来思考, 就是如何把庞大的工程, 生活中的问题, 或许是跟编程完全无联系的东西拆解成可以用计算机执行的基本元素, 这是反向的过程, 同时也是更实际的问题. 两头都打通了, 智力就更上一个层次了.

转自豆瓣 GEB书评
http://book.douban.com/review/1596919/

GEB(《哥德尔,埃舍尔和巴赫——集异璧之大成》)是本妙书。作为标题的三个人,两个跟我是老 朋友——巴赫和哥德尔。从计算机科学来看,如果说得玄一点,不确定性原理以及图灵机这样的概念,是可以当成哲学来说的。巴赫老人家的音乐在某种意义上也可 以当作神秘主义符号来说。荷兰画家埃舍尔我了解有限,不过作品倒还很合我口味:充满悖论和幻觉。
  
   总的来说,我们这个世界是可以被不同的定义和推演 所描述的。拟定一个方向,所有的“数”都乖乖地沿它长下去。至于“语言”,说白了就是从游戏规则出发——可能是荒谬的规则,但从这规则你可以定义整个世 界。世界被一条描述分成两半:属于和不属于。巴赫的音乐可以被解释出一种“数字意”,因为他一直在攀爬,重复,不经意间回到起点。我常常把巴赫的灵感,想 成一种荒诞的规则,一颗怪异的种子。在羽管键琴的机械敲打中,种子当当当地长成盘旋的绿藤。
  也正因为此,我一直悄悄把写复调的作曲家巴赫当成现代艺术家,拓扑观念的高手。
  
  隐喻
   个人一向反对硬做文章式地联系科学和艺术。自己乐意做个老实人,哪怕被人称 为只见树木不见森林的工匠,盯住细节死板地研究。然而我又认为,从艺术和科学层面去想,其实不应看成对艺术和科学的归纳,而是走出新的一径,对世界重新定 义。我常常嘲笑那种要用科学解释艺术的人,是把立体的东西放到二维座标系中按扁,然而按GEB的作者的目光看去,不是把三维按成二维,而是让它长成四维 了。如今我不由自主深深赞美这种新鲜的眼光。顺手拈来一则,是作者谈 “堆栈” 。堆栈是一种程序中常用的数据结构,即存数据是先进先出(比如一节节车厢通过山洞) 还是先进后出(如同一头堵死的竹筒) 。作者用巴赫的晚期杰作《赋格的艺术》来讲它,“紧张和释放是音乐进行的基本动力”,《赋格的艺术》中,先用转调形成一种压力,然后在那个基础上继续变 形,而解开压力的顺序与之相反——倒退着解开。呵呵,把巴赫和堆栈联系在一起的人,应该受我一拜。
  
  我读计算机系硕士的导师,专门搞一些“形式语 言”,让我们活活抓狂而死。那时我们定义语言,总有一项是unknown(未知,未定义)。GEB的作者Hofstadter画了一幅图,两棵树,一黑一 白,中间有unreachable falsehoods & unreachable truths。一个“异常”就一下子把过程扔到深渊里去了,最后扑通扔出一个错误信息了事。在我看来,这其实是对世界的一种隐喻。计算机科学充满了这种对 人世的模仿和寓言。比如图灵机,答答答答地在带子上打出结果,有时有确定的答案,有时没有。这个东西奇妙在完全不能用实验印证。我们做题听课热火朝天,却 完全是在一个乌托邦里闹,根本看不到后果。我们的证明,往往就是为得出一个“不可解”的结论,在一个并不存在的空间里,我们抓瞎着在概念丛中穿行。
  
  当 然,习惯了那些概念丛,它们就是真的了,比真还真,成为意识的一部分。而里面的磕磕碰碰,都有真实质感。素质好的人,从一丝碰撞的触觉摸去,就能撞见个新 洞天。我过去有个很年轻的老师,读硕士时就发表了很出色的论文。后来他不无得意地对我们回忆那个下午,一个闷热孤单的地方,他一个人郁闷一大顿之后,给外 出开会的导师发了一封振聋发聩的邮件,汇报自己的发现。有一次,我问他,你的研究其实根本不用计算机,对吗?他笑着举起一张写了些铅笔字的小纸片,看,这 就是我的全部研究。
  
  
  递归
   上面说了图灵机。它不是真实的机器,是一种抽象数学模型,用纸带模拟数学运 算。看上去,它原始得不可思议,但又永恒得不可思议。因为假设纸带无限长,又假设可以保存整个纸带的当前状况。它正是计算机的理论模型和概念的开端。英国 数学家图灵认为这样的假想“机器”就能模拟人类所能进行的任何计算过程——抵达如此简洁的概括,真乃天才。
  同为英国人的散文家兰姆,写过一个半小 说半散文的东西,说某个国家(似乎是中国)的一个男孩发现房子烧毁了,碰巧烤熟猪肉,就很好吃。为了有熟猪肉,他们就一间一间地烧房子。现在看来,早期计 算机的思想,简直就是这样,笨手笨脚地绕许多弯才能解决一个最最简单的问题。其实,现在的机器定理证明也是这样的,对初学者来说,证明x+1 > x 需要繁琐的定义,动辄面对大量错误信息。然而那就是计算机的发端,跟人类直觉思维截然不同的思考方式。从那里开始,人的思想史开始了新的头绪—当人发现自 己的直觉太过聪明,聪明到了头,打算换成笨办法的时候,才开始了一种“可持续发展”的新聪明。
  
  递归本来是一种编程技术,简单地说,是让一个函数从 其内部调用其自身。比如计算阶乘。0 的阶乘被特别地定义为 1。 更大数的阶乘是通过计算 1 * 2 *…来求得的,每次增加 1,直至达到要计算其阶乘的那个数。也就是说,每一步都保存形式(每次增加1),但变更内容(被增加的数字时刻在变化),变到你不需要再变为止。递归思路 本身和编程应用都不太直观,需要学习和适应,才能有对“样式” 的坚强守护——它不是保留一个具体公式反复调用和推算,而是保持一个“样式”,比如一个数乘以一个比它小1的数,这个“比它小1”的“它”,每次都变,所 以设计者必须在脑子里整好这个样式和结构,能够在抽象的状态中,从抽象到抽象。
  
  而递归一旦开始,形式就固定了,只有到了终止条件才停住。条件未满 足的时候,闭眼往前走即可。也就是说,这个过程完全不用知道整体的信息,而是只关心前一步结果是什么,然后据此推出下一步是什么,至于以后是什么,旁边是 什么,前一步的前一步,完全不管,它闭着眼睛摸黑走下去。这种对自身的不停调用的方式,好象混凝土一样,高效地合成整个世界。在我看来,递归是一种认知哲 学:把所知减到最少,驴拉磨一样。最少产生了最多——由最低能的图灵机生出计算机,由最简易的程序生发出人工智能。
  
  美国人Mitchell Waldrop写过一本叫做《复杂》的书,说的是一群博士研究生命科学,提到进化,认为以达尔文的理论,人能从无序的生命,进化成如今的样子,机率不超过 猴子在打字机上乱打,打出莎士比亚全集。有人说,最早的有机分子,由少数粘合成“大分子” ,一步步继续粘合,长成更“大”的生物,经过多少万年的进化、选择、粘合,才有了生命。不论是否经过证实,至少在我听来是有道理的。说到底,这理论仍然是 一种“生命递归”,由种子开始,由少变多,由小变大,动态积累,不能跳步。生命其实是盲目的,不知道自己在整体中的位置,只能从现存状态做有限的挣扎,当 然,不像计算机算法那样处于封闭状态,而是不时受扰动和灾难,可能犯错误、跃进、终止。这流向仍然是一般意义上的递归:发端是一种难以言说的天意或者“第 一推动”,而生命如默默跟着头羊走的羊群,不知所来,不知所终。
  
  
  出发
   递归在我眼中也意味着生命的无限——纸带无限长,记忆无限多,可以运行无限 的时间。而以递归为本的图灵机,却从一开始就既盲目,又“知道”自己的局限——图灵用它证明第一个不可决定问题——图灵机会不会停。结论是,没有一个一般 规律能够决定,对一些输入和算法,图灵机停还是不停。停,这里是个预定条件,比如我可规定,移动的读写头走到某位置,整个机器停下来。条件因机器游戏规则 而异,而最后我们知道的是,我们什么也不知道,无法一般性地预言,那个期待的地方能否抵达。因为一旦预言,结论必然矛盾,所以只好不预言。
  
  所以,生命出发了,然而不知道有没有终点,不知道前进的意义。上帝预设了谜给我们,一代一代才有兴致递归式生存,不知所终。我们是快乐的亚当夏娃。
  
  在 我看来,一方面,“样式” 是一种存在——一种由物质构成的“宏物质”——它粘合物质,把猴子向人带领。所以你我是一堆物理化学生物实体,更是“样式”的迭加计算结果---如果非要 用计算机模拟一下,我们的一举一动,一颦一笑,都是无数递归计算的结果,从此时可倒推到生命之初。而另一方面,“样式”这个东西,又可类比为人世中的“精 神层面”,因为人只有运用智力才能吸收并且保持形式。所谓精神、智慧、道德、伦理之类,可以跟物质保持一定的独立,这正是“形式”跟“内容”的关系。上面 说过,N的阶乘,N乘以N-1, 一直乘下去,不到那个尽头的1,也就是物质资源完全用光,这个形式一直保持,无论N有多小。
  
  跑题一下,记得 历史学家吉多(H.D. Kitto) 的《希腊历史》引言里说,与古希腊同时的民族,比如希伯莱,埃及等等,生活经验和智慧上本来一点不逊于古希腊,而且这些民族,各自有自己的文学传世。然而 只有希腊人形成了真正的科学,为什么?因为只有他们有意识地交流和总结,把数学哲学变成体系的学问,流传下来。相比较而言,希伯莱人积累的生活经验却一代 代化为云烟。古希腊人跟当时别的民族的比较,好比成人的智力跟儿童智力的比较。说到底,文化的积累本来都是递归式,然而还远远不够,因为递归中的元素,自 己不携带任何全局信息。大家盲目地跟着眼前的法则走,不介意整体状态,走到南墙活活撞死也得认命。
  
  递归的伟大在于将它抽象成“样式”的人。被递归的元素,却可舒坦地保持弱智状态。而人的社会,总要有人站在递归之外,为递归洪流设置终止条件吧。
  
  
  抵达
   音乐上有荒岛CD一说,那么“荒岛书”可就太多了。对我来说,GEB算一本,斯宾格勒的《西方的没落》也算一本。到了一个荒岛上,你念念不忘这个世界横竖在没落,左一文明,右一文明,“神龟虽寿,尤有竟时”,既然生出来也要衰落,那为什么还生呢?
  
  而GEB 是一本阳光之书。我每天等咖啡烧好那片刻都在读。今天下午在科学楼底买了只水果冰激淋,吃的时候不知看什么,就看它。那时,自己坐在圆桌跟前,周围的老师 同学也在买咖啡和冰激凌。书真是旧了,书皮从书脊脱落,落下很多黄屑。此刻,圆桌、黄屑,这些沙沙作响的东西,都可成为“观念”。在荒芜的桌旁,我凝视书 中的巴赫音乐谱例。其实,这本书里谈论巴赫的部份并非发前人所未发,毕竟作者不是音乐家。不过作者将数学和计算机的想法跟巴赫联系一下,有时别有奇趣。比 如说到巴赫的Hemiola和声,作者说,这是世界的不确定性。说得太简单干脆,让我以为这是我说的,简直想跳起来跟作者争版权。
  
  巴赫的管风琴赋 格作品的结尾,常有这种和声,节奏飘忽地变了一下,很蛮不讲理地把乐意扯到别处,给听者吃了贴迷幻药。那时我就想,上帝为我们设计巴赫这个人物的存在,是 跟量子力学一道给人类准备好的礼物。人秉承牛顿之意似乎把这个世界越算越妥贴,然而最终上帝撕碎我们的信心,毁掉人的骄傲。这一切,真是一种轮回。
  
  依 我看,GEB缺了重要的内容。如果我写,定要加上美国诗人史蒂文斯(Wallace Stevens)。史蒂文斯的诗歌充满荒诞意象,在我看来,往往是是对世界的拓朴式解构,赤裸裸的循环递归迭代,把信仰都绕进去。他喜欢写“一个基督徒女 人”这种题目,更喜欢慢条斯理地细细数来“十三种方式看黑鸟”,喜欢追究“存在”、“记忆”、“消失”。注意,在我看来,这些理念都“后计算机”得不得 了,而且自己丁丁当当搭起概念集合的架子。而且,他的诗意是放射性的,从语词中心出发,从那些华丽怪诞的动物名或者地名出发,最后形成凸多边形——是凸 的,不包括弯弯的蚕豆那样内凹的形状。
  
  我们就这样站在荒岛上,看各种轮回,看船来船往。

Inception:一场层层调用的函数大战

转自 安婆婆 科学松鼠会
http://songshuhui.net/archives/42661.html

就有这么凑巧的事:上周还在看侯世达 (Hofstadter)先生的《集异璧》,这周就在电影院里看到了书中概念的演绎版——哈,说的当然是日前火爆酷炫的高分电影Inception啦。废话少说,赶快剧透。还没看过的同学们海涵了,虽说透穿了剧情也不会影响你观影的效果。

Inception抓人眼球的是它“梦中做 梦”和盗梦的情节设计。在层层深入的梦境里,人的意识逐步放松警惕,入侵者便可以趁机盗走储存在大脑中的信息。控制梦中的意识,“我做你的梦”,两个 人的思想在同一个大脑中争斗……这都是令人看得过瘾的狂野想象。然而身为一个业余程序员和《集异璧》忠实读者,看到人在梦里死了掉进迷失域(limbo) 再也出不来,我第一反应还是忍不住叫出来:“哇,堆栈溢出!”

堆栈是一个计算机术语,我看来看去,觉得Cobb这群人在剧中完成任务的方法就像出自程序员的手笔。你看每个梦,都是同样的一组人物,抱着同样的目标,只是换到了不同的场景里。这多像一个函数调用的过程啊。

也许你没听说过函数调用,但你也许炒过青菜。 通常我们会先热锅、放油,然后爆炒、加盐、出锅。那么从热锅到出锅的一整套动作就可以写一个名为“炒”的函数。如果我们为白菜调用这个函数,就完成了“炒 白菜”的任务;如果为空心菜调用这个函数,就完成了“炒空心菜”这个任务。你还可以自由发挥,为各种包菜、韭菜、胡萝卜调用同一个函数,就把它们都炒了。

Cobb先生当然不在乎炒的是什么菜,他的任 务是在Fisher的脑中播种下拆分公司的念头。他为Fisher先生设计的函数就是梦,让Fisher的潜意识瓦解的梦。在计算机程序中,一个函数内部 可以调用另一个函数,在第二层函数运行的过程中,第一层的函数就在等待,直到第二层函数返回了运算结果,第一层函数再利用这个返回的值来继续它自身的运 算。这么一比较,Cobb的精心设计实际上就是用一个梦去调用另一个梦,上一层梦境中熟睡的人们都在等待下一层梦境中的人完成任务。一旦成功,就用音乐或失去平衡的方式返还(在迷失域则是死亡),来结束上一层梦境。

就像程序员喜欢在函数中调用函数来使问题步步细化,这些嵌套在一起的梦也起到了步步逼近Fisher内心深处的作用。但是这样层层的调用也有个风险,万一信息链被破坏,函数不知道自己身处的是哪一层,事情就要乱套。这样就使得“堆栈”这个概念变得重要了。

在计算机语言里,“栈”是内存中的存储区,它保存着正在运行中的程序的临时信息,在程序完成后就被新的程序信息覆盖。“堆栈”就是向这些存储区写入信息,好让系统知道现在哪个函数在等待返回值,以及返回来的值要到哪里去读取。

但是计算机的内存容量是有限的。当函数调用的 层数过多,新调用的函数信息在写入内存的时候空间不够,就把一些老的信息覆盖了。麻烦的是,被覆盖的那层函数还在等待下层函数的返回值来完成暂停的任务。 这样虽然新的函数成功运行,老函数却没法正确找到返回值,整个程序就出错了。这种因为空间不够而产生的错误覆盖,就是开头提到的堆栈溢出。

这和情节有什么联系呢?当然有啊,Cobb的 老婆Mal不就是堆栈出错的受害者嘛。根据影片情节设计,Mal在迷失域中就因为待得太久而失去了对现实的记忆。她一直在最底层的函数里,却认为活在最顶层的现实,不需要返回到任何地方。而Cobb的“栈”还是完好的,他还记得 现实中的孩子,知道应该返回到顶层去。

这个时候,如果Cobb直接带着Mal卧轨, 不和她说那些有的没的,两人也许就安全地从底层返还了。但是Cobb犯了个错误,他对Mal的潜意识进行了修改,这就相当于故意在Mal的“栈”里放置了 错误的但是有意义的数据。这样当Mal回到最顶层的现实时,本来整个大程序应该宣告结束,但因为她的“栈”被改写了,这个程序就错误地认为自己并不在顶 层。于是Mal就失去了对梦境和现实的分辨力,觉得自己应该再死一次才回到现实。

“悲剧啊!”看见Mal坠下高楼,我不由叹息,一出内存出错的惨剧。

与其说这是一部关于梦的科学幻想,倒不如说是 利用人类的算法对意识进行的一次设计。据说影片的灵感有部分来自侯世达先生的《集异璧》。这是本涉及甚广的奇书,试图综合各学科的知识来探讨意识的机制。 侯先生虽然也不能完全回答自己提出的这个问题,但他猜想意识的关键之处在于“我”这个概念的产生。而这个概念来自自我和外界的区分,来自人类和外界不断的 信息交流。于是对“我”的认知从出生时起就一层层叠进脑内,这种交流积累终其一生循环往复。书中曾把这个过程类比于函数对自身进行循环调用,那么影片中的 故事设计与计算机原理相似的情况倒也不太出乎人意料。

咦,那么有没有可能,导演在试图把计算机科学的知识植入到我们的潜意识里面?银幕前面的你,被他的Inception施中了吗?