陳凱
先來(lái)玩一個(gè)找不同的游戲,看看圖1中哪個(gè)人的坐姿與眾不同?這實(shí)在是太容易了,當(dāng)然是第四個(gè)人啊。然而稍微增加一點(diǎn)規(guī)則,游戲就變得有點(diǎn)意思了,考慮這樣的假設(shè):每個(gè)人的坐姿都代表著一種含義,如果坐在我西面的那個(gè)人和我的方向一致,那么我就面向西坐(左西右東),如果坐在我西面的那個(gè)人和我的方向不一致,那么我就面向東坐。至于最西面的第一個(gè)人,他就假裝把最東面的那個(gè)人看成是坐在他西面的人。現(xiàn)在的問(wèn)題是,哪個(gè)人的朝向是錯(cuò)誤的?
按這樣的規(guī)則,可以發(fā)現(xiàn),從西往東數(shù),第一個(gè)到第四個(gè)人都坐得妥妥當(dāng)當(dāng)?shù)?,就算是第四個(gè)人,他的坐姿也恰好沒(méi)有問(wèn)題,比較糾結(jié)的是第五個(gè)人,他的朝向與他西面的人的朝向不同,所以按規(guī)則,他就必須改變自己的坐姿,把臉朝向東,不過(guò)若他真的這樣做了,就會(huì)發(fā)現(xiàn),他的朝向就和坐在他西面那位保持一致了,于是他只有再把座位轉(zhuǎn)回來(lái),然而這樣就沒(méi)完沒(méi)了啦。真是左右為難??!
為避免出現(xiàn)這樣矛盾的情況,需要引入一個(gè)指揮者,指揮者從左到右逐個(gè)詢問(wèn)坐著的人是否要改變坐姿,指揮者走到最東面后,他就重新回到西面第一個(gè)人開(kāi)始指揮,坐著的人無(wú)論是變還是不變,只有當(dāng)指揮者指揮到自己時(shí)才能做一次決定??梢钥闯觯谝粋€(gè)人到第四個(gè)人的決定都是保持不動(dòng),第五個(gè)人根據(jù)規(guī)則改變了朝向,從面向西改作面向東了(如圖2)。
然后,第六個(gè)人發(fā)現(xiàn)自己也必須要改變朝向了(如圖3)。
很快一個(gè)圈子兜了下來(lái),到第十一步的時(shí)候,已經(jīng)兜回到第三個(gè)人了,他也改變了朝向,總算大家坐姿一樣了(如圖4)。
也許感覺(jué)一切都要結(jié)束了,所有人都妥妥地面朝東坐著了,讓強(qiáng)迫癥患者感覺(jué)要崩潰的是,當(dāng)指揮到第十二步時(shí),第四個(gè)坐著的人發(fā)現(xiàn),坐在他西面的人的朝向和他自己的朝向一致,所以他只好由面向東改為面向西(如圖5)。
看上去正好和初始時(shí)的狀態(tài)完全顛倒了一下,莫非再繼續(xù)變化一輪,大家的坐姿就能變回初始狀態(tài)嗎?這種想法實(shí)在是太簡(jiǎn)單、太天真了,其實(shí)復(fù)雜的變化才剛剛開(kāi)始,想要知道其后變化過(guò)程的朋友,可以繼續(xù)演算一下,或者編寫一個(gè)小程序模擬一下。
剛才游戲中的符號(hào)變化,其實(shí)可以做一臺(tái)機(jī)器來(lái)實(shí)現(xiàn),這里筆者并不打算用程序代碼,而是要使用電子元件來(lái)模擬出整個(gè)變化過(guò)程。需要的元件是一個(gè)存儲(chǔ)器、一個(gè)異或門、一個(gè)計(jì)數(shù)器、一個(gè)觸發(fā)器和一個(gè)時(shí)鐘發(fā)生器。其中,異或門、計(jì)數(shù)器和觸發(fā)器可以用三極管來(lái)搭建,當(dāng)然實(shí)際上人們往往會(huì)使用封裝好的集成電路芯片,時(shí)鐘發(fā)生器可以使用輕觸開(kāi)關(guān)來(lái)模擬,實(shí)際電路中可能需要電容和穩(wěn)壓二極管,至于存儲(chǔ)器,雖然可以用場(chǎng)效應(yīng)管、電容等元件來(lái)組裝,但因?yàn)榻Y(jié)構(gòu)太復(fù)雜,一般也是直接使用封裝好的芯片。為了方便解釋,這里給出整個(gè)系統(tǒng)的邏輯電路圖,電路圖是用開(kāi)源的Logisim軟件繪制的。圖6中1號(hào)元件是時(shí)鐘發(fā)生器,在Logisim軟件中,用鼠標(biāo)點(diǎn)兩下時(shí)鐘發(fā)生器,就會(huì)產(chǎn)生一個(gè)完整的脈沖信號(hào);2號(hào)元件是一個(gè)觸發(fā)器,觸發(fā)器里存儲(chǔ)的是上一次異或門運(yùn)算的結(jié)果,默認(rèn)初始值為“0”;3號(hào)元件是異或門,作用是當(dāng)兩個(gè)輸入的二進(jìn)制信號(hào)不相等時(shí),輸出信號(hào)“1”,否則輸出“0”;4號(hào)元件是計(jì)數(shù)器,將它的“Data bits”參數(shù)設(shè)置為“4”,就會(huì)隨時(shí)鐘發(fā)生器的脈沖,從0計(jì)數(shù)到15,然后再?gòu)念^開(kāi)始;5號(hào)元件是存儲(chǔ)器,將它的“Address Bit Width”設(shè)置為“4”,里面就能存儲(chǔ)16個(gè)二進(jìn)制數(shù),存儲(chǔ)器左側(cè)的D端口可以輸入數(shù)據(jù),右側(cè)的D端口可以輸出數(shù)據(jù),對(duì)應(yīng)游戲看,其實(shí)是表示了十六個(gè)人的坐姿的朝向,朝向西為“0”,朝向東為“1”。
這張電路圖把先前文字層面的游戲規(guī)則給實(shí)物化了,時(shí)鐘發(fā)生器和計(jì)數(shù)器起到了指揮的作用,異或門的作用是將存儲(chǔ)器中的當(dāng)前的數(shù)據(jù)和前一次異或運(yùn)算的結(jié)果再進(jìn)行異或運(yùn)算,然后把新得到的數(shù)據(jù)存儲(chǔ)到存儲(chǔ)器中,這對(duì)應(yīng)著游戲中坐姿朝向變化的過(guò)程。
就算弄不明白電路運(yùn)行的原理,在Logisim中直接照著畫一下也不需要太長(zhǎng)時(shí)間。然后運(yùn)行Logisim電路模擬器,用鼠標(biāo)不斷點(diǎn)擊時(shí)鐘發(fā)生器讓整個(gè)系統(tǒng)工作起來(lái),在運(yùn)行了16步也就是點(diǎn)擊了32次鼠標(biāo)之后,存儲(chǔ)器里的數(shù)據(jù)變成了如圖7所示的樣子。
有人會(huì)問(wèn),既然可以編寫程序解決游戲中的坐姿朝向問(wèn)題,為什么還要專門來(lái)搭建一個(gè)電路呢?當(dāng)然不只是為了好玩,實(shí)際上,這個(gè)電路就是一個(gè)完整的計(jì)算機(jī)。時(shí)鐘發(fā)生器模擬了計(jì)算機(jī)中時(shí)鐘頻率的作用;觸發(fā)器就是寄存器,注意不是模擬,因?yàn)槿粘S?jì)算機(jī)中的寄存器就是用觸發(fā)器實(shí)現(xiàn)的,當(dāng)然,日常使用的計(jì)算機(jī)中的寄存器要多得多;異或門是運(yùn)算部件,日常計(jì)算機(jī)中的運(yùn)算部件包含的邏輯門當(dāng)然要多很多;這張電路圖中的存儲(chǔ)器的邏輯結(jié)構(gòu)也和日常計(jì)算機(jī)中的存儲(chǔ)器的邏輯結(jié)構(gòu)相同,為簡(jiǎn)化問(wèn)題,這里只用一個(gè)單純做加法的計(jì)數(shù)器來(lái)尋址。有興趣的讀者可以照此電路圖親手制造出一臺(tái)迷你計(jì)算機(jī)。
雖然可以將這臺(tái)機(jī)器稱為坐姿朝向游戲模擬機(jī),但這臺(tái)小計(jì)算機(jī)的作用不限于此,它也可以對(duì)應(yīng)其他實(shí)際用途。例如,可以用做奇偶校驗(yàn)。假設(shè)存儲(chǔ)器前8位作為輸入,后8位作為輸出,那么在前8位中,“1”的個(gè)數(shù)是奇數(shù)還是偶數(shù),會(huì)使得后8位數(shù)據(jù)發(fā)生有趣的變化。
假設(shè)初始狀態(tài)時(shí),前8位中有兩個(gè)“1”,即偶數(shù)個(gè)“1”,后8位數(shù)據(jù)預(yù)先清0(如圖8),運(yùn)行一輪結(jié)束后,可觀察到后8位數(shù)存儲(chǔ)數(shù)據(jù)不變,表示檢查結(jié)果為偶數(shù)個(gè)“1”(如圖9)。
假設(shè)初始狀態(tài)時(shí),前8位中有三個(gè)“1”,即奇數(shù)個(gè)“1”(如圖10),運(yùn)行一輪結(jié)束后,可觀察到后8位數(shù)都變成了“1”,表示檢查結(jié)果為奇數(shù)個(gè)“1”(如圖11)。
除了用作奇偶校驗(yàn),這臺(tái)小計(jì)算機(jī)還會(huì)畫復(fù)雜的圖畫,假設(shè)初始狀態(tài)全是“1”,不停運(yùn)行后,存儲(chǔ)器中的數(shù)據(jù)會(huì)按過(guò)程發(fā)生如下變化:
把數(shù)據(jù)中的0替換成空格,把1替換成字符“V”,就能看得非常清楚了,這就是叫作謝爾賓斯基三角形的分形圖案(如圖12)。
所以說(shuō),這臺(tái)小計(jì)算機(jī)既是坐姿變化游戲的模擬器,又是奇偶校驗(yàn)器,還可以是謝爾賓斯基三角形繪圖儀,或者也可以單純用于烘托氣氛的LED閃爍控制。這個(gè)系統(tǒng)究竟起什么樣的作用,取決于使用者如何詮釋符號(hào)以及符號(hào)變化的意義。
不過(guò),這里有一個(gè)頗為麻煩的情況,這臺(tái)小計(jì)算機(jī)雖然能做一些小事情,但它的能力十分有限,要擴(kuò)充它的能力,就需要改變電路圖,增加邏輯門元件和存儲(chǔ)器容量。例如,可以通過(guò)增加存儲(chǔ)器和邏輯門實(shí)現(xiàn)一個(gè)簡(jiǎn)單卻又較難破譯的加密裝置(如圖13)。
這個(gè)小裝置能夠把用戶輸入的ASCII碼進(jìn)行加密,如輸入的是“GO”的ASCII碼(如圖14),加密后,輸出的密碼就是如圖15所示的樣子。并且因?yàn)榧用艿拿罔€自身也在變化,所以下一輪如果仍然要加密“GO”這兩個(gè)字母,生成的密碼和第一次是不同的。基本的加密思路和歷史上著名的Enigma是類似的。
最后要給出一個(gè)奇妙的問(wèn)題:如文中案例所示,當(dāng)人們?cè)黾佑?jì)算步驟或改變計(jì)算過(guò)程的時(shí)候,就需要改變計(jì)算裝置的電路結(jié)構(gòu),如增加邏輯門元件或存儲(chǔ)器的數(shù)量,并改變它們的連接方式。那么是不是存在某種結(jié)構(gòu)的電路,當(dāng)人們的計(jì)算需求發(fā)生變化后,并不需要增減電子元件及改變電路結(jié)構(gòu),也能照樣進(jìn)行計(jì)算呢?乍一想似乎不可思議,但問(wèn)題的答案是肯定的。早在上世紀(jì)三四十年代,數(shù)學(xué)家阿隆佐·邱奇和艾倫·圖靈就指出,存在這樣一種機(jī)器,不需要改變邏輯運(yùn)算部件的結(jié)構(gòu),只要提供容量足夠大的存儲(chǔ)器,就能滿足人們不同的計(jì)算需求了。艾倫·圖靈還給出了具體的方法,說(shuō)明應(yīng)該如何把這樣的機(jī)器建造出來(lái)。后來(lái)人們將圖靈設(shè)想的這種機(jī)器稱為通用計(jì)算機(jī)。圖靈被稱為計(jì)算機(jī)之父,實(shí)在是當(dāng)之無(wú)愧。艾倫·圖靈提出的建造方法究竟是怎樣的呢?這可不是本文這點(diǎn)篇幅能夠說(shuō)清楚的,然而實(shí)現(xiàn)的關(guān)鍵思路卻簡(jiǎn)單扼要:第一,人們需要進(jìn)行的運(yùn)算過(guò)程都可以對(duì)應(yīng)一系列的符號(hào)變化過(guò)程;第二,用來(lái)實(shí)現(xiàn)符號(hào)變化的機(jī)器自己的變化,也可以對(duì)應(yīng)一系列的符號(hào)變化過(guò)程。如果讀者能真正領(lǐng)會(huì)這兩句話的深刻內(nèi)涵,那么只要對(duì)文章中的電路稍微做些改造,就能造出一臺(tái)真正的通用計(jì)算機(jī)來(lái)了。