2013-04-10 52 views
5

我正在为AI和Fox类型的游戏编写AI。我的一个谓词是这样的:Prolog findall/3:多个包

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)谓语?

回答

3

这个问题是可以解决建筑列表,然后分离元素,如库(pairs)确实

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

如果你的序言没有pairs_keys_values/3,很容易使用maplist或通过递归谓词写入。下面是地图列表方式:

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

感谢您回答如此之快!它像一个魅力。 – 2013-04-10 22:03:32