I'm writing AI for a Fox and Geese type of game. One of my predicates looks like this:
moveFox(+PrevState, -NextState, -PegList, +VisitedStates, -NewVisitedStates)
It takes a game state and makes a move with a fox. The resulting state is unified with NextState
and the actual move is unified with PegList
. Everything works as expected.
I am calculating the utility score for all of the moves' NextState
. To be able to find the state with the highest utility score, I use findall/3
to get all states in a list before comparing their utility scores.
findall(NextState, moveFox(...), NextStatesList)
By finding the maximum utility score I know the NextState
(as well as its position in the list) with the highest utility score. There is only one problem, currently I haven't written any predicate to infer which move was made to come to NextState
, e.g.:
getMove(+PrevState, +NextState, -PegList)
Instead of writing such a predicate, I would much rather use findall/3
or equivalent. My question is if there is some way to get two different variables in two different lists. I'm thinking like this (if it would have worked):
findall([NextState, PegList], moveFox(...), [NextStatesList, MoveList])
Could I implement such functionality without having to either run findall/3
twice (ugly overhead) or write that getMove(+PrevState, +NextState, -PegList)
predicate?
this problem can be tackled building a list of pairs, and then separating the elements, like library(pairs) does
...
findall(NextState-PegList, moveFox(...), Pairs),
pairs_keys_values(Pairs, NextStates, Pegs),
...
If your Prolog doesn't have pairs_keys_values/3, it's easy to write either with maplist or via a recursive predicate. Here is the maplist way:
pkv(K-V, K, V).
pairs_keys_values(Pairs, Keys, Vals) :-
maplist(pkv, Pairs, Keys, Vals).