等待谓词 Prolog 结束
Wait the end of a predicate Prolog
我有一个谓词 list_moves(Move)
,它给出了游戏的所有可能动作。然后我有以下谓词:
find_best_move:-
nb_setval(best,0),
list_moves(NewMove),
nb_getval(best,OldMove),
better(OldMove,NewMove).
better(OldMove, NewMove):-
NewMove > OldMove,
nb_setval(best,NewMove), !.
better(_,_).
get_best_move(Move):-
find_best_move,
nb_getval(max,Move).
当我调用 get_best_move(Move)
时,我只想得到一步:最好的一步。问题是:我确实得到了最好的着法,但我也得到了很多其他着法。
例子:
假设我从 list_moves(Move)
开始按此顺序执行以下移动(值越大,移动越好):
move1 : 0
move2 : 1
move3 : 2
move4 : 1
move5 : 2
move6 : 0
我将通过调用 get_best_move(Move)
得到以下结果:
移动1
move2
move3
move3
move3
move3
问题是:我只想获得 move3 一次。我不关心 move1-2,也不关心 move3 的其他 3 次出现。
我认为一种解决方案是 "wait",直到 get_best_move
中的 find_best_move
调用完成,而不是对 [=15] 给出的每个答案都执行 nb_getval
=].
我该怎么做?还有其他解决方案吗?
是的,当然有解决办法。您将获得一个结果列表,因此您需要按特定谓词过滤它们,或者只取最后一个,因为您按递增顺序对它们进行排序。
Prolog 一一生成这些解决方案。有时我们希望拥有一个查询的所有解决方案,我们希望它们以一种简洁、可用的形式交给我们。 Prolog 具有三个内置谓词来执行此操作:findall
、bagof
和 setof
。我们需要先把所有的都列出来
?- findall(X,get_best_move(Move))
应该return列出[move1, move2, move3, move3, move3, move3]
然后使用最后一个函数
%% last(?List, ?Last)
%
% Succeeds when Last is the last element of List. This
% predicate is =semidet= if List is a list and =multi= if List is
% a partial list.
%
% @compat There is no de-facto standard for the argument order of
% last/2. Be careful when porting code or use
% append(_, [Last], List) as a portable alternative.
last([X|Xs], Last) :-
last_(Xs, X, Last).
last_([], Last, Last).
last_([X|Xs], _, Last) :-
last_(Xs, X, Last).
类似的东西
?- last(findall(X,get_best_move(Move)), Y)
我不知道您使用的是哪种实现,但这可能会有所帮助
我有一个谓词 list_moves(Move)
,它给出了游戏的所有可能动作。然后我有以下谓词:
find_best_move:-
nb_setval(best,0),
list_moves(NewMove),
nb_getval(best,OldMove),
better(OldMove,NewMove).
better(OldMove, NewMove):-
NewMove > OldMove,
nb_setval(best,NewMove), !.
better(_,_).
get_best_move(Move):-
find_best_move,
nb_getval(max,Move).
当我调用 get_best_move(Move)
时,我只想得到一步:最好的一步。问题是:我确实得到了最好的着法,但我也得到了很多其他着法。
例子:
假设我从 list_moves(Move)
开始按此顺序执行以下移动(值越大,移动越好):
move1 : 0
move2 : 1
move3 : 2
move4 : 1
move5 : 2
move6 : 0
我将通过调用 get_best_move(Move)
得到以下结果:
移动1
move2
move3
move3
move3
move3
问题是:我只想获得 move3 一次。我不关心 move1-2,也不关心 move3 的其他 3 次出现。
我认为一种解决方案是 "wait",直到 get_best_move
中的 find_best_move
调用完成,而不是对 [=15] 给出的每个答案都执行 nb_getval
=].
我该怎么做?还有其他解决方案吗?
是的,当然有解决办法。您将获得一个结果列表,因此您需要按特定谓词过滤它们,或者只取最后一个,因为您按递增顺序对它们进行排序。
Prolog 一一生成这些解决方案。有时我们希望拥有一个查询的所有解决方案,我们希望它们以一种简洁、可用的形式交给我们。 Prolog 具有三个内置谓词来执行此操作:findall
、bagof
和 setof
。我们需要先把所有的都列出来
?- findall(X,get_best_move(Move))
应该return列出[move1, move2, move3, move3, move3, move3]
然后使用最后一个函数
%% last(?List, ?Last)
%
% Succeeds when Last is the last element of List. This
% predicate is =semidet= if List is a list and =multi= if List is
% a partial list.
%
% @compat There is no de-facto standard for the argument order of
% last/2. Be careful when porting code or use
% append(_, [Last], List) as a portable alternative.
last([X|Xs], Last) :-
last_(Xs, X, Last).
last_([], Last, Last).
last_([X|Xs], _, Last) :-
last_(Xs, X, Last).
类似的东西
?- last(findall(X,get_best_move(Move)), Y)
我不知道您使用的是哪种实现,但这可能会有所帮助