交换参数

时间:2015-11-19 17:25:32

标签: prolog

我有以下事实:

    make(product_A, product_Z, product_Y).
    make(P, X, Y) :- make(P, Y, X).

我希望确保产品product_A的半成品(即product_Z和product_Y)无论其在查询中的位置如何都将为真。

所以我想要这个查询:

make(product_A, product_Y, product_Z).

和这一个:

make(product_A, product_Z, product_Y).

应该被Prolog视为等价物(相同) - 即使我没有将这两个案例作为事实放入Prolog的数据库中。换句话说,我想让参数(product_Z和product_Y)在查询中可以交换。

但是当我把代码放在开头时,Prolog似乎重复了一个无限循环。

那我怎么能实现这个目标呢?

2 个答案:

答案 0 :(得分:6)

无限推导的原因是,只要你愿意,就可以向后(或向前)翻转参数。您可以为翻转谓词引入新名称:

cmake(A,B,C) :- make(A,B,C).
cmake(A,B,C) :- make(A,C,B).

与一次性的解决方案相比,你保持逻辑纯粹。

即使翻转参数有效,但对于两个以上的依赖项,你会指数性地炸掉搜索空间(因为你需要覆盖n个参数的所有排列)。作为替代方案,您可以将依赖关系的排序列表作为第二个参数传递。然后,您对输入进行一次排序并进行查找。

答案 1 :(得分:1)

您需要在规则中添加once,如下所示:

make(A, B, C) :- once(make(A, C, B)).

这样,它就会停止处理事实,并且不会处于无限循环中。