prolog中数据管理的最佳实践

lur*_*ker 9 database prolog inference-engine

我刚刚参与使用Prolog来处理的不仅仅是最简单的数据形式(事实),而且正在寻找经验丰富的Prologers的一些指导......

如果我想动态管理数据或事实,我有几个主要选择,例如:

  • 在Prolog,OR中将数据作为断言进行管理
  • 与Prolog,OR的数据库接口
  • 可能是两者的结合

如果我将事实作为Prolog中的断言来管理,我也有一个代表这些事实的最佳方式的问题.假设我有一个person名字,姓氏和年龄的人.我可以断言:

person(first_name(_), last_name(_), age(_)).
Run Code Online (Sandbox Code Playgroud)

或隐含假设人的属性是什么:

person(_, _, _).  % first name, last name, age
Run Code Online (Sandbox Code Playgroud)

如果我想将一个人与其他人联系起来,我真的需要一个人的钥匙.所以我可能倾向于断言一个人:

person(id(_), ...).  % Maintain id as a uniq person key; or done implicitly as above
Run Code Online (Sandbox Code Playgroud)

当然,现在我正在使我的Prolog断言看起来像关系数据库表条目.这让我想知道我是否采取了错误的方法并使事实的表现过于复杂化.

所以,我的问题是:在Prolog中管理中到复杂数据时是否需要考虑一些最佳实践?命名约定是它的一小部分.我读过像Prolog中的assert/retract这样的位是低效的.所以我也想知道如何处理数据组织本身,比如什么时候采用外部SQL数据库而不是Prolog-only表示.

附录

我认为,由于关系数据库使用它们的原因,在关系数据库中使用记录密钥是可取的.这意味着必须保持密钥.对于每种情况,在Prolog中手动(显式)执行此操作似乎很麻烦,那么这通常如何完成?或者我的假设是正确的?

mat*_*mat 10

考虑为谓词使用更具描述性的名称,例如:

id_fname_lname_age(_, _, _, _).

这明确表示参数是什么而不需要任何其他结构.

在我看来,命名谓词的一个好的经验法则是按照它们出现的顺序描述参数,使用以下划线分隔的声明性名称.

编辑:至于你的其他问题:与一个很好的声明性编程风格相比,它assertz/1很慢(并且还有许多其他缺点),它简单地在不需要对子句数据库进行任何修改的谓词之间传递参数.当你真的需要断言其他事实,因为你正在使用像关系数据库系统这样的Prolog时,那么assertz/1就是一种方法(其他选项在这里的其他答案中提到),并且可能在效率上与任何其他关系数据库系统相当对于许多使用场景.如前所述,一些现代Prolog系统对所有参数执行即时索引,因此您无需显式声明任何"键".

  • 有许多项目将 Prolog 用于具有大量相互关联的事实的大型数据库(参见例如 SWI-Prolog 的语义 Web 用例等)而无需求助于 SQL,因此您可能可以使用普通 Prolog 走得更远,尤其是在现代系统还执行即时索引和其他各种在许多用例中产生良好性能的技术。我认为 Prolog 事实的良好的、描述性的命名约定使得在 Prolog 中制定复杂查询比在 SQL 中更容易。 (2认同)

Cap*_*liC 6

Prolog基于关系数据模型。

然后,关系数据模型(一般而言)足以满足 Prolog,尽管就我个人而言,我怀念通过 SQL DML 获得的元数据工具。文档 - 如果可用 - 很容易不同步,并且处理与许多列的关系很痛苦,部分是因为 Prolog 是无类型的,部分是因为你不能(轻松地)“按名称调用”列 - Prolog 错过了“投影运算符” ' 可用于关系代数(当然还有 SQL)。SWI-Prolog 必须library(record)克服这个问题,但我不太喜欢它。

一般来说,当涉及到一些“现实世界”的数据建模时,比如深度嵌套的(XML/HTML/SVG/任何)表示,或者维度索引实体,比如空间和地理数据库,或者大型图形,正如当今本体所要求的那样,关系数据建模可能是不够的

您必须提供缺失的详细信息,这在技术上可能非常复杂。如果您需要一些 Prolog 引擎未提供的索引,您将陷入用低级语言(通常是 C)编写困难接口的困境。那么为什么不使用一些更简单的语言,以及基于复杂数据建模的随时可用(和调试)的库呢?他们有很多。

因此,SWI-Prolog 的开发是由实用性驱动的,而不是 Prolog 应用程序最初关注的抽象语言(自然的和合成的)研究,它具有专门的接口,例如用于 Web 和本体的接口。请参阅页面,其中大多数都是精心设计的复杂数据接口。

从软件工程的角度来看,此类接口的可用性会对语言选择产生影响。为了强调 SWI-Prolog 的声誉有多高,它最近被提名(与 Python 一样)荷兰 ICT 创新奖

持续的开发 - 比如在基于 DCG 的 HTML 生成中嵌入 javascript 的准引用 - 以及来自 SWI-Prolog 邮件列表的大力支持都是巨大的增值!

就我个人而言,我致力于通过将其应用于实际任务来学习RDF建模。


小智 6

在使用断言/撤回时,还没有人解决您关于效率的问题。

对于 SWI-Prolog,简而言之,事实索引(just-in-time 意味着第一次查询时),并且查找非常有效(基于哈希表)。默认情况下,索引仅针对第一个参数,但有内置函数可以解决这个问题(我想将所有内容都保持在规范化的形式会很痛苦)。

经验法则似乎是,只要您的所有数据都适合内存,并且您不经常断言/撤回,它就是最佳选择。您可以使用 library(persistency) 使谓词持久化。

至于约束和触发器等,我想您必须编写自己的谓词,但是使用 Prolog 的语法,这不应该比在 SQL 中定义这些更冗长(尽管我在关系数据库方面的经验非常有限,所以我可能会说从我的屁股里出来)。