% register unique attribute names from rules
attrs
( H
, [ N
- V
| R
] ) :- memberchk
( N
- X
, H
) , X
= V
, ( R
= [ ] - > true ; attrs
( H
, R
) ) .
in( HS, Attrs) :- member( H, HS) , attrs( H, Attrs) .
in
( HS
, G
, AttrsL
) :- call ( G
, Args
, HS
) , maplist
( attrs
, Args
, AttrsL
) .
left_of( [ A, B] , HS) :- append( _, [ A, B| _] , HS) .
next_to( [ A, B] , HS) :- left_of( [ A, B] , HS) ; left_of( [ B, A] , HS) .
zebra( Owner, Houses) :-
Houses = [ A, _, C, _, _] , % 1
maplist( in( Houses) , [ [ nation- englishman, color- red ] % 2
, [ nation- swede, owns - dog ] % 3
, [ nation- dane, drink- tea ] % 4
, [ drink - coffee, color- green ] % 6
, [ smoke - 'Pall Mall' , owns - birds ] % 7
, [ color - yellow, smoke- 'Dunhill' ] % 8
, [ drink - beer, smoke- 'Blue Master' ] % 13
, [ nation- german, smoke- 'Prince' ] % 14
] ) ,
in( Houses, left_of, [ [ color - green ] , [ color - white ] ] ) , % 5
maplist( attrs, [ C, A] , [ [ drink - milk ] , % 9
[ nation- norwegian] ] ) , % 10
maplist( in( Houses, next_to) ,
[ [ [ smoke - 'Blend' ] , [ owns - cats ] ] % 11
, [ [ owns - horse ] , [ smoke- 'Dunhill' ] ] % 12
, [ [ nation- norwegian] , [ color- blue ] ] % 15
, [ [ drink - water ] , [ smoke- 'Blend' ] ] % 16
] ) ,
in( Houses, [ owns- zebra, nation- Owner] ) .
:- time( ( zebra( Z, HS) , ( maplist( length, HS, _) - > maplist( sort, HS, S) ,
maplist
( writeln
, S
) , nl , writeln
( Z
) ) , false
; writeln( 'No More Solutions' ) ) ) .
Oi0gc2V0X3Byb2xvZ19mbGFnKHZlcmJvc2Usbm9ybWFsKS4KCiUgcmVnaXN0ZXIgdW5pcXVlIGF0dHJpYnV0ZSBuYW1lcyBmcm9tIHJ1bGVzCmF0dHJzKEgsW04tVnxSXSk6LSBtZW1iZXJjaGsoIE4tWCwgSCksIFg9ViwgKFI9W10gLT4gdHJ1ZSA7IGF0dHJzKEgsUikpLgogICAgICAgICAgICAgICAgICAgCmluKEhTLEF0dHJzKSAgOi0gbWVtYmVyKEgsSFMpLCBhdHRycyhILEF0dHJzKS4KaW4oSFMsRyxBdHRyc0wpOi0gY2FsbChHLEFyZ3MsSFMpLCBtYXBsaXN0KGF0dHJzLEFyZ3MsQXR0cnNMKS4KCmxlZnRfb2YoW0EsQl0sSFMpOi0gYXBwZW5kKF8sW0EsQnxfXSxIUykuCm5leHRfdG8oW0EsQl0sSFMpOi0gbGVmdF9vZihbQSxCXSxIUykgOyBsZWZ0X29mKFtCLEFdLEhTKS4KIAp6ZWJyYShPd25lcixIb3VzZXMpOi0KICAgIEhvdXNlcyA9IFtBLF8sQyxfLF9dLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJSAxCiAgICBtYXBsaXN0KCBpbihIb3VzZXMpLCBbIFsgbmF0aW9uLWVuZ2xpc2htYW4sICAgY29sb3ItcmVkICAgICAgICAgIF0gICUgMgogICAgICAgICAgICAgICAgICAgICAgICAgLCBbIG5hdGlvbi1zd2VkZSwgICAgICAgIG93bnMgLWRvZyAgICAgICAgICBdICAlIDMKICAgICAgICAgICAgICAgICAgICAgICAgICwgWyBuYXRpb24tZGFuZSwgICAgICAgICBkcmluay10ZWEgICAgICAgICAgXSAgJSA0CiAgICAgICAgICAgICAgICAgICAgICAgICAsIFsgZHJpbmsgLWNvZmZlZSwgICAgICAgY29sb3ItZ3JlZW4gICAgICAgIF0gICUgNgogICAgICAgICAgICAgICAgICAgICAgICAgLCBbIHNtb2tlIC0nUGFsbCBNYWxsJywgIG93bnMgLWJpcmRzICAgICAgICBdICAlIDcKICAgICAgICAgICAgICAgICAgICAgICAgICwgWyBjb2xvciAteWVsbG93LCAgICAgICBzbW9rZS0nRHVuaGlsbCcgICAgXSAgJSA4CiAgICAgICAgICAgICAgICAgICAgICAgICAsIFsgZHJpbmsgLWJlZXIsICAgICAgICAgc21va2UtJ0JsdWUgTWFzdGVyJ10gICUgMTMKICAgICAgICAgICAgICAgICAgICAgICAgICwgWyBuYXRpb24tZ2VybWFuLCAgICAgICBzbW9rZS0nUHJpbmNlJyAgICAgXSAgJSAxNAogICAgICAgICAgICAgICAgICAgICAgICAgXSApLAogICAgaW4oSG91c2VzLCBsZWZ0X29mLCAgICBbW2NvbG9yIC1ncmVlbiAgICBdLCAgW2NvbG9yIC13aGl0ZSAgICBdXSksICAlIDUKICAgIG1hcGxpc3QoIGF0dHJzLCBbQyxBXSwgW1tkcmluayAtbWlsayAgICAgXSwgICAgICAgICAgICAgICAgICAgICAgICAgJSA5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmF0aW9uLW5vcndlZ2lhbl1dKSwgICAgICAgICAgICAgICAgICAgICAgICUgMTAKICAgIG1hcGxpc3QoIGluKEhvdXNlcywgbmV4dF90byksICAKICAgICAgICAgICAgICAgICAgICAgICAgIFsgW1tzbW9rZSAtJ0JsZW5kJyAgXSwgIFtvd25zIC1jYXRzICAgICAgXV0gICAgJSAxMQogICAgICAgICAgICAgICAgICAgICAgICAgLCBbW293bnMgIC1ob3JzZSAgICBdLCAgW3Ntb2tlLSdEdW5oaWxsJyBdXSAgICAlIDEyCiAgICAgICAgICAgICAgICAgICAgICAgICAsIFtbbmF0aW9uLW5vcndlZ2lhbl0sICBbY29sb3ItYmx1ZSAgICAgIF1dICAgICUgMTUKICAgICAgICAgICAgICAgICAgICAgICAgICwgW1tkcmluayAtd2F0ZXIgICAgXSwgIFtzbW9rZS0nQmxlbmQnICAgXV0gICAgJSAxNgogICAgICAgICAgICAgICAgICAgICAgICAgXSApLAogICAgaW4oSG91c2VzLCBbb3ducy16ZWJyYSwgbmF0aW9uLU93bmVyXSkuCiAgICAKOi0gdGltZSgoIHplYnJhKFosSFMpLCAobWFwbGlzdChsZW5ndGgsSFMsXykgLT4gbWFwbGlzdChzb3J0LEhTLFMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBsaXN0KHdyaXRlbG4sUyksbmwsd3JpdGVsbihaKSkKICAgICAgICAgICAgICAgICAgICAgLCBmYWxzZSAKICAgICAgICAgIDsgd3JpdGVsbignTm8gTW9yZSBTb2x1dGlvbnMnKSkpLg==