1

我正在实现一个 Prolog 解释器,我想包含一些内置的数学函数(sum、product 等)。例如,我希望能够使用这样的知识库进行计算:

NetForce(F) :- Mass(M), Acceleration(A), Product(M, A, F)
Mass(10) :- []
Acceration(12) :- []

那么我应该能够进行类似的查询?NetForce(X)。我的问题是:在我的解释器中构建这样的功能的正确方法是什么?

特别是,我遇到的问题是,为了评估Sum,Product等,必须首先评估它们的所有参数(即绑定到数字常量)。例如,虽然上面的代码应该正确评估,但置换规则:

NetForce(F) :- Product(M, A, F), Mass(M), Acceleration(A)

不会,因为M并且在处理术语A时不受约束。Product我目前的方法是简单地重新排序术语,以便数学表达式最后出现。这在简单的情况下有效,但看起来很笨拙,我希望在具有多个数学术语或递归的情况下会出现问题。有更好的解决方案吗?

4

3 回答 3

2

您所描述的功能作为约束扩展存在于现有系统中。有理数之上有 CLP(Q),实数之上有 CLP(R) - 实际上是浮动的,最后但并非最不重要的 CLP(FD) 通常扩展到 CLP(Z)。参见例如 library(clpfd)

在任何情况下,从头开始一个 Prolog 实现都将是一项艰巨的工作,您将没有时间调查您想要实现的内容,因为您将被低得多的细节所淹没。因此,您将不得不使用更经济的方法并明确您真正想要做什么。

您可能会在现有系统中研究和实现约束语言。或者您可能想使用基于元解释器的方法。或者,也许您想从头开始实现一个 Prolog 系统。但不要指望你能在这一切中取得成功。

并为您节省另一项工作:重用现有的标准语法。您使用的语法需要您构建一个额外的解析器。

于 2013-11-14T20:59:30.850 回答
1

您可以使用协同程序来延迟对产品的评估:

product(X, A, B) :- freeze(A, freeze(B, X is A*B))

freeze/2延迟对其第二个参数的评估,直到其第一个参数成立。像这样嵌套使用,它只X is A*B在两者之后评估A并且B绑定到实际术语。

(免责声明:我不是高级 Prolog 主题的专家,可能有更简单的方法可以做到这一点 - 例如,我认为 SICStus Prolog 有“块声明”,它以更简洁的方式做几乎相同的事情,并且概括了谓词的所有声明。)

于 2013-11-14T21:07:48.803 回答
0

您的谓词不会独立于子句顺序,这非常重要。您需要确定谓词的使用模式 - NetForce() 的使用模式是什么?如果我要设计一个像 Force 这样的谓词,我会做类似的事情

force(Mass,Acceleration,Force):- Force is Mass * Acceleration.

这有一个使用模式+,+,-意味着你给我质量和加速度,我会给你力量。

否则,您将根据定义的事实来统一变量,如果您首先将它们传递给 Product,它们将继续统一和统一,您将永远不会停止。

于 2013-11-14T20:50:07.547 回答