Пазл SWI Пролог Водяной кувшин
Я здесь впервые, и я знаю, что уже есть сообщения на эту тему, но, похоже, я не так кодирую. Я просто продолжаю получать ответ ложный.
Я вхожу: solve(0,0).
Результат false.
Код.
solve(5,_).
solve(X,Y):- X < 7,
\+ member((7,Y),L),
concat(E,[(X,Y)],L),
write('Fill 7 litre jug from tap.\n'),
solve(7,Y).
solve(X,Y):- Y < 4,
\+ member((X,4),L),
concat(E,[(X,Y)],L),
write('Fill 4 litre jug from tap.\n'),
solve(X,4).
solve(X,Y):- X+Y >= 7,
Y > 0,
Z is Y - (7 - X),
\+ member((7,Z),L),
concat(E,[(X,Z)],L),
write('Fill 7 litre jug with 4 litre jug.\n'),
solve(7,Z).
solve(X,Y):- X+Y >= 4,
X > 0,
Z is X - (4 - Y),
\+ member((Z,4),L),
concat(E,[(Z,Y)],L),
write('Fill 4 litre jug with 7 litre jug.\n'),
solve(Z,4).
solve(X,Y):- X+Y < 4,
Y > 0,
Z is X + Y,
\+ member((Z,0),L),
concat(E,[(Z,Y)],L),
write('Empty 4 litre jug into 7 litre jug.\n'),
solve(Z,0).
solve(X,Y):- X+Y < 7,
X > 0,
Z is X+Y,
\+ member((0,Z),L),
concat(E,[(X,Z)],L),
write('Empty 7 litre jug into 4 litre jug.\n'),
solve(0,Z).
solve(X,Y):- X > 0,
\+ member((0,Y),L),
concat(E,[(X,Y)],L),
write('Empty 7 litre jug.\n'),
solve(0,Y).
solve(X,Y):- Y > 0,
\+ member((X,0),L),
concat(E,[(X,Y)],L),
write('Empty 4 litre jug.\n'),
solve(X,0).
member(X,[X|L]).
member(X,[L|L]):-
member(X,L).
concat([],L,L).
concat([X|A],B,[X|L]):-
concat(A,B,L).
Буду признателен за любую оказанную помощь. Благодарю.
1 ответ
Я думаю, что вы хотите сделать простой поиск в глубину с обходом цикла. По крайней мере, я принимаю проверку члена как проверку существующего цикла в поиске.
Теперь ваш код для предиката solve/2
и это гласит следующее:
[..]
solve(X,Y):- X+Y < 4,
Y > 0,
Z is X + Y,
\+ member((Z,0),L),
concat(E,[(Z,Y)],L),
write('Empty 4 litre jug into 7 litre jug.\n'),
solve(Z,0).
[..]
Проблема в том, что вы не передаете L и E. При обращении к тексту пролога вы также должны получить предупреждение, которое, вероятно, скажет, что E - это переменная-одиночка.
Я думаю, решение, которое использует предикат solve/3
вместо предиката solve/2
будет работать лучше. Вы можете передать уже посещенные состояния в третьем аргументе. Код будет выглядеть следующим образом:
[..]
solve(X,Y,L):- X+Y < 4,
Y > 0,
Z is X + Y,
\+ member((Z,0),L),
concat(E,[(Z,Y)],L),
write('Empty 4 litre jug into 7 litre jug.\n'),
solve(Z,0,E).
[..]
Надеюсь это поможет.
до свидания
PS: concat/3 не нужен, просто скажите E = [(Z,0)|L]
или полностью исключить уравнение E и просто измените вызов решения / 3 в теле, чтобы solve(Z,0,[(Z,0)|L])
,