有這樣一堆可以儲存數字的方格:
如果我們可以對其中任意2個方格進行「或"運算並寫入任意1個方格,或者對任意1個方格進行"非"運算並寫入任意1個方格,那麼由無限個方格和操作組成的機器是圖靈完備的嗎?答案是肯定的,下面我將給出這種機器的乙個例項:
該機器具有如下特點:
該機器例項的構成:
有限個方格,每個方格可以儲存16位二進位制數,即可以表達十進位制數0到65535,為了增加可讀性本文所有數字都用十進位制表示。
每行放8個方格,每個方格都有乙個編號,編號從0開始,從左往右遞增,從上往下換行,即行主序。
一堆方格可以組成模組,每個模組只能定址到自身,模組與模組之間可以硬連線。增加模組的目的是增加可讀性,如果所有數字都寫在乙個模組裡很可能不是人類可讀的。
每個模組都有乙個自身的振盪器(即時序),但所有振盪器都是同源的。也就是說,所有模組都是並行的。
每個模組的行為比較簡單,它由乙個振盪器驅動,反覆執行動作。首先,讀取第0號方格中的數字,設為a,再讀取編號為a的方格中的數字,設為b,根據b的值決定接下來的動作:
下面通過乙個例子來說明:
該模組的執行流程是:
那麼這個模組到底在幹嘛?其實它就是乙個16位2輸入與門,根據德·摩根定律,a * b = ~ (~ a + ~ b),假設每條指令的計算耗時均不超過1個時間單位,我們將2個輸入分別放入5號和6號方格,等待4個時間單位後,7號方格就得到了結果。由於與門不在我們的操作列表裡,所以這裡我們用或門和非門實現了與門。我們把輸入和輸出方格標識出來,對這個模組進行重新描述如下:(注意**中第一行的加粗字型並不表示什麼含義,只是markdown的**第一行會自動加粗)
接下來基於2輸入與門,我們就可以實現3輸入與門:
**中大寫字母開頭的方格aa5表示該方格硬連線到模組a的第5號方格,是編碼為a的例項,就是說aa和ab都是2輸入與門,但他們是兩個不同的例項。另外由於該模組用到了a模組,所以它必須要等待a模組操作完,振盪器週期應設為4個時間單位。(這裡b模組用到了a模組,假設我們稱b為父模組,a為子模組,只要每個父模組的振盪器週期是所有它的子模組的計算耗時的倍數,即使子模組內部在中途修改了輸出方格的值也沒關係)
同樣的,為了實現一點有趣的功能,我們還需要實現其他的基本模組:
這裡要注意,x模組中的aa和b模組中的aa是不同的例項。
這裡用到了第三種指令按位或運算,所以**中的1 * 16即16,pa3 * 16即pa48,按位定址。另外進行位運算前無需清零,因為儲存器在一開始已經全部清零。
這裡需要一點特殊的技巧,將5號方格的in_addr和6號方格的in_addr分別寫入8號和9號方格,然後因此m模組的輸出是0或者1,所以第五行將2號方格的8與ma7進行或運算相當於對ma7加8,即0+8=8或者1+8=9。另外66號方格最開始是0,但會被倒數第二行的指令修改,即自修改,只有這種自修改的方法才能實現條件選擇。
2號方格的8是第二行的起始編號,3號方格的88是最後一行的起始編號,4號方格用來每次加1,5號方格是迴圈變數,初始化為1,6號方格的6是迴圈變數的終止值。注意最後乙個方格即95號方格,它的初始值是0,但它會被最後一行的指令根據s模組的輸出值修改(又是自修改),也就是如果sa3等於sa4,則把sa5(88)放入95號方格,如果sa3不等於sa4,則把sa6(8)放入95號方格。所以最後一條指令相當於實現了條件跳轉,根據情況選擇跳轉到8或者88。
經過21991200個時間單位後,我們在右上角(即7號方格)看到了1+2+3+4+5的計算結果15,最終該模組陷入了執行最後一行指令的無限迴圈。
但是無限迴圈的逼格始終不夠高,相信看過《論可計算數及其在判定問題上的應用》和《電腦程式的構造和解釋》的朋友應該對裡面的元直譯器印象深刻,下面我們也來實現乙個元直譯器:
只要把上面的迴圈求和模組z裝入1024開始的一堆方格中,等待一段時間即可看到1+2+3+4+5的計算結果15。注意只有最外層的模組是跑在直譯器裡的,其他子模組還是跑在真機裡。
如果要模擬圖靈機也可以用類似的方法,能模擬圖靈機即可證明它是圖靈完備的。
修改python系統預設編碼的一種方法
修改python系統預設編碼的一種方法 火流星x unicodedecodeerror ascii codec can t decode byte 0xb2 in position 0 ordinal not in range 128 相信很多人都遇到過這樣的情況了,尤其是在同時處理unicode和...
Unity指令碼子執行緒修改UI的一種方式
初學unity,發現它和android一樣,沒法在子執行緒中修改ui,甚至沒法建立gameobject或者使用gameobject.find 於是又只有拐著彎去實現執行緒間通訊。我使用了一種方法,在這裡記錄一下,因為都是自己探索的,所以這個方法不一定所有情況都好用。在乙個房間列表介面,房間列表的內容...
介紹一下MySQL修改root密碼的4種方法
方法1 用set password命令 首先登入mysql。格式 mysql set password for 使用者名稱 localhost password 新密碼 例子 mysql set password for root localhost password 123 方法2 用mysqla...