4

如果返回两个或更多结果,如何实现rule1成功?rule2

rule1(X) :-
    rule2(X, _).

我如何计算结果,然后设置何时成功的最小值?

4

2 回答 2

5

我如何计算结果,然后为它设置一个最小值?

目前尚不清楚您所说的结果是什么意思。所以我会做一些猜测。结果可能是:

一个解法。例如,目标member(X,[1,2,1])有两个解决方案。不是三个。在这种情况下,请考虑使用 anysetof/3或类似的谓词。无论如何,setof/3在解决您遇到的问题之前,您应该先了解。

一个答案。目标member(X,[1,2,1])有三个答案。目标member(X,[Y,Z])有两个答案,但有无限多的解决方案。

因此,如果您想确保至少有一定数量的答案,请定义:

至少(目标,N):-
   \+ \+ call_nth(目标,N)。

call_nth/2 在另一个 SO-answer 中定义。

请注意,其他 SO 答案不正确:它们要么不终止,要么产生意外的实例化。

于 2012-11-15T09:30:39.477 回答
2

您可以使用库(聚合)来计算解决方案

:- use_module(library(aggregate)).

% it's useful to declare this for modularization
:- meta_predicate at_least(0, +).

at_least(Predicate, Minimum) :-
      aggregate_all(count, Predicate, N),
      N >= Minimum.

例子:

?- at_least(member(_,[1,2,3]),3).
true.

?- at_least(member(_,[1,2,3]),4).
false.

在此处编辑是一种更有效的方法,将 SWI-Prolog 工具用于全局变量

at_least(P, N) :-
    nb_setval(at_least, 0),
    P,
    nb_getval(at_least, C),
    S is C + 1,
    ( S >= N, ! ; nb_setval(at_least, S), fail ).

根据这个定义,P被调用N 次。(我介绍了一个服务谓词 m/2 来显示它返回的内容)

m(X, L) :- member(X, L), writeln(x:X).

?- at_least(m(X,[1,2,3]),2).
x:1
x:2
X = 2.

编辑@false评论的会计,我试过了

 ?- call_nth(m(X,[1,2,3]),2).
x:1
x:2
X = 2 ;
x:3
false.

与 call_nth 从这里

从实际的角度来看,我认为 nb_setval (vs nb_setarg ) 在全局变量和局部变量之间进行了通常的权衡。即对于某些任务,可以很容易地知道接受条件的限制是什么。如果这不是必需的,则 nb_setarg 会更干净。

底线:更好的方法显然是使用 call_nth,双重否定的“技巧”解决了不适当的变量实例化。

于 2012-11-15T07:33:38.990 回答