/* Программа для решения задачи о волке, козе и капусте. */
/* Начальное и конечное состояние */
initial_state( 'Исходное состояние: все находятся на левом берегу' ,
wgc( left, [ 'волк' , 'коза' , 'капуста' ] , [ ] ) ) .
final_state( wgc( right, [ ] , [ 'волк' , 'коза' , 'капуста' ] ) ) .
/* Определение возможности перехода из состояния в состояние */
move( wgc( left, L, _) , Cargo) :-
member( Cargo, L) .
move( wgc( right, _, R) , Cargo) :-
member( Cargo, R) .
move( wgc( _, _, _) , none) . % Перевозка без груза
/* Поиск состояния, достижимого из заданного */
update( wgc( Boat, L, R) , Cargo, wgc( NewBoat, NewL, NewR) ) :-
update_boat( Boat, NewBoat) ,
update_banks( Cargo, Boat, L, R, TempL, TempR) ,
sort( TempL, NewL) ,
sort( TempR, NewR) .
/* Изменение местонахождения лодки */
update_boat( left, right) .
update_boat( right, left) .
/* Выбор груза для перевозки (Уже используется встроенный member, select не нужен) */
/* Порядок сортировки (используем встроенный предикат @< для сравнения атомов) */
/* Изменение состава обитателей берегов. */
update_banks( none, _, L, R, L, R) . % Без груза
update_banks( Cargo, left, L, R, NewL, [ Cargo| R] ) :-
select( Cargo, L, NewL) .
update_banks( Cargo, right, L, R, [ Cargo| L] , NewR) :-
select( Cargo, R, NewR) .
/* Допустимость состояния */
legal( wgc( _, L, R) ) :-
safe( L) ,
safe( R) .
safe( List) :-
not( ( member( волк, List) , member( коза, List) , not( member( farmer, List) ) ) ) ,
not( ( member( коза, List) , member( капуста, List) , not( member( farmer, List) ) ) ) .
/* solve(State, Path) - Найти путь от начального состояния до конечного */
solve( State, [ State] ) :-
final_state( State) .
solve( State, [ State | RestPath] ) :-
move( State, Cargo) , /* Найти допустимый ход */
update( State, Cargo, NextState) , /* Получить следующее состояние */
legal( NextState) , /* Убедиться что состояние допустимо */
not( member( NextState, [ State | RestPath] ) ) , /* Проверка на зацикливание */
solve( NextState, RestPath) .
/* Добавим предикат для запуска поиска решения */
solve_problem( Path) :-
initial_state( _, InitialState) ,
append( [ InitialState] , Path2, Path) ,
solve( InitialState, Path2) .
/* Добавим правило, чтобы фермер всегда был с лодкой */
member( X, [ X| _] ) .
member( X, [ _| T] ) :-
member( X, T) .
update_banks( none, left, L, R, L1, R1) :-
select( farmer, L, L2) ,
L1 = L2,
R1 = R.
update_banks( none, right, L, R, L1, R1) :-
select( farmer, R, R2) ,
R1 = R2,
L1 = L.
move( wgc( left, L, _) , Cargo) :-
member( Cargo, L) ,
member( farmer, L) .
move( wgc( right, _, R) , Cargo) :-
member( Cargo, R) ,
member( farmer, R) .
initial_state( 'Исходное состояние: все находятся на левом берегу' ,
wgc( left, [ farmer, 'волк' , 'коза' , 'капуста' ] , [ ] ) ) .
/* Примеры вызовов: */
/* ?- solve_problem(Path). */
/* ?- print(Path). */
Lyog0J/RgNC+0LPRgNCw0LzQvNCwINC00LvRjyDRgNC10YjQtdC90LjRjyDQt9Cw0LTQsNGH0Lgg0L4g0LLQvtC70LrQtSwg0LrQvtC30LUg0Lgg0LrQsNC/0YPRgdGC0LUuICovCgovKiDQndCw0YfQsNC70YzQvdC+0LUg0Lgg0LrQvtC90LXRh9C90L7QtSDRgdC+0YHRgtC+0Y/QvdC40LUgKi8KaW5pdGlhbF9zdGF0ZSgn0JjRgdGF0L7QtNC90L7QtSDRgdC+0YHRgtC+0Y/QvdC40LU6INCy0YHQtSDQvdCw0YXQvtC00Y/RgtGB0Y8g0L3QsCDQu9C10LLQvtC8INCx0LXRgNC10LPRgycsCiAgICAgICAgICAgICAgd2djKGxlZnQsIFsn0LLQvtC70LonLCAn0LrQvtC30LAnLCAn0LrQsNC/0YPRgdGC0LAnXSwgW10pKS4KCmZpbmFsX3N0YXRlKHdnYyhyaWdodCwgW10sIFsn0LLQvtC70LonLCAn0LrQvtC30LAnLCAn0LrQsNC/0YPRgdGC0LAnXSkpLgoKLyog0J7Qv9GA0LXQtNC10LvQtdC90LjQtSDQstC+0LfQvNC+0LbQvdC+0YHRgtC4INC/0LXRgNC10YXQvtC00LAg0LjQtyDRgdC+0YHRgtC+0Y/QvdC40Y8g0LIg0YHQvtGB0YLQvtGP0L3QuNC1ICovCm1vdmUod2djKGxlZnQsIEwsIF8pLCBDYXJnbykgOi0KICAgIG1lbWJlcihDYXJnbywgTCkuCgptb3ZlKHdnYyhyaWdodCwgXywgUiksIENhcmdvKSA6LQogICAgbWVtYmVyKENhcmdvLCBSKS4KCm1vdmUod2djKF8sIF8sIF8pLCBub25lKS4gICUg0J/QtdGA0LXQstC+0LfQutCwINCx0LXQtyDQs9GA0YPQt9CwCgoKLyog0J/QvtC40YHQuiDRgdC+0YHRgtC+0Y/QvdC40Y8sINC00L7RgdGC0LjQttC40LzQvtCz0L4g0LjQtyDQt9Cw0LTQsNC90L3QvtCz0L4gKi8KdXBkYXRlKHdnYyhCb2F0LCBMLCBSKSwgQ2FyZ28sIHdnYyhOZXdCb2F0LCBOZXdMLCBOZXdSKSkgOi0KICAgIHVwZGF0ZV9ib2F0KEJvYXQsIE5ld0JvYXQpLAogICAgdXBkYXRlX2JhbmtzKENhcmdvLCBCb2F0LCBMLCBSLCBUZW1wTCwgVGVtcFIpLAogICAgc29ydChUZW1wTCwgTmV3TCksIAogICAgc29ydChUZW1wUiwgTmV3UikuCgoKLyog0JjQt9C80LXQvdC10L3QuNC1INC80LXRgdGC0L7QvdCw0YXQvtC20LTQtdC90LjRjyDQu9C+0LTQutC4ICovCnVwZGF0ZV9ib2F0KGxlZnQsIHJpZ2h0KS4KdXBkYXRlX2JvYXQocmlnaHQsIGxlZnQpLgoKCi8qINCS0YvQsdC+0YAg0LPRgNGD0LfQsCDQtNC70Y8g0L/QtdGA0LXQstC+0LfQutC4ICjQo9C20LUg0LjRgdC/0L7Qu9GM0LfRg9C10YLRgdGPINCy0YHRgtGA0L7QtdC90L3Ri9C5IG1lbWJlciwgc2VsZWN0INC90LUg0L3Rg9C20LXQvSkgKi8KLyog0J/QvtGA0Y/QtNC+0Log0YHQvtGA0YLQuNGA0L7QstC60LggKNC40YHQv9C+0LvRjNC30YPQtdC8INCy0YHRgtGA0L7QtdC90L3Ri9C5INC/0YDQtdC00LjQutCw0YIgQDwg0LTQu9GPINGB0YDQsNCy0L3QtdC90LjRjyDQsNGC0L7QvNC+0LIpICovCgoKLyog0JjQt9C80LXQvdC10L3QuNC1INGB0L7RgdGC0LDQstCwINC+0LHQuNGC0LDRgtC10LvQtdC5INCx0LXRgNC10LPQvtCyLiAqLwp1cGRhdGVfYmFua3Mobm9uZSwgXywgTCwgUiwgTCwgUikuICAlINCR0LXQtyDQs9GA0YPQt9CwCnVwZGF0ZV9iYW5rcyhDYXJnbywgbGVmdCwgTCwgUiwgTmV3TCwgW0NhcmdvfFJdKSA6LQogICAgc2VsZWN0KENhcmdvLCBMLCBOZXdMKS4KCnVwZGF0ZV9iYW5rcyhDYXJnbywgcmlnaHQsIEwsIFIsIFtDYXJnb3xMXSwgTmV3UikgOi0KICAgIHNlbGVjdChDYXJnbywgUiwgTmV3UikuCgovKiDQlNC+0L/Rg9GB0YLQuNC80L7RgdGC0Ywg0YHQvtGB0YLQvtGP0L3QuNGPICovCmxlZ2FsKHdnYyhfLCBMLCBSKSkgOi0KICAgIHNhZmUoTCksCiAgICBzYWZlKFIpLgoKc2FmZShMaXN0KSA6LQogICAgbm90KChtZW1iZXIo0LLQvtC70LosIExpc3QpLCBtZW1iZXIo0LrQvtC30LAsIExpc3QpLCBub3QobWVtYmVyKGZhcm1lciwgTGlzdCkpKSksCiAgICBub3QoKG1lbWJlcijQutC+0LfQsCwgTGlzdCksIG1lbWJlcijQutCw0L/Rg9GB0YLQsCwgTGlzdCksIG5vdChtZW1iZXIoZmFybWVyLCBMaXN0KSkpKS4KCgovKiBzb2x2ZShTdGF0ZSwgUGF0aCkgLSDQndCw0LnRgtC4INC/0YPRgtGMINC+0YIg0L3QsNGH0LDQu9GM0L3QvtCz0L4g0YHQvtGB0YLQvtGP0L3QuNGPINC00L4g0LrQvtC90LXRh9C90L7Qs9C+ICovCnNvbHZlKFN0YXRlLCBbU3RhdGVdKSA6LQogICAgZmluYWxfc3RhdGUoU3RhdGUpLgoKc29sdmUoU3RhdGUsIFtTdGF0ZSB8IFJlc3RQYXRoXSkgOi0KICAgIG1vdmUoU3RhdGUsIENhcmdvKSwgICAgICAgICAgLyog0J3QsNC50YLQuCDQtNC+0L/Rg9GB0YLQuNC80YvQuSDRhdC+0LQgKi8KICAgIHVwZGF0ZShTdGF0ZSwgQ2FyZ28sIE5leHRTdGF0ZSksIC8qINCf0L7Qu9GD0YfQuNGC0Ywg0YHQu9C10LTRg9GO0YnQtdC1INGB0L7RgdGC0L7Rj9C90LjQtSAqLwogICAgbGVnYWwoTmV4dFN0YXRlKSwgICAgICAgICAgICAgLyog0KPQsdC10LTQuNGC0YzRgdGPINGH0YLQviDRgdC+0YHRgtC+0Y/QvdC40LUg0LTQvtC/0YPRgdGC0LjQvNC+ICovCiAgICBub3QobWVtYmVyKE5leHRTdGF0ZSwgW1N0YXRlIHwgUmVzdFBhdGhdKSksICAvKiDQn9GA0L7QstC10YDQutCwINC90LAg0LfQsNGG0LjQutC70LjQstCw0L3QuNC1ICovCiAgICBzb2x2ZShOZXh0U3RhdGUsIFJlc3RQYXRoKS4KCi8qINCU0L7QsdCw0LLQuNC8INC/0YDQtdC00LjQutCw0YIg0LTQu9GPINC30LDQv9GD0YHQutCwINC/0L7QuNGB0LrQsCDRgNC10YjQtdC90LjRjyAqLwpzb2x2ZV9wcm9ibGVtKFBhdGgpIDotCiAgICBpbml0aWFsX3N0YXRlKF8sIEluaXRpYWxTdGF0ZSksCiAgICBhcHBlbmQoW0luaXRpYWxTdGF0ZV0sUGF0aDIsUGF0aCksCiAgICBzb2x2ZShJbml0aWFsU3RhdGUsIFBhdGgyKS4KCi8qINCU0L7QsdCw0LLQuNC8INC/0YDQsNCy0LjQu9C+LCDRh9GC0L7QsdGLINGE0LXRgNC80LXRgCDQstGB0LXQs9C00LAg0LHRi9C7INGBINC70L7QtNC60L7QuSAqLwptZW1iZXIoWCxbWHxfXSkuCm1lbWJlcihYLFtffFRdKSA6LQogICAgbWVtYmVyKFgsVCkuCgp1cGRhdGVfYmFua3Mobm9uZSxsZWZ0LEwsUixMMSxSMSkgOi0KICAgIHNlbGVjdChmYXJtZXIsTCxMMiksCiAgICBMMSA9IEwyLAogICAgUjEgPSBSLgp1cGRhdGVfYmFua3Mobm9uZSxyaWdodCxMLFIsTDEsUjEpIDotCiAgICBzZWxlY3QoZmFybWVyLFIsUjIpLAogICAgUjEgPSBSMiwKICAgIEwxID0gTC4KCm1vdmUod2djKGxlZnQsIEwsIF8pLCBDYXJnbykgOi0KICAgIG1lbWJlcihDYXJnbywgTCksCiAgICBtZW1iZXIoZmFybWVyLEwpLgoKbW92ZSh3Z2MocmlnaHQsIF8sIFIpLCBDYXJnbykgOi0KICAgIG1lbWJlcihDYXJnbywgUiksCiAgICBtZW1iZXIoZmFybWVyLFIpLgoKaW5pdGlhbF9zdGF0ZSgn0JjRgdGF0L7QtNC90L7QtSDRgdC+0YHRgtC+0Y/QvdC40LU6INCy0YHQtSDQvdCw0YXQvtC00Y/RgtGB0Y8g0L3QsCDQu9C10LLQvtC8INCx0LXRgNC10LPRgycsCiAgICAgICAgICAgICAgd2djKGxlZnQsIFtmYXJtZXIsICfQstC+0LvQuicsICfQutC+0LfQsCcsICfQutCw0L/Rg9GB0YLQsCddLCBbXSkpLgoKLyog0J/RgNC40LzQtdGA0Ysg0LLRi9C30L7QstC+0LI6ICovCi8qID8tIHNvbHZlX3Byb2JsZW0oUGF0aCkuICovCi8qID8tIHByaW50KFBhdGgpLiAgICAgICAqLw==