Перевод Пролога может быть простым, правило за правилом, по-прежнему следуя парадигме создания экземпляра домена путем выбора из него . Здесь это область атрибутов дома; в связанном ответе атрибуты дома фиксируются программистом, а домен представляет собой фактические жилые дома, что позволяет очень сжатое кодирование.
Другими словами, разница заключается в нотации: сложная нотация уже уводит нас на полпути, но это был человек, который изобрел ее и последовал ей (как программист, имеющий записать norwegian
в первую спецификацию дома напрямую, в соответствующей позиции аргумента position) - не компьютер.
Здесь мы стараемся внести в код как можно меньше человеческих знаний, следуя ограничениям домашнего задания. (хотя, конечно, все можно спорить, и в конечном итоге в предотвращении вмешательства человека будет компьютерная программа, которая принимает английский текст в качестве входных данных ... что снова будет открыто для критики относительно того, насколько конкретно эта программа предназначена для поиска решения этой конкретной головоломки или типа головоломок и т. д. и т. д.)
Мы кодируем его в стиле сверху вниз. Видимо вопрос отсутствует. Это должно быть «кто пьет воду? Кому принадлежит зебра?»:
zebra( Z, W ,HS) :-
length( HS, 5), % nation? color? what's that? define it later...
member( H1, HS), nation( H1, eng ), color( H1, red ),
member( H2, HS), nation( H2, spa ), owns( H2, dog ),
member( H3, HS), drink( H3, coffee ), color( H3, green ),
member( H4, HS), nation( H4, ukr ), drink( H4, tea ),
right_of(B, A, HS), color( A , ivory ), color( B , green ),
member( H5, HS), smoke( H5, oldgold), owns( H5, snails ),
member( H6, HS), smoke( H6, kools ), color( H6, yellow ),
middle( C, HS), drink( C , milk ),
first( D, HS), nation( D , nor ),
next_to( E, F, HS), smoke( E , chester), owns( F , fox ),
next_to( G, H, HS), smoke( G , kools ), owns( H , horse ),
member( H7, HS), smoke( H7, lucky ), drink( H7, orange ),
member( H8, HS), nation( H8, jpn ), smoke( H8, parlamt),
next_to( I, J, HS), nation( I , nor ), color( J , blue ),
member( W, HS), drink( W , water ),
member( Z, HS), owns( Z , zebra ).
right_of( B, A, HS) :- append( _, [A, B | _], HS).
next_to( A, B, HS) :- right_of( B, A, HS) ; right_of( A, B, HS).
middle( A, [_,_,A,_,_]).
first( A, [A | _]).
nation(H, V) :- attr( H, nation-V).
owns( H, V) :- attr( H, owns-V). % select an attribute
smoke( H, V) :- attr( H, smoke-V). % from an extensible record H
color( H, V) :- attr( H, color-V). % of house attributes
drink( H, V) :- attr( H, drink-V). % which *is* a house
attr(House, Attr-Value) :-
memberchk( Attr-X, House), % unique attribute names
X = Value.
Тестирование, выполнение исчерпывающего поиска с отказоустойчивым циклом,
3 ?- time((zebra(Z,W,_), maplist(nation,[Z,W],R), writeln(R), false ; true)).
[jpn,nor]
% 180,974 inferences, 0.016 CPU in 0.020 seconds (78% CPU, 11600823 Lips)
true.
Вот как определяются дома:
5 ?- zebra(_, _, HS), maplist( writeln, HS),
false.
[smoke-kools, color-yellow, nation-nor, owns-fox, drink-water |_G859]
[nation-ukr, drink-tea, smoke-chester, owns-horse, color-blue |_G853]
[nation-eng, color-red, smoke-oldgold, owns-snails, drink-milk |_G775]
[nation-spa, owns-dog, color-ivory, smoke-lucky, drink-orange|_G826]
[drink-coffee, color-green, nation-jpn, smoke-parlamt, owns-zebra |_G865]
false.
или, если списки атрибутов "заморожены" путем фиксации их длины, а затем отсортированы,
7 ?- zebra( _, _, HS), maplist( length, HS, _), !, maplist( sort, HS, S),
maplist( writeln, S), false.
[color-yellow, drink-water, nation-nor, owns-fox, smoke-kools ]
[color-blue, drink-tea, nation-ukr, owns-horse, smoke-chester]
[color-red, drink-milk, nation-eng, owns-snails, smoke-oldgold]
[color-ivory, drink-orange, nation-spa, owns-dog, smoke-lucky ]
[color-green, drink-coffee, nation-jpn, owns-zebra, smoke-parlamt]
false.
Также легко сделать так, чтобы предикат attr/2
принимал списки Name-Value
пар, что позволяет более естественно плавный, высокоуровневый стиль кодирования с своего рода «расширяемыми записями» - можно даже сказать «объектами» - спецификациями, например
zebra( Z, W ,HS):-
length( HS, 5),
member( H1, HS), attr( H1, [nation-eng, color-red ] ),
member( H2, HS), attr( H2, [nation-spa, owns-dog ] ),
member( H3, HS), attr( H3, [drink-coffee, color-green] ),
......
и т. д..
person
Will Ness
schedule
20.11.2013
select
для одновременного взаимоисключающего выбора из домена, чтобы ограничениеdiff
удовлетворялось путем построения. - person Will Ness   schedule 18.11.2013owns/2
,smokes/2
иdrinks/2
, верно? Я не говорю, что у вас не может быть элегантного решения в прологе (наоборот, я раньше думал, что мое решение довольно элегантно, пока не увидел ваше (ссылка выше выглядит неработающей github.com/thanosqr/side_projects/blob/master/zebra_puzzle.pl)), просто домашнее задание ограничения затрудняют написание элегантного решения - person Thanos Tintinidis   schedule 19.11.20131+1 = 1+1
действительно. Хороший! - person Will Ness   schedule 19.11.2013owns/2
и тому подобное, и это тоже не слишком уродливо. :) Делает в 75 раз больше выводов, чем мой другой ответ, но все равно работает очень быстро. - person Will Ness   schedule 20.11.2013