比较SQL和Prolog

我已经开始学习Prolog,并想知道与SQL语言的理论差异。

例如:

  • 两者都是声明性语言
  • 都支持事实驱动的知识库
  • 都支持问题式的数据检索
  • 两者都支持函数依赖关系

还有更多的共同点吗? 任何显着的差异?

大多数(早期的)答案都反映了大多数人不知道什么是SQL(它是关系演算的一个实现)或者这意味着什么(它是一种谓词逻辑)。 以下语句对于Prolog和SQL都是正确的:

  • 它们都是逻辑驱动的
  • 他们既可以存储,expression和使用关系(Prolog中的逻辑关系)
  • 他们既可以存储和expression复杂的逻辑条件
  • 他们都有事实(SQL中的数据),并可以从这些事实得出结论
  • 他们都有疑问,事实上这意味着同样的事情
  • 他们都有数据(Prolog中的事实)并且使用它们类似
  • 他们都是编程语言
  • 他们都是完整的(虽然在他们两人中都有点难以获得)
  • 等等。

一般来说,人们并不知道它们之间的这些等价关系:

  1. “事实”和“数据”是一回事。 这是Codd最初的论文的直接结果。
  2. 关系理论中的“关系”与SQL中的“表”是一样的,与谓词逻辑中的关系或关系函数是相同的,与集合论中的元组相同
  3. SQL中的别名expression式(即视图等)和Prolog中的规则是一样的。

那么他们的区别是什么? 虽然他们在相同的概念领域运作,但他们的重点却完全不同。 在Prolog术语中,SQL主要是事实和关系(集合)引擎,而Prolog主要是规则和推理引擎。 每个人都可以在有限的程度上做另一个人,但是即使复杂性的小幅度增加也会变得越来越困难。 例如,你可以在SQL中进行推理,但是它几乎完全是手动的,并不像Prolog的自动前向推理。 是的,您可以将数据(事实)存储在Prolog中,但是它并不是为SQL的“存储,检索,投影和减less数以万计的同时用户的行数”而devise的。

另外,SQL主要是服务器语言范例,而Prolog主要是客户端语言范例。

你是正确的:Prolog和SQL在理论上是相关的(你特别提到了理论差异)。

我想补充RBarryYoung的答案 ,给你一些提示,以了解这种联系,这样你就有了一个研究和理解技术的起点。

Prolog和SQL共享一个核心:在Prolog子集中可expression的每个查询都可以用SQL的一个子集表示, 反之亦然 ,即这些子集在逻辑上是等价的。

要理解这可能是真实的,你需要检查Prolog和SQL的基础是什么理论基础:

  • SQL 1是不同部分的混合,并不总是很好地集成, 显然来自关系代数( RA )和元组关系演算( TRC2和其他部分,不涉及逻辑(即SUM,AVG运算符,ORDER BY等等上)。
  • RA安全 (域独立)TRC (这被称为Codd定理 )的expression能力上是等价的 。
  • RA在expression能力上等同于安全Datalog,无recursion和(分层)否定 。
  • Datalog可以被认为是Prolog 3的一个“松散的子集” ; 一个“松散的子集”,在Prolog的操作语义上存在复杂的意义上说:“ 在数据目录中,子句的sorting与Prolog不同,而Prolog依赖于计算查询调用结果的子句的sorting ” ( 从这里引用 )。

当然,这些子集中的东西需要更多的翻译工作。

尽pipe如此,我认为在考虑Prolog到SQL的翻译时,这两个子集的expression能力的等价性不仅仅是对图灵等价性 4的一种吸引力。

笔记:

1)不幸的是,与RDBMS理论基础( 关系代数计算 )相比,可以使用SQL; 例如, SQL表不一定是关系 – 按照RA – 即它们可以没有(主键),所以重复行是允许的。 这样的表不是集合,而是多元组(又名袋) 。 在这样的背景下,所有RA关于集合的理论结果都不一定有效。

2)对于从SQL到TRC的翻译,请参阅关于SQL到元组演算的注释 ,也在这里(postscript论文) 。

3)有关Datalog和Prolog之间的差异,请参阅数据logging一直想知道的内容 (pdf文件 – 直接链接到第6页,标题为H. Datalog和Prolog )。

4)为了logging: RA (以及它们的等价安全TRC和安全Datalog W / Orecursion)不是有意图灵完成的,以避免永不结束的查询。

历史笔记: Prolog和Codd的关系代数是在不同的背景下(70年代末60年代末)构思的–Colmerauer构想了Prolog的自然语言处理,Codd将RA理解为Relational DBMS的理论基础。 因此,Prolog-Datalog-RA-SQL之间的任何理论联系必然是事后build立 ,并且暗示它们都是基于一阶谓词演算 (又名一阶逻辑 )。

Prolog和SQL都基于一阶逻辑,但是SQL表是简单的二元关系,而Prolog谓词是Horn子句。

这不是一些模糊的理论观点。 SQL二元关系是事实陈述,forms如下:

f(A,B,C … N)

其中f是关系的名称, A … N是其variables。 Prolog二元关系的含义如下:

A < – B,C,D … N

A … N本身就是Horn子句。 SQL关系是描述数据的有效方法。 序言关系描述了数据之间的复杂关系,它们本身作为数据存储。

理解在Prolog中,数据和操作之间没有分离是很重要的。 Prolog的事实,规则和查询都是Horn子句,因此数据是大多数大学课程翻译时丢失的东西。 Prolog不像C,而是用事实而不是variables和规则而不是函数。 另一方面,SQL很像没有规则或查询的Prolog。

SQL查询也是逻辑谓词,但SQL查询不存储在数据库本身中。 相反,它们被用来从事实数据库中提取数据集。 您可以将查询作为表格行存储在SQL数据库中,但不能以此格式执行。

Prolog查询像任何其他Prolog谓词一样存储在数据库中,因为它们就像任何其他Prolog谓词一样。 查询是forms的Horn子句:

< – B,C,D … N

所以暗示先例,但没有先例,因此总是假的。 事实是有先例但没有先例的Horn条款,forms如下:

A < –

所以总是如此。 Prolog通过驳斥certificate了一个查询:如果它找不到certificate它的事实(或规则),它将声明目标是真实的,因为查询总是假的。 在这个过程中,绑定了一些variables,所以可以构造结果集,就像SQL对SELECT查询所做的一样。

现代SQL数据库pipe理系统具有存储过程和stream程控制语言等function,所以SQL可以用于推断(而不是你在SQL中进行推理)。 Prolog已经准备好了一个推理引擎,它被调整到它的Horn子句的数据库中,因为这是一种有效的方式来对数据库中的二元关系进行推理(而不是,因为它很漂亮)。

Prolog的homoiconic性质(数据是操作是数据)意味着新的新数据必须被添加到数据库,因此到程序,因为数据库是程序。 所以每当一个新的事实被添加到它的数据库(通常使用assert / 1),整个程序必须被反编译。 这是一个庞大的PITA,使得Prolog在存储大型数据集方面效率低下,尽pipe没有理由说为什么在数据检索时效率不高,而且Prolog系统为此使用与SQL系统相同的algorithm。 另一方面,SQL非常适合存储和检索。

最后,Prolog还有一些SQL没有的特性,即超模式匹配称为统一,否定为失败以及便于列表处理和语法声明(定义语句表示法)的语法元素。 这些只是一个令人高兴的事故,并且大部分都被添加到了语言中,因为它们在第一次创build时就很stream行(感谢LISP)。 SQL最近得到了recursion查询,所以Prolog不能再吹嘘它了。

当然,这两种语言在I / O和math上都很弱,尽pipe至less你可以在Prolog中做一些算术运算,而不必一直把头发拉出来。

所以,实际上,Prolog和SQL与C和Haskell非常相似。 它们都是基于相同的抽象概念,一阶逻辑(比如C和Haskell都是基于代数的),但事情变得非常不同了。 而且,从语言devise的angular度来看,SQL往往是断裂的,具有许多不同的语言特征(包括查询,数据操纵语言等)。 Prolog的devise非常一致,所以整个语言实际上只是谓词和一些标点符号。

对我来说,最重要的区别是:我不喜欢SQL,但我必须使用它。 我喜欢Prolog,但是我不能在工作中使用它。 人生是不公平的 :)

在我看来,主要区别在于SQL从表中检索行,也就是从与过滤条件相符的实例化对象的有限集合中检索行。 另一方面,Prolog在理论上给你所有满足条件的可实例化对象。 而在Prolog中,您也可以从有限集合中检索实体,但是在SQL中,您无法从理论上无限集合中获取所有值。

当你开始使用它们的时候,我认为有很多不同之处。 记住,由于术语的变化,过去被称为同一事物的东西现在意味着非常不同的东西。

非常广泛的差异概述。

SQL语句对关系数据库起作用,并从该数据库中查询(请求)数据,对数据进行更改,结果用语言精确表示,而在Prolog中,您定义事实并且逻辑引擎根据现有数据生成新事实事实。 新数据(事实)通过评估创build。

他们都使用所谓的查询(但他们完全不同),他们都有数据(但用不同的方式)。

SQL和Prolog的用例也完全不同。 在Prolog中存储地址列表永远不会有意义,但这正是SQLdevise的目的。

简单地说SQL就是用来访问数据存储的,Prolog是一个expression式计算器。

我认为主要区别在于Prolog是一种查询语言,用于将复杂的模式与简单事实的数据库进行匹配。 另一方面,SQL仅限于关系数据库。

这将使你开始: 编程在Prolog

很早之前,你可以阅读这个:

Prolog作为一种编程语言有点不寻常。 它可以理解为一种标准的程序语言,具有两个不同寻常的特性。 这是一种程序语言,如帕斯卡尔或阿尔戈尔。 一种程序语言通过编写执行特定操作的程序来编程。 通过使用原始语句和调用其他过程来指定一个过程。 Prolog程序只有局部variables,程序可以使用或产生的所有信息必须通过它的parameter passing。

C可以被看作是一种程序语言,通过思考使用它而没有function; 即所有函数都返回void,并且信息只通过parameter passing给函数。

在Prolog中,过程被称为谓词。 Prolog的两个不寻常的方面是:

1. Prolog有分配一次的variables,2. Prolog是不确定的。

请享用。

xonix,你需要更多的开发经验来说是否可以在sql中做的事情。

以下是您的fibo系列至less2种解决scheme。 一个使用Stored Procedure ,另一个使用CTE 。 拿你的select。

方法1

 declare @a int, @b int, @c int, @i int, @N int = 10 select @a=0, @b=1, @i=0, @c=0 print @a print @b while @i < @N Begin set @c=@a+@b print @c set @i=@i+1 set @a=@b set @b=@c end 

方法2

 WITH FibonacciNumbers (RecursionLevel, FibonacciNumber, NextNumber) AS ( -- Anchor member definition SELECT 0  AS RecursionLevel, 0  AS FibonacciNumber, 1  AS NextNumber UNION ALL -- Recursive member definition SELECT  a.RecursionLevel + 1       AS RecursionLevel, a.NextNumber           AS FibonacciNumber, a.FibonacciNumber + a.NextNumber AS NextNumber FROM FibonacciNumbers a WHERE a.RecursionLevel < 10 ) -- Statement that executes the CTE SELECT 'F' + CAST( fn.RecursionLevel AS VARCHAR) AS FibonacciOrdinal, fn.FibonacciNumber, fn.NextNumber FROM FibonacciNumbers fn; GO 

只是几个想法:

  1. SQL是一种查询语言(可能任意复杂)访问(关系)数据,它不是一种编程语言。
  2. 即使将SQL视为编程语言,也不是图灵完整的。 我很难想象sql查询返回1到100(例如)的总和。
  3. SQL是用于访问/操作(DML) 数据库的语言,其中Prolog是用于处理知识库 (&规则parsing引擎,原因)的语言。 事实上,Prolog不再是简单的统一回溯
  4. 这并不是说SQL和Prolog的应用领域完全不同,它们是有效的(常规)数据存储和AI /符号计算/parsing/专家系统/约束求解器/…/等等。