Very, very nice formulation!
You can apply the same trick to the query, i.e., you only need to write down the whole list once, if you formulate the query for example like this:
?- Vs = [GreenHouse, RedHouse, IvoryHouse, YellowHouse, BlueHouse,
Englishman, Spaniard, Ukrainian, Norwegian, Japanese,
Dog, Snails, Fox, Horse, Zebra,
Coffee, Tea, Milk, OrangeJuice, Water,
OldGold, Kools, Chesterfields, LuckyStrike, Parliaments],
puzzle(Vs),
label(Vs).
In the above, I have introduced the logical variable Vs to refer to the same list in both goals.In the case of the Zebra puzzle, we only care about a few of these variables in particular, so we do not even introduce names for others. Instead, we can use anonymous variables, so that not even bindings are reported for those variables that do not matter in this case:
?- Vs = [_,_,_,_,_,
Englishman, Spaniard, Ukrainian, Norwegian, Japanese,
_,_,_,_,Zebra,
_,_,_,_,Water|_],
puzzle(Vs),
label(Vs).
This yields the following solution: Vs = [5, 3, 4, 1, 2, 3, 4, 2, 1|...],
Englishman = 3,
Spaniard = 4,
Ukrainian = 2,
Norwegian = Water, Water = 1,
Japanese = Zebra, Zebra = 5 .
By introducing additional variables like this, you can use maplist/2 to more compactly express the sequence of all_distinct/1 constraints.That's really a very nice way to formulate the puzzle in Prolog, and makes excellent use of features that are still quite recent innovations in Prolog implementations.
I came to Logic Programming via grokking mrocklin's port of Kanren to Python: https://github.com/logpy/logpy; and to solving logic puzzles via Laws of Form: http://www.markability.net/ (Last year the author of that site George Burnett-Stuart apparently cracked how to encode Predicate Calculus in the notation, which is an exciting development, IMHO!) So I'm not a complete novice. That said, at first I thought I should define relations like smokes and pet_of, but somehow between seeing the table on the Wikipedia entry for the Zebra Puzzle and the SEND MORE MONEY example (https://github.com/triska/clpfd/blob/master/sendmory.pl) it became obvious what to do. If you look at the SEND MORE MONEY solution you'll see the Zebra solution is laid out just like it. To me, it seems like the same sort of puzzle as Sudoku, but much simpler. It's unfortunate that the solution and the solving proper (querying for the result) obscure the art of the puzzle-maker, eh?
Thanks for the suggestion! I've incorporated it into the version in Github "gist": https://gist.github.com/calroc/603ed919bc814ccee10c1b3df6142... (I kept the more verbose query though, as I think the output is nicer. :-) YMMV)