如果返回两个或更多结果,如何实现rule1
成功?rule2
rule1(X) :-
rule2(X, _).
我如何计算结果,然后设置何时成功的最小值?
我如何计算结果,然后为它设置一个最小值?
目前尚不清楚您所说的结果是什么意思。所以我会做一些猜测。结果可能是:
一个解法。例如,目标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 答案不正确:它们要么不终止,要么产生意外的实例化。
您可以使用库(聚合)来计算解决方案
:- 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,双重否定的“技巧”解决了不适当的变量实例化。