由于Lambda Ultimate没有任何响应,因此我在这里再次尝试:术语重写系统用于自动定理,例如证明符号计算,当然也用于定义形式语法。有一些基于术语重写的编程语言,但据我了解,该概念更称为模式匹配。模式匹配在功能语言中被大量使用。巴里·杰伊(Barry Jay)创建了一个称为模式演算的整体理论,但他仅简要提及术语重写。我觉得它们都指的是相同的基本思想,因此您可以同义地使用术语重写和模式匹配吗?
由于Lambda Ultimate没有任何响应,因此我在这里再次尝试:术语重写系统用于自动定理,例如证明符号计算,当然也用于定义形式语法。有一些基于术语重写的编程语言,但据我了解,该概念更称为模式匹配。模式匹配在功能语言中被大量使用。巴里·杰伊(Barry Jay)创建了一个称为模式演算的整体理论,但他仅简要提及术语重写。我觉得它们都指的是相同的基本思想,因此您可以同义地使用术语重写和模式匹配吗?
Answers:
看这两个概念的一种方式是说模式匹配是编程语言的一种功能,用于安全,紧凑和有效地组合对构造函数的区分和破坏术语(同时选择和局部命名术语片段)。模式匹配的研究通常集中在实现效率上,例如如何最小化匹配机制必须进行的比较次数。
相比之下,术语重写是一种通用的计算模型,它研究了用其他术语替换句法表达式子项(更确切地说是在一组变量中的术语代数的元素)的各种(潜在的不确定性)方法。术语重写系统的研究通常是关于重写系统的抽象属性,例如合流,确定性和终止,更具体地说,是关于重写系统上的代数运算如何保留或不保留这些属性,即这些属性在多大程度上是组合的。
两者之间显然存在概念上的重叠,并且区别在某种程度上是传统的,而不是技术上的。一个技术不同的是在任意上下文的项重写发生(即,规则诱导重写Ç [ 升σ ] → C ^ [ - [R σ ]为任意的上下文Ç [ 。]和替换σ),而像Haskell,OCaml或Scala这样的现代语言中的模式匹配则仅用于重写术语的“顶部”。我认为,Jay的模式演算也施加了这种限制。让我解释一下此限制的含义。使用OCaml,Haskell,Scala感觉中的模式匹配时,您无法说出类似
match M with
| C[ x :: _ ] -> printf "%i ...\n" x
| C[ [] ] -> printf "[]"
这是C[.]
什么 它应该是一个范围广泛的变量。但是,像OCaml,Haskell或Scala这样的语言不会为程序员提供在任意(单孔)上下文范围内的变量,而只能为值提供范围的变量。换句话说,在这种语言中,您无法在术语中的任意位置进行模式匹配。您始终必须指定从模式的根部到感兴趣的部分的路径。我猜想施加此限制的关键原因是,否则模式匹配将是不确定的,因为术语可能会与模式中的模式匹配不止一种方式。例如,假设
在此类上下文范围内,该术语以两种方式(true, [9,7,4], "hello", 7)
与模式匹配。C[7]
C[.]
我认为称呼它们为同义词是不正确的。在研究和实施方面存在一些重叠。我对Jay的工作一点都不熟悉,对术语重写系统也只有一点点熟悉,所以我可能也会缺少一些东西。
模式匹配通常会解决以下问题:您具有某种结构(树,列表或多集),并且您想检查结构是否与模式(或多个模式之一)匹配。这个问题肯定与术语重写有关,因为在术语重写系统中,术语与模式匹配这一事实意味着可以将术语重写为其他术语,但这不是术语重写的同义词。(重写时可能会有模式匹配的表述:“给一个术语,您可以重写它以匹配模式吗?”但我从未见过。)
功能性编程语言中的模式匹配在关注方面具有逻辑解释(例如,参见Krishnaswami的“关注模式匹配”)。另一方面,术语重写系统通常对某些方程式属性进行模匹配,这在大多数函数式编程语言中都不存在(您无法与ML或Haskell中的多集进行匹配)。但是,在功能语言中不应该存在匹配的模方程式属性是没有根本原因的。
(我宁愿以此作为评论,但目前不能。)
如果我错了,请指正我,但据我了解,模式匹配和术语重写之间的另一个区别是,马丁·伯杰(Martin Berger)在其出色的回答中说的是,模式匹配规则具有固定的顺序(例如Haskell's),而对于术语重写规则,情况并非一定如此。正如人们所期望的那样,在考虑规则的行为(尤其是终止)时,此功能可能会产生很大的不同(例如,请参见“ Haskell的温和介绍,版本98”,第4.2节,或者只是阶乘)。例如,“了解您的Haskell”)。
精通重写理论的人对此有更多的话要说(例如,打字究竟如何适合这样的比较?),但在我看来,我与马丁·伯杰尔(Martin Berger)持相同的观点,在这个术语中,重写被认为涵盖了所有内容。模式匹配(至少是在像Haskell这样的语言中实现的),在某种程度上,它们可以(而不是干脆地)视为仅使用术语相关规则的设备。