如果成功rule1
iff rule2
返回两个或更多结果,
rule1(X) :-
rule2(X, _).
如何计算结果,然后设置何时成功的最小值?
答案 0 :(得分:5)
如何计算结果,然后设置最小值?
目前尚不清楚结果的含义。所以我会做一些猜测。结果可能是:
解决方案。例如,目标member(X,[1,2,1])
有两个解决方案。不是三个。在这种情况下,请考虑使用setof/3
或类似的谓词。无论如何,在解决您遇到的问题之前,您应首先了解setof/3
。
答案。目标member(X,[1,2,1])
有三个答案。目标member(X,[Y,Z])
有两个答案,但无数的解决方案。
因此,如果您想确保至少有一定数量的答案,请定义:
at_least(Goal, N) :- \+ \+ call_nth(Goal, N).
call_nth/2
defined in another SO-answer。
请注意,其他SO-answers不正确:它们要么不终止,要么产生意外的实例化。
答案 1 :(得分:2)
您可以使用库(aggregate)来计算解决方案
:- 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.
编辑这是一种更有效的方法,使用global variables
的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.
来自here的call_nth。
从实际的角度来看,我认为nb_setval(vs nb_setarg)在全局变量和局部变量之间经常进行权衡。即对于某些任务可以轻易地知道接受条件的限制是什么。如果不需要,nb_setarg会更干净。
底线:更好的方法是使用call_nth,双重否定的'技巧'解决了过度的变量实例化。