Résoudre des Cannibales/Missionnaires à l'aide de largeur tout d'abord de recherche (BFS) en Prolog?

Je suis en train de travailler sur la résolution de la classique Missionnaires(M) et les Cannibales(C) problème, l'état de départ est de 3 M et 3 C sur la rive gauche et le but de l'état est de 3M, 3C, sur la rive droite. J'ai terminer la fonction de base dans mon programme et j'ai besoin de implemet la recherche-stratégie, tels que la BFS et DFS.

Fondamentalement, mon code est d'apprendre à partir de l'Internet. Jusqu'à présent, je peux réussi à exécuter le programme avec DFS méthode, mais j'essaie de le lancer avec BFS il retourne toujours false. C'est mon tout premier SWI-Prolog programme, je ne trouve pas où est le problème de mon code.

Voici la partie de mon code, j'espère que vous pourrez m'aider à trouver le problème de il

solve2 :-
   bfs([[[3,3,left]]],[0,0,right],[[3,3,left]],Solution),
   printSolution(Solution).

bfs([[[A,B,C]]],[A,B,C],_,[]).
bfs([[[A,B,C]|Visisted]|RestPaths],[D,E,F],Visisted,Moves) :-
   findall([[I,J,K],[A,B,C]|Visited]),
     (
       move([A,B,C],[I,J,K],Description),
       safe([I,J,K]),
       not(member([I,J,K],Visited)
     ),
     NewPaths
   ),
   append(RestPaths,NewPaths,CurrentPaths),
   bfs(CurrentPaths,[D,E,F],[[I,J,K]|Visisted],MoreMoves),
   Moves = [ [[A,B,C],[I,J,K],Description] | MoreMoves ].


move([A,B,left],[A1,B,right],'One missionary cross river') :-
   A > 0, A1 is A - 1.  
   % Go this state if left M > 0. New left M is M-1
.
.
.
.
.
safe([A,B,_]) :-
   (B =< A ; A = 0),
   A1 is 3-A, B1 is 3-B,
   (B1 =< A1; A1 =0).

- Je utiliser findall de trouver tous les chemins possibles avant d'aller au prochain niveau. Seul celui qui passe du coffre-fort() sera considérer comme possible l'état suivant. L'état de ne pas utiliser si elle existe déjà. Depuis mon programme peut s'exécuter avec DFS donc je pense qu'il n'y a rien de mal à se déplacer() et() de prédicat. Mon BFS prédicat est en train de changer la base sur mon DFS code, mais sa fonctionne pas.

findall/3 a arité 3, mais vous n'utiliser qu'un seul argument dans votre code. Vous pouvez également utiliser des variables Visisted et Visited. Sont-ils censés être de la même? Essayez l'indentation de ton code pour le rendre plus lisible, et ajouter quelques commentaires. Sinon, il est difficile de comprendre ce que vous essayez d'atteindre avec le findall/3 appel et le bloc suivant.

OriginalL'auteur Shawn Lien | 2012-03-30