Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



Cheers! That's awesome. I'm going to set aside some time to learn more Prolog. :-)




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: