我正在实现一个Prolog解释器,我想要包含一些内置的数学函数(求和,产品等)。例如,我希望能够使用像这样的知识库进行计算:
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
字词时未受约束。我目前的方法是简单地重新排序术语,以便数学表达式出现在最后。这在简单的情况下有效,但看起来很糟糕,我希望在有多个数学术语或递归的情况下出现问题。有更好的解决方案吗?
答案 0 :(得分:2)
您描述的功能在现有系统中作为约束扩展存在。在理性上有CLP(Q),在实数上有CLP(R) - 实际上是浮点数,最后但并非最不重要的是CLP(FD),它经常扩展到CLP(Z)。例如,参见
library(clpfd)
在任何情况下,从头开始执行Prolog都将是一项非常重要的工作,您将没有时间调查您要实现的内容,因为您将被更低级别的详细信息所淹没。所以你必须使用更经济的方法,并澄清你真正想做的事情。
您可以在现有系统中学习和实施约束语言。或者你可能想要use a meta-interpreter based approach。或者您可能希望从头开始实施Prolog系统。但是不要指望你在所有这些方面取得成功。
为了节省您的额外努力:重用现有的标准语法。您使用的语法需要您构建额外的解析器。
答案 1 :(得分:1)
您可以使用coroutining来延迟产品的评估:
product(X, A, B) :- freeze(A, freeze(B, X is A*B))
freeze/2
延迟了对第二个参数的评估,直到它的第一个参数为基础。像这样嵌套使用,它只在X is A*B
和A
绑定到实际术语后才评估B
。
(免责声明:我不是高级Prolog主题的专家,可能有更简单的方法来做到这一点 - 例如我认为SICStus Prolog有“块声明”,它以更简洁的方式做同样的事情并推广了谓词的所有声明。)
答案 2 :(得分:0)
您的谓词不会独立于子句,这非常重要。您需要确定谓词的使用模式 - NetForce()的使用模式是什么?如果我正在设计一个类似Force的谓词,我会做类似
的事情force(Mass,Acceleration,Force):- Force is Mass * Acceleration.
这个使用模式为+,+, - 意味着你给我质量和加速度,我会给你力量。
否则,您依赖于您已定义的事实来统一您的变量,如果您首先将它们传递给产品,它们将继续统一和统一,您永远不会停止。