据我了解, call_nth(:Goal, ?Nth) 返回 Goal 的第 N 个解决方案,但同时它秘密计算所有先前的解决方案(从第一个到第 (N-1) 个)并简单地忽略它们。如果我们希望将 1 到 N-1 之间的每个 X 的第 X 个解与第 (X+1) 个解进行比较,那么 call_nth 变得非常昂贵,因为它基本上一直在计算前面步骤中已经计算过的解。我想知道是否有更有效的方法来解决这种形式的问题,当然不使用 findall/3。
(一个典型的例子是下面的脚本,如果谓词中不存在 GOAL,它会找到 GOAL 或最接近的最大值。)
num(10).
num(20).
num(30).
num(40).
num(50).
search_for_goal(GOAL,RESULT):-
search_for_goal(GOAL,0,1,RESULT).
search_for_goal(GOAL,_,COUNTER,GOAL):-
call_nth(num(GOAL),COUNTER),!.
search_for_goal(GOAL,CURRENT_MAX,COUNTER,RESULT):-
call_nth(num(X),COUNTER),
COUNTER2 is COUNTER+1,
( X=<CURRENT_MAX->
search_for_goal(GOAL,CURRENT_MAX,COUNTER2,RESULT)
; search_for_goal(GOAL,X,COUNTER2,RESULT)
).
search_for_goal(_,CURRENT_MAX,COUNTER,CURRENT_MAX):-
\+call_nth(num(_),COUNTER).