кувшин для воды в прологе - PullRequest
0 голосов
/ 04 октября 2011

Это проблема с кувшином для воды.Чем больше ведро содержит 5, тем меньше - 3. Я хочу получить 4 в большем ведре.

Проблема в том, что когда я бегу, я не могу получить ответ, выдает ошибку.Это не кажется очевидной ошибкой, алгоритм прост и понятен.

Может ли кто-нибудь помочь мне выяснить, что с ним не так?

check_safe(X,Y):- X>=0,X=<3,Y>=0,Y=<5.

%empty the 3 bucket

move(state(X,Y),state(0,Y)):- X>0,check_safe(0,Y).

%empty the 5 bucket

move(state(X,Y),state(X,0)):- Y>0,check_safe(X,0).

%fill the 3 bucket

move(state(X,Y), state(3,Y)):- X<3, X>=0,check_safe(3,Y).

%fill the 5 bucket

move(state(X,Y),state(X,5)):- Y>=0, Y<5,check_safe(X,5).

%transfer from 3 to 5 until the larger bucket is full

move(state(X,Y),state(NewX,5)):- X+Y>= 5, X>0,Y>=0, NewX=X+Y-5,check_safe(NewX,5).

%transfer from 3 to 5 until the smaller bucket is empty

move(state(X,Y),state(0,NewY)):- X+Y<5, X>0,Y>=0, NewY=X+Y,check_safe(0,NewY).

%transfer from 5 to 3 until the smaller is full

move(state(X,Y),state(3,NewY)):- Y>0,X>=0,X+Y>=5, NewY=Y+X-3,check_safe(3,NewY).

%transfer from 5 to 3 until the larger is empty

move(state(X,Y),state(NewX,0)):-Y>0,X>=0, X+Y<5, NewX=Y+X,check_safe(NewX,0).


path(X,X,_,[X]).
path(X,Y,BeenStates,Path):-
    move(X,Somewhere),not(member(Somewhere,BeenStates)),
    path(Somewhere,Y,[Somewhere|BeenStates],Path2), Path = [X|Path2].


puzzle:- path(state(0,0),state(0,5),[state(0,0)],PathList),X>=0,X=<5,
    writeOut(PathList).

% Here's an easy little predicate for printing a list.
writeOut([]).
writeOut([H|T]):-write(H),nl, writeOut(T).

1 Ответ

5 голосов
/ 04 октября 2011

Вы не используете "is" для назначений.

Ваш предикат puzzle\0 имеет две несвязанные переменные: X & Y.

А ваши path\4 предикаты ошибочны.

Попробуйте это:

path([state(X, 4)|Xs],[state(X, 4)|Xs]):- !.
path([X|Xs],Rs):-
    move(X,Y),not(member(Y,[X|Xs])),
    path([Y,X|Xs],Rs).

puzzle:- path([state(0,0)],PathList),
    write(PathList), nl, fail.

Ниже мое решение этой проблемы:

move(s(X,Y),s(Z,5)) :- Z is X - (5 - Y), Z >= 0.
move(s(X,Y),s(Z,0)) :- Z is X + Y, Z =< 3.
move(s(X,Y),s(3,Z)) :- Z is Y - (3 - X), Z >=0.
move(s(X,Y),s(0,Z)) :- Z is X + Y, Z =< 5.

move(s(0,Y),s(3,Y)).
move(s(X,0),s(X,5)).
move(s(X,Y),s(X,0)) :- Y > 0.
move(s(X,Y),s(0,Y)) :- X > 0.

moves(Xs) :- moves([s(0,0)],Xs).
moves([s(X0,Y0)|T], [s(X1,4),s(X0,Y0)|T])
    :- move(s(X0,Y0),s(X1,4)), !.
moves([s(X0,Y0)|T],Xs) :-
    move(s(X0,Y0),s(X1,Y1)), 
    not(member(s(X1,Y1),[s(X0,Y0)|T])),
    moves([s(X1,Y1),s(X0,Y0)|T],Xs).

?- moves(Xs), write(Xs), nl, fail.

Я получаю эти решения:

[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(1,5),s(3,3),s(0,3),s(3,0),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(3,5),s(3,0),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,2),s(0,5),s(0,0)]
[s(3,4),s(2,5),s(2,0),s(0,2),s(3,2),s(0,5),s(0,0)]
[s(0,4),s(3,1),s(0,1),s(1,0),s(1,5),s(3,3),s(0,3),s(3,0),s(3,5),s(0,5),s(0,0)]

Очевидно, что вторым по длине, будучи самым коротким, является лучшим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...