SWI Prolog list subtract gives error: Out of local stack

SWI Prolog list subtract gives error: Out of local stack

我是 运行 一些使用减法函数的 Prolog 规则,在堆栈跟踪中,我发现错误来源是这样的:

lists:subtract([b, d | _], [b, d] , [r]) ? creep
ERROR: Out of local stack

原来的电话是:

member(b, X), member(d, X), subtract(X, [b, d], [r]).

预期输出为 [b, d, r]

我是 Prolog 的新手,无法理解错误的来源以及如何修复它。请帮忙。

来自 SWI Prolog manual :

The library(lists) contains a number of old predicates for manipulating sets represented as unordered lists, notably intersection/3, union/3, subset/2 and subtract/3. These predicates all use memberchk/2 to find equivalent elements. As a result these are not logical while unification can easily lead to dubious results.

你遇到这个问题是因为 subtract 不是纯粹的,需要实例化它的前两个参数,因此 + 在它的文档中签名。

subtract(+Set, +Delete, -Result)

您可以改用 union/3

union(+Set1, +Set2, -Set3)

您可以在here.

中了解更多关于其他模式指示器的信息

unable to understand the source of error and how to fix it.

只需进行查询并单独查看前两个目标:

?- member(b, X), member(d, X).
   X = [b,d|_A]
;  X = [b,_A,d|_B]
;  X = [b,_A,_B,d|_C]
;  X = [b,_A,_B,_C,d|_D]
;  X = [b,_A,_B,_C,_D,d|_E]
;  ... .

仅仅这两个目标就已经产生了无数个答案。因此,无论接下来发生什么,您的查询都不会终止。偶然的机会,你可能碰巧得到了一个解决方案,但更多的时候你会以某种循环结束。

所以首先你需要以某种方式解决这个问题。

再考虑SWI中subtract/3的含义:

?- subtract([b,d,r], [b,d], [r]).
true.

?- subtract([b,d,X], [b,d], [r]).
false. % ?? why not X = r?

单从这一点就可以看出subtract/3不是关系。所以你不能将它用作关系,比如 append/3.

要解决此问题并尽可能接近您的原始查询,请使用 library(reif)library(lambda):

?- S1=[b,d,X], S2 = [b,d], tpartition(S2+\E^memberd_t(E,S2),S1,_,[r]).
   S1 = [b,d,r], X = r, S2 = [b,d].