我正在寻找一种小语言来帮助“说服”学生,图灵机是一种足够通用的计算模型。也就是说,一种语言看起来像它们惯用的语言,但也很容易在图灵机上模拟。
Papadimitriou使用RAM机器来完成这项工作,但我担心将奇怪的事物(作为图灵机)与另一个奇怪的事物(基本上是汇编语言)进行比较,对于许多学生而言,这太令人信服了。
任何建议都将受到欢迎(特别是如果它们带有一些推荐的文献)
我正在寻找一种小语言来帮助“说服”学生,图灵机是一种足够通用的计算模型。也就是说,一种语言看起来像它们惯用的语言,但也很容易在图灵机上模拟。
Papadimitriou使用RAM机器来完成这项工作,但我担心将奇怪的事物(作为图灵机)与另一个奇怪的事物(基本上是汇编语言)进行比较,对于许多学生而言,这太令人信服了。
任何建议都将受到欢迎(特别是如果它们带有一些推荐的文献)
Answers:
我现在正在考虑如何让自己相信图灵机是一种通用的计算模型。我同意在某些标准教科书(例如Sipser)中对Church-Turing论文的标准处理不是很完整。这是我可能会从图灵机转到更易识别的编程语言的草图。
考虑具有if
和while
语句的块结构化编程语言,具有非递归定义的函数和子例程,具有命名的布尔型随机变量和通用布尔型表达式,以及具有可递增或递减tape[n]
的整数数组指针的单个无界布尔数组n
,n++
或者n--
。指针n
最初为零,数组tape
最初全部为零。因此,这种计算机语言可以是C语言或Python语言,但是其数据类型非常有限。实际上,它们是如此有限,以至于我们甚至没有办法n
在布尔表达式中使用指针。假如说tape
仅在右边无限,如果n
为负,则可以声明指针下溢“系统错误” 。同样,我们的语言有一个exit
带有一个参数的语句,用于输出布尔值答案。
那么第一点是,该编程语言是图灵机的一种良好规范语言。您可以轻松地看到,除了磁带数组之外,该代码仅具有有限的许多可能状态:所有声明的变量的状态,当前执行的行及其子例程堆栈。后者仅具有有限数量的状态,因为不允许使用递归函数。您可以想象有一个“编译器”可以通过这种类型的代码创建“实际的”图灵机,但是其细节并不重要。关键是我们拥有一种具有相当不错的语法但非常原始的数据类型的编程语言。
其余的构造是通过有限的库函数和预编译阶段列表将其转换为更实用的编程语言。我们可以进行如下操作:
使用预编译器,我们可以将布尔数据类型扩展为更大的但有限的符号字母,例如ASCII。我们可以假设该tape
值采用更大的字母。我们可以在磁带的开头保留一个标记以防止指针下溢,并在磁带的末端保留一个可移动的标记以防止TM意外滑到磁带上的无穷大。我们可以在符号之间实现任意二进制运算,并可以将for if
和while
statement 转换为boolean 。(实际上,if
也可以用while
不可用的方法来实现。)
我们将一个磁带指定为符号值的“内存”,将其他磁带指定为无符号的整数值的“寄存器”或“变量”。我们将整数存储在带有终止标记的little-endian二进制中。我们首先实现寄存器的副本和寄存器的二进制减量。结合内存指针的递增和递减,我们可以实现符号存储器的随机访问查找。我们还可以编写函数来计算整数的二进制加法和乘法。编写带有按位运算的二进制加法函数和编写左移乘以2的函数并不难。(或者,实际上是右移,因为它是低位字节序。)有了这些原语,我们可以编写一个使用长乘法算法将两个寄存器相乘的函数。
我们可以使用公式将存储带从一维符号阵列重组为symbol[n]
二维符号阵列。现在,我们可以使用内存的每一行来表示带有终止符号的二进制无符号整数,以获得一维,随机存取,整数值的内存。我们可以实现从存储器读取到整数寄存器,以及从寄存器写入到存储器。现在可以使用以下功能实现许多功能:有符号和浮点算术,符号字符串等。symbol[x,y]
n = (x+y)*(x+y) + y
memory[x]
只有另外一种基本功能严格要求预编译器,即递归函数。这可以通过广泛用于实现解释语言的技术来完成。我们为每个高级递归函数分配一个名称字符串,然后将低级代码组织到一个大while
循环中,该循环使用常规参数维护调用堆栈:调用点,被调用函数和参数列表。
在这一点上,构造具有高级编程语言的足够功能,以至于进一步的功能更多地是编程语言和编译器的主题,而不是CS理论。用这种开发的语言编写图灵机模拟器已经很容易了。为该语言编写自编译器并非易事,但绝对是标准的。当然,您需要一个外部编译器来使用类似C或类似Python的语言从代码创建外部TM,但这可以在任何计算机语言中完成。
请注意,此草绘的实现不仅支持逻辑函数的递归函数类的Church-Turing命题,而且支持扩展的(即多项式)Church-Turing命题,因为它适用于确定性计算。换句话说,它具有多项式开销。实际上,如果为我们提供了RAM机器或(我个人最喜欢的)树形磁带TM,则可以将其减少为用于RAM存储器的串行计算的多对数开销。
我不是CS理论的专家,但是我有一些有用的知识。我采取了另一种方法。我设计了一个简单的处理器,可以直接用一小部分C语言进行编程。没有汇编代码,只有类似C的代码。您可以使用与我相同的工具,并修改该处理器来设计您的Turing机器模拟器。我花了4天的时间设计,仿真和测试该处理器,还有一些说明!我使用的工具甚至使我能够生成真正的VHDL可合成代码。这是一个真正的工作处理器。
程序如下所示:
这是使用这些工具的处理器的图片:
工具“ Novakod Studio”使用高级语言硬件描述语言。例如,这是程序计数器的代码: 足够的交谈,如果有人感兴趣,请与以下公共信息联系我:https : //repertoire.uqac.ca/Fiche.aspx?id=JjstNzsH0&link=1
卢克
在这里采用用户GMB表示的想法如何(将一盘磁带的图灵机通过将N条磁带交织到一条磁带上,并一次跳过N个位置来读取其中任何一个磁带,就可以模拟一盘N磁带的图灵机。使用N盘磁带的计算机可以实现...)并编写实现简单RAM机的图灵机程序。RAM计算机实际上可能是具有可用LLVM或GCC后端的一些简单,真实的CPU。然后,可以将GCC / LLVM用于该CPU的C程序和图灵机程序的交叉编译,该程序模拟RAM机,通过让模拟的RAM机执行GCC / LLVM输出来运行RAM机仿真。Turing机器的实现可能是一些非常简单的C代码,适合一个小的C文件。
关于RAM机器,则存在一个演示项目,其中一个8位微控制器模拟了32位CPU,并且模拟的32位CPU启动Linux。慢得要命,但据作者德米特里·格林伯格说,它行得通。对于可仿真的RAM机器,也许Zylin CPU (GitHub用户zylin)可能是可行的选择。另一个RAМ机器候选人可能是Niklaus Wirth的ProjectOberon dot com 。
(我的文字中的“点”和“ com”是由于我刚刚2015_10_21在cstheory.stackexchange上注册了我的帐户,尽管事实上,我的网络应用程序不允许新用户使用超过2个链接他们可以从我的其他stackexchange帐户中自动看到我可能是愚蠢的,但我不是巨魔。)