:- module puzzle. :- interface. :- import_module io. :- pred main(io::di, io::uo) is det. :- implementation. :- import_module list, string, solutions. :- type races ---> english; japanese; spanish. :- type colors ---> red; blue; green. :- type pets ---> jaguar; snail; zebra. :- type house ---> house( race :: races, color :: colors, pet :: pets ). :- pred distinct(house::in, house::in) is semidet. distinct(house(R1, C1, P1), house(R2, C2, P2)) :- not (R1 = R2 ; C1 = C2 ; P1 = P2). :- pred row(list(house)::out) is nondet. row([A, B, C]) :- house(A), house(B), house(C), A^pet = snail <=> B^race = japanese, B^pet = snail <=> C^race = japanese, C^color = blue <=> B^pet = snail, B^color = blue <=> A^pet = snail, not A^race = japanese, not C^pet = snail, distinct(A, B), distinct(B, C), distinct(A, C). :- pred house(house::out) is nondet. house(house(R, H, P)) :- race(R), color(H), pet(P), R = english <=> H = red, R = spanish <=> P = jaguar, not (R = japanese, P = snail), not (P = snail, H = blue). main(!IO) :- solutions(row, Solutions), ( if Solutions = [] then io.write_string("Impossible puzzle.\n", !IO) else foldl((pred(L::in, !.IO::di, !:IO::uo) is det :- io.print(L, !IO), io.nl(!IO)), Solutions, !IO) ). :- pred race(races::out) is multi. race(english). race(japanese). race(spanish). :- pred color(colors). :- mode color(out) is multi. :- mode color(in) is det. color(red). color(blue). color(green). :- pred pet(pets::out) is multi. pet(jaguar). pet(snail). pet(zebra).