2013-04-10 21 views
5

Piszę sztuczną inteligencję dla gry typu Fox i Gęsi. Jeden z moich predykatów wygląda następująco:Prolog findall/3: więcej niż jedna torebka

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

To trwa stan gry i wykonuje ruch z lisem. Stan wynikowy jest zunifikowany z NextState, a rzeczywisty ruch jest zunifikowany z PegList. Wszystko działa zgodnie z oczekiwaniami.

Obliczam wynik narzędzia dla wszystkich ruchów "NextState. Aby znaleźć stan o najwyższym wyniku użyteczności, używam findall/3, aby uzyskać wszystkie stany na liście przed porównaniem ich wyników użytkowych.

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

Znajdując maksymalną ocenę użytkową Znam NextState (a także swoją pozycję na liście) z najwyższym wynikiem użytkowego. Jest tylko jeden problem, aktualnie nie pisałem żadnej orzecznik aby wywnioskować, który powstał ruch przyjść do NextState, np .:

getMove(+PrevState, +NextState, -PegList) 

zamiast pisać takie orzeczenie, Chętniej używać findall/3 lub równoważny. Moje pytanie brzmi, czy jest jakiś sposób na uzyskanie dwóch różnych zmiennych na dwóch różnych listach. Ja myślę tak (jeśli byłoby to działało):

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

można zaimplementować taką funkcjonalność bez konieczności uruchom findall/3 dwukrotnie (brzydki overhead) lub napisać, że getMove(+PrevState, +NextState, -PegList) orzecznika?

Odpowiedz

3

problem ten można rozwiązać budując listę par, a następnie oddzielenie elementów, takich jak biblioteki (pairs) robi

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

Jeśli Prolog nie posiada pairs_keys_values ​​/ 3, to łatwo Napisz albo z listą map lub z predykatem rekurencyjnym. Oto lista maplist:

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

Dzięki za odpowiedź tak szybko! To działało jak czar. –

Powiązane problemy