我已经更改了一些现有代码,但是输出不是我想要得到的。
% initialisation de la recherche
etat_initial([bidon(3,0), bidon(5,0), bidon(8,8)]).
% etat de réussite
etat_final([bidon(3,0), bidon(5,4), bidon(8,4)]).
% Prédicat transfert(+bidon(CX, VX), +bidon(CY, VY), -bidon(CX,VX1),-bidon(CY,VY1))
transfert(bidon(CX, VX), bidon(CY, VY), bidon(CX,VX1),bidon(CY,VY1)) :-
VX > 0,
VY < CY,
DeltaV is CY-VY,
Verse is min(DeltaV, VX),
VX1 is VX - Verse,
VY1 is VY + Verse.
% prédicat un_etat_suivant(+N, -NN)
% N est un noeud dont on veut calculer un voisin
% NN est un noeud voisin de N
un_etat_suivant(N, NN) :-
select(B1, N, N1),
select(B2, N1, N2),
transfert(B1, B2,B3,B4),
sort([B3,B4|N2], NN).
% Prédicat etat_suivant(+N, -LN)
% N est le noeud dont on veut connaître "les voisins"
% LN est la liste des états voisins au noeud N
etats_suivants(N, LN) :-
setof(NN, un_etat_suivant(N, NN), LN).
jarres:-
etat_initial(Init),
etape_suivante([[Init]], S),
%afficher(S,Y).
write(S),nl.
% Predicat afficher(X,Y)
% X est la liste chemin plus court
% Y est le numero de la jarres
%afficher(S,Y) :-
% Prédicat etape_suivante(+X, -S)
% X est la liste des chemins déjà parcourus
% Y est a liste des nouveaux chemins après une recherche d'un niveau supplémentaire de profondeur
etape_suivante(X, S) :-
calcule_etape_suivante(X, Y) ,
( ( recherche_terminee(Y, R), reverse(R, S))
;
etape_suivante(Y, S)
).
recherche_terminee(Y,R) :-
sublist(noeud_terminal_atteint, Y, [R |_]).
% Prédicat noeud_terminal_atteint(+Chemin)
% Chemin est une liste d'etats et on regarde le premier pour savoir
% s'il est "terminal"
noeud_terminal_atteint([Final|_]):-
etat_final(Final).
% prédicat calcule_etape_suivante(+X, -Y)
% X est la liste des chemins déjà parcoururs
% Y est la nouvelle liste de chemins obtenue à partir de X en
% ajoutant un niveau supplémentaire
% Lorsque la liste est vide, on unifie le resultat avec la liste vide
% (construction en retour de récursivité)
calcule_etape_suivante([], []).
% On calcule ici la liste des nouveaux chemins issus du premier chemin de la liste
calcule_etape_suivante([H|T], X) :-
% etape 1 : on calcule la liste des nouveaux chemins pour la liste restante
% (on a oté le premier chemin)
calcule_etape_suivante(T, X1),
% On calcule la liste des nouveaux chemins issus de H
etape_suivante_un_chemin(H, X2),
% On concatène la liste des nouveaux chemins issus de X avec ceux déjà obtenus
% par les appels précédents à calcule_etape_suivante
append(X2,X1,X).
% Prédicat etape_suivante_un_chemin(+T, -X)
% T est un chemin déjà parcouru, on ne s'intéresse qu'à son premier noeud
% X est la liste de tous les chemins obtenus à partir de T en ajoutant à chaque
% fois un noeud adjacent au premier noeud de T.
etape_suivante_un_chemin([N | L] , X) :-
etats_suivants(N, LN),
ajoute(LN,[N| L], X).
% Prédicat ajoute(+LN, +C, -X)
% LN est la liste des noeuds ajacents au premier noeud de C
% C est un chemin
% X est la liste des chemins obtenus en ajoutant un élément de LN en tête de C
% on ajoute les nouveaux noeuds au chemin
% dont ils sont issus, à condition qu'ils n'y figurent pas déjà.
ajoute([], _, []).
ajoute([H|T], L, [[H | L] | X]) :-
\+memberchk(H, L), !,
ajoute(T, L, X).
ajoute([_|T], L, X) :-
ajoute(T, L, X).
当前输出
?- jarres.
[[bidon(3,0),bidon(5,0),bidon(8,8)],[bidon(3,0),bidon(5,5),bidon(8,3)],[bidon(3,3),bidon(5,2),bidon(8,3)],[bidon(3,0),bidon(5,2),bidon(8,6)],[bidon(3,2),bidon(5,0),bidon(8,6)],[bidon(3,2),bidon(5,5),bidon(8,1)],[bidon(3,3),bidon(5,4),bidon(8,1)],[bidon(3,0),bidon(5,4),bidon(8,4)]]
true
那是正确的路径,但是我需要这个:
?- jarres.
1 -> 2
2 -> 3
3 -> 1
2 -> 3
1 -> 2
2 -> 3
3 -> 1
true.
其中
1 is the 8 jug
2 its 5 jug
and 3 its the 3 jug