select([A|As],S):- select(A,S,S1),select(As,S1).
select([],_). 
 
next_to(A,B,C):- left_of(A,B,C) ; left_of(B,A,C).
left_of(A,B,C):- append(_,[A,B|_],C).

puzzle(X, Houses) :- % color, territory, animal, drink, car
  Houses = [h(_, west, _, _, _), _, h(_, _, _, milk, _), _, _],
  select([h(red, tasmania, _, _, _),
          h(green, _, _, cocoa, _),
          h(yellow, _, _, _, ford)], Houses),
  select([h(_, queensland, wombat, _, _),
          h(_, nsw, _, eggnog, _),
          h(_, victoria, _, _, vw)], Houses),
  select([h(_, _, crocodile, _, oldsmobile),
          h(_, _, _, juice, mercedes)], Houses),
  left_of(h(ivory, _, _, _, _), h(green, _, _, _, _), Houses),
  next_to(h(_, _, _, _, chevrolet), h(_, _, devil, _, _), Houses),
  next_to(h(_, _, _, _, ford), h(_, _, platipus, _, _), Houses),
  next_to(h(_, west, _, _, _), h(blue, _, _, _, _), Houses),
  member(h(_, X, coala, _, _), Houses).
  
main :- puzzle(X, Houses), maplist(writeln, Houses), nl, nl, fail.
main :- write('No more solutions.').
