Prolog 和 SQL 都基于一阶逻辑,但 SQL 表是简单的二元关系,而 Prolog 谓词是 Horn 子句。
这不是一些晦涩的理论观点。 SQL 二元关系是事实陈述,形式为:
f(A, B, C ... N)
其中f 是关系的名称,A...N 是它的变量。 Prolog 二元关系是含义,形式为:
A
其中 A ... N 本身就是 Horn 子句。 SQL 关系是描述数据的一种有效方式。 Prolog 关系描述了数据之间的复杂关系,数据本身存储为数据。
重要的是要了解在 Prolog 中,数据和操作之间没有分离。 Prolog 事实、规则和查询都是 Horn 子句,因此是数据,在大多数大学课程的翻译中都会丢失。 Prolog 与 C 不同,但使用事实而不是变量和规则而不是函数。另一方面,SQL 很像 Prolog,没有规则或查询。
SQL 查询也是逻辑谓词,但 SQL 查询并不存储在数据库本身中。相反,它们用于从事实数据库中提取数据集。您可以将查询作为表行存储在 SQL 数据库中,但不能以该形式执行。
Prolog 查询与任何其他 Prolog 谓词一样存储在数据库中,因为它们与任何其他 Prolog 谓词一样。查询是以下形式的 Horn 子句:
所以有先例但没有先例的含义,因此总是错误的。 Facts 是带先行词但没有先例的 Horn 子句,形式为:
一个
总是如此。 Prolog 通过反驳来证明一个查询:如果它找不到证明它的事实(或规则),它将声明目标为真,因为查询总是错误的。在此过程中,绑定了一些变量,因此可以构造结果集,就像 SQL 对 SELECT 查询所做的那样。
现代 SQL DBMS 具有存储过程和流控制语言等功能,因此 SQL 可用于推理(不是您想要在 SQL 中进行推理)。 Prolog 配备了一个针对其 Horn 子句数据库调整的推理引擎,因为这是对表示为二进制关系的事实数据库进行推理的一种有效方法(不,不仅仅是因为它很漂亮)。
Prolog 的同义性(数据就是操作就是数据)意味着必须将新的新数据添加到数据库中,因此必须添加到程序中,因为数据库就是程序。因此,每次将新事实添加到其数据库(通常使用 assert/1)时,都必须反编译整个程序。这是一个巨大的 PITA,使 Prolog 在存储大型数据集时效率低下,尽管没有理由说明它在数据检索方面效率低下检索,并且 Prolog 系统将为此目的使用与 SQL 系统相同的算法.另一方面,SQL 非常适合存储和检索。
最后,Prolog 有一些 SQL 所没有的特性,即它的超级模式匹配(称为统一)、否定作为失败以及有助于列表处理和语法声明的语法元素(定句语法表示法)。这些只是一个快乐的意外,并且大部分被添加到语言中,因为它们在它最初创建的时候很流行(感谢 LISP)。 SQL 相对最近才获得递归查询,所以 Prolog 不能再吹嘘了。
当然,这两种语言在 I/O 和数学方面都很薄弱,尽管至少您可以在 Prolog 中进行一些算术运算,而不必一路费尽心思。
所以,实际上,Prolog 和 SQL 与 C 和 Haskell 非常相似。它们都基于相同的根抽象,一阶逻辑(如 C 和 Haskell 都基于代数),但在那之后事情很快就变得非常不同。此外,从语言设计的角度来看,SQL 往往是支离破碎的,具有许多不同的语言特性(词条、查询、数据操作语言......)。 Prolog 的设计极其一致,以至于整个语言真的只是谓词和几个标点符号。
对我来说,最重要的区别是:我不喜欢 SQL,但我必须使用它。我喜欢 Prolog,但我不能在工作中使用它。生活是不公平的:)