Prolog findall / 3:不止一个包

时间:2013-04-10 20:59:39

标签: prolog prolog-findall

我正在为Fox和Geese类型的游戏编写AI。我的一个谓词看起来像这样:

moveFox(+PrevState, -NextState, -PegList, +VisitedStates, -NewVisitedStates)

它需要一个游戏状态并与狐狸一起移动。生成的状态与NextState统一,实际移动与PegList统一。一切都按预期工作。

我正在计算所有动作'NextState的效用得分。为了能够找到效用得分最高的州,我使用findall/3获取列表中的所有州,然后再比较他们的效用得分。

findall(NextState, moveFox(...), NextStatesList)

通过查找最大效用得分,我知道具有最高效用得分的NextState(以及其在列表中的位置)。只有一个问题,目前我还没有写任何谓词来推断NextState的移动是什么,例如:

getMove(+PrevState, +NextState, -PegList)

我宁愿使用findall/3或等同词,而不是编写这样的谓词。我的问题是,是否有某种方法可以在两个不同的列表中获得两个不同的变量。我这样想(如果有用的话):

findall([NextState, PegList], moveFox(...), [NextStatesList, MoveList])

我是否可以实现此类功能而无需运行findall/3两次(丑陋的开销)或编写getMove(+PrevState, +NextState, -PegList)谓词?

1 个答案:

答案 0 :(得分:3)

这个问题可以解决建立一个列表,然后分离元素,比如库(pairs)吗

...
findall(NextState-PegList, moveFox(...), Pairs),
pairs_keys_values(Pairs, NextStates, Pegs),
...

如果您的Prolog没有pairs_keys_values / 3,则可以使用maplist或通过递归谓词轻松编写。这是地图列表方式:

pkv(K-V, K, V).
pairs_keys_values(Pairs, Keys, Vals) :-
    maplist(pkv, Pairs, Keys, Vals).