Пазл 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]),

Другие вопросы по тегам