模式匹配和一致性的区别是什么?

28

我曾经以为我理解了类似于Scala和Haskell中的模式匹配与在Prolog中发现的协同一致的区别,但是我对Prolog的误解很大。有哪些简单的问题可以通过其中一个解决而无法通过另一个解决?

4个回答

32

简单来说,模式匹配是单向的,而统一是双向的。也就是说,在Prolog中,右侧(被匹配的一侧)可以包含未绑定的变量。例如,如果你有两个未绑定的变量XY,这将可以很好地工作:

X = Y,
X = 5,
%% Y = 5 now as well

在Erlang中(它使用与Prolog语法相近的模式匹配),代码行X = Y会产生错误:变量'Y'未绑定。请注意,X未绑定是可以的:它应该进行模式匹配。

这在处理部分定义值时非常有用。一个很好的例子是差分列表

这也允许在多种模式下使用Prolog谓词。例如,在Scala/Haskell/Erlang中,如果要1)查找A ++ B,2)解决方程A ++ X == B,或3)解决方程X ++ A == B,给定列表AB,则需要编写3个单独的函数;在Prolog中,所有这些任务(及更多!)都由一个谓词完成。


胡说八道。试着统一这个:?- B = X + A, B 是 3,A 是 2。 - Feofilakt
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Feofilakt
@Feofilakt 这个问题是关于PM和统一之间的区别,所以答案就是在谈论这个。"通过阅读答案,你可以认为PM有这些特点,而统一没有"。但是怎么可能呢?如果是这样的话,那么这将是统一的优势,并且会在答案中提到,但事实并非如此。 - Alexey Romanov
@Feofilakt 没问题:在现代 Prolog(大约 20 年)中,?- 8 #= X + 3. => X = 5.。详细了解请参阅:https://www.metalevel.at/prolog/clpfd - Felixyz
@Felixyz 那性能呢?这些技巧已经在swi-prolog组讨论过了,那里显示了很大的减速。 - Feofilakt
显示剩余6条评论

8

我认为将概念形式化,而不是仅限于某个具体语言,是很有用的。匹配和统一是基本概念,不仅在模式匹配和Prolog中使用,在更多场景中也会用到。

  • 术语s与t匹配,当且仅当存在一个替换phi使得phi(s) = t
  • 术语s与t统一,当且仅当存在一个替换phi使得phi(s) = phi(t)

举个例子,我们检查术语s = f(Y,a)和t = f(a,X),其中X、Y是变量,a是常量。s与t不匹配,因为我们无法对常量a进行普遍量化。然而,s和t存在一个统一:phi = {X\a, Y\a}


1
在Scala中,以下代码将无法编译,因为它的第一个case分支尝试两次声明变量x。
(1, 1) match{
   case (x, x) => println("equals")
   case _      => println("not equals")
}

如果Scala使用统一而不是模式匹配,那么这将成功并打印“equals”。
(1, 2) match{
   case (x, x) => println("equals")
   case _      => println("not equals")
}

会打印“不相等”。这是因为在尝试将变量x绑定到12时,统一将失败。

11
实际上,这就是线性模式匹配(如Scala和Haskell)与非线性模式匹配(如Erlang和Mathematica)之间的区别。 - Alexey Romanov

1
在Prolog中,您可以像这样将[3]附加到[1,2]:

?- append([1,2], [3], Z).
Z = [1, 2, 3].

统一性的好处在于可以使用相同的代码('append'的内部定义),但是可以找到需要的第二个参数来从第一个参数中获取结果。
?- append([1,2], Y, [1,2,3]).
Y = [3].

与其编写“做这个,然后做那个”的代码不同,你在Prolog中编写代码是通过陈述你所知道的内容。Prolog将你提供的事实视为“方程式”。统一性让它可以解决那些你还不知道值的变量,无论它们在左侧还是右侧。
例如,你可以在Prolog中编写一个计划者,并且可以向前运行它,给它一个计划并让它预测结果;或者你可以向后运行它,给它一组结果并让它构建一个计划。你甚至可以同时以两种方式运行它(如果你在编码时小心),指定一组目标和计划约束条件,这样你就可以说:“找到一条去上班的路线,不涉及乘坐地铁。”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接