Prolog 使用切割提高效率

Prolog 使用切割提高效率,prolog,prolog-cut,Prolog,Prolog Cut,如果我有以下知识库,我如何在学期的父_中添加一个切口,以便如果一个X已经被确定为父亲,prolog不会试图“检查”X是否也是母亲 father_of(max,john). father_of(max,james). father_of(max,gabe). mother_of(june,john). mother_of(june,james). parent_of(X,Y) :- father_of(X,Y). parent_of(X,Y) :- mother_of(X,Y). 例如,我想要

如果我有以下知识库,我如何在学期的父_中添加一个切口,以便如果一个X已经被确定为父亲,prolog不会试图“检查”X是否也是母亲

father_of(max,john).
father_of(max,james).
father_of(max,gabe).
mother_of(june,john).
mother_of(june,james).

parent_of(X,Y) :- father_of(X,Y).
parent_of(X,Y) :- mother_of(X,Y).
例如,我想要:

(max,Y)的父母:Y=john,Y=james,Y=gabe

(六月,Y)的父母:Y=john,Y=james

对于第一个问题,我不希望prolog甚至试图检查max是否是的母亲,因为已经确定他是的父亲

我已经尝试了很多组合,包括:

parent_of(X,Y) :- father_of(X,Y),!.  <-- fixes an X and Y and thus will list only Y=john
parent_of(X,Y) :- !,father_of(X,Y). <-- works for parent_of(max,Y) but not parent_of(jane)

X,Y的父(X,Y):-X,Y的父(X,Y) 进行这样的优化是非常棘手的。Prolog在这些问题上表现得相当出色,没有任何优化

但作为一般规则:您不能简单地在程序中设置剪切,您需要提前执行各种测试。我怀疑这些测试很容易比您打算删除的开销更昂贵。这是一个尝试。老实说,我感觉不是很好,因为你应该先学习纯序言

所以我们假设没有解决方案:
?-父亲(p,u),母亲(p,u)。

(F,C)的父项:- (原子(F),\+\+是(F,\\>)的父亲! ;是的 ), (F,C)的父亲。 (M,C)的父项:- (M,C)的母亲。 这真的更好吗?也许是,也许不是


但在任何情况下,您都已经理解了一个要点:聪明的优化需要大量的测试。我相信上面的说法是正确的,但我甚至不确定这会更快。毕竟,现在有两个查找
父亲/2
,而不是一个查找
父亲/2
和一个查找
母亲/2
。原始版本可能更快…

为此,一些Prolog系统提供了“软剪切”
*->/2

parent_of(X,Y) :- father_of(X,Y) *-> true ; mother_of(X,Y).
通常用于
If*->Then;否则
,如果条件
如果
成功,则执行
然后
,只返回
如果
然后
的回溯替代解决方案。只有在
完全没有解决方案的情况下,才会执行
Else

这要求您知道谓词的模式,即调用模式。在您的例子中,如果谓词
parent\u of
的模式是
parent\u of(++,?)
,那么添加软剪切是可以的(假设名称是唯一的或只针对一种性别出现)。在(++,++)的
parent_的情况下,即使是常规切割也可以,尽管没有必要,除非数据库中有重复的事实(对称性破坏是切割的一个用例)。然而,如果您还必须满足(-,)
的父级需求,那么削减实际上会削减解决方案


一般情况下:仅当您确定删除的搜索树分支不包含任何解决方案,或仅包含您不感兴趣的对称解决方案时,才使用剪切。

您的解决方案不是OP要求的。OP询问“如果一个X已经被确定为父亲,Prolog不会试图“检查”X是否也是母亲”。现在考虑<代码> x <代码>为父,<代码> y < /代码>一些无关的人:您失败了,尝试<代码>妈妈/ 2 < /代码>…在任何情况下,好的多参数索引可能要好得多…OP的示例是(++,-)
的父对象,所以我想说我的解决方案正是OP所要求的。正如我所说的,这取决于谓词所使用的模式。你所说的
++
是什么意思?我从来没见过这个。我知道
+
。而
-
的确切含义是什么?它有几个含义。如何确保这两种情况?
+
:完全实例化,
+
:实例化,但可能只是部分实例化。来自ECLiPSe,我总是发现这是一个有用的区别,即使它不是ISO,正如我现在意识到的<代码>-
:调用时解除绑定。确保ISO的意思当然很难,我想这就是为什么它没有被广泛使用的原因。你知道为什么你认为ISO的意思很难。在ISO中,(模板和)模式在这里产生相应的错误。没有含糊不清的地方。但在另一种情况下,
-
至少有两种不同的含义:论点没有影响,但可能是无价值的;或者它必须是免费的。顺便说一句,
+
在哪里定义?在询问之前我做了一些搜索。。。
parent_of(X,Y) :- father_of(X,Y) *-> true ; mother_of(X,Y).