【苏联计算机往事】Markov 算法
译自 Markov Algorithm。除非特殊声明,下文中「我」指原文作者 Oleg Kiselyov。 如果问一个人知道什么计算模型,得到的常见答案可能是「图灵机」和「λ-演算」。也许有的人会说「寄存器机」,但应该不会有人说「Post 系统(Post System)」1或「Markov 算法(Markov Algorithm)」 。这洵为一件憾事,因为逻辑学和理论计算机科学中常见的推理规则就是 Post 系统的一种表现形式,模板引擎、EBNF 规则、XSLT 或宏也是如此。仔细研究这些系统及其令人惊讶的表现力或许会令人有所启发,毕竟,Chomsky 就受到了 Post 系统启发,他的上下文无关生成文法以及其他一些生成文法都受到了 Post 系统的影响。除了作为计算模型的理论意义外,Markov 算法的思想也启发了一种真正的编程语言:Refal。在模式匹配被推广到普通的编程语言之前,Refal 就已经基于模式匹配。「窥孔优化(peephole optimizer)」也是一种 Markov 算法。 Post 系统(试想生成文法)基于重复的,甚至可能是上下文相关的字符串替换,即用新的字符串替换一个原有字符串的子串。替换规则由一组有限的规则序列(文法生成规则)组成,可以用任意顺序应用替换规则。而「正规 Markov 算法(Normal Markov Algorithm)」,顾名思义,是这种基于规则的替换系统的一种受限的「正规」形式。在正规 Markov 算法中,替换是上下文无关的,同时按照严格定义的顺序进行。因此整个字符串替换过程具有确定性,可以通过一种简单的机制(即「机器」)完成。正规 Markov 算法才能称之为「算法」2(这其实是一个俄语中的文字游戏,「算法」在俄语中是「алгоритм」,而 Markov 称他的系统为「алгорифм」)。 由上可知,正规 Markov 算法是一种机器,根据一串重写规则序列,通过按顺序反复应用规则重写输入字符串。规则由源 src 和替换目标 rplc 一对字符串组成,两者都可为空字符串。有的规则被标记为「终止规则」。机器的工作循环是:按重写规则序列的顺序,依次尝试用每条规则的 src 匹配输入字符。如果有匹配的,那么就用对应的 rplc 替换输入字符串中最左侧匹配到的 src 。匹配结束后,如果这条规则是一条终止规则,那么就停机。否则把改写后的字符串作为新的输入,然后重新开始循环。当没有可用的规则时也停机。 举个例子,下面是一个 OCaml 数组形式编写的规则序列。它可以把一个大端序二进制数字(由 0 和 1 组成的字符串)转换为由 | 组成的一进制数字字符串。 let bin_to_unary = [| rule "1" "0|"; rule "|0" "0||"; rule "0" ""; |] 使用本文随附的代码运行 run bin_to_unary "110" 可以生成有六条杠的字符串 "||||||"。该代码还打印了重写过程中触发的所有规则以及对应生成的中间结果,以展示这一巧妙算法的工作原理。...