问题
I'm trying to solve a riddle in Prolog. the riddle is: There are two buildings, each one has tree apartments (apartment per floor): one apartment of 3 rooms,one of 4 rooms and one of 5 rooms.
Dana,Joni and Noah lives in building 1. Ron,Gale and Aron lives in building 2.
Joni apartment is higher then Dana and Noah. It means he lives on the third floor of building 1. Noah and Gale lives on the same floor (in different buildings). Ron has a one more room than Aron. Ron lives one floor above Gale. The highest apartment in building 2 is the 5 rooms apartment.
I need to find in which floor everyone lives.
I wrote this code:
solve([dana,building1,F1,R1],[noah,building1,F2,R2],[joni,building1,F3,R3],[gale,building2,F4,R4],[ron,building2,F5,R5],[aron,building2,F6,R6]
) :-
L =[[dana,building1,1,3],[dana,building1,1,4],[dana,building1,1,5],[dana,building1,2,3],[dana,building1,2,4],[dana,building1,2,5],[dana,building1,3,3],[dana,building1,3,4],[dana,building1,3,5]
,[noah,building1,1,3],[noah,building1,1,4],[noah,building1,1,5],[noah,building1,2,3],[noah,building1,2,4],[noah,building1,2,5],[noah,building1,3,3],[noah,building1,3,4],[noah,building1,3,5]
,[joni,building1,1,3],[joni,building1,1,4],[joni,building1,1,5],[joni,building1,2,3],[joni,building1,2,4],[joni,building1,2,5],[joni,building1,3,3],[joni,building1,3,4],[joni,building1,3,5]
,[gale,building1,1,3],[gale,building1,1,4],[gale,building1,1,5],[gale,building1,2,3],[gale,building1,2,4],[gale,building1,2,5],[gale,building1,3,3],[gale,building1,3,4],[gale,building1,3,5]
,[ron,building1,1,3],[ron,building1,1,4],[ron,building1,1,5],[ron,building1,2,3],[ron,building1,2,4],[ron,building1,2,5],[ron,building1,3,3],[ron,building1,3,4],[ron,building1,3,5]
,[aron,building1,1,3],[aron,building1,1,4],[aron,building1,1,5],[aron,building1,2,3],[aron,building1,2,4],[aron,building1,2,5],[aron,building1,3,3],[aron,building1,3,4],[aron,building1,3,5]],
F3 > F2,
F3>F1,
F2 == F4,
R5 == R6-1,
F5 == F4+1,
(F4 == 3, R4 == 5;F5 == 3, R5 == 5; F6 == 3, R6 == 5),
del([dana,building1,F1,R1],L,List1),
del([noah,building1,F2,R2],List1,List2),
del([joni,building1,F3,R3],List2,List3),
del([gale,building2,F4,R4],List3,List4),
del([ron,building2,F5,R5],List4,List5),
del([aron,building2,F6,R6],List5,_).
del(X,L,L1) :-
remove(X,L,L1).
But when I execute the query:
solve([dana,building1,F1,R1],[noah,building1,F2,R2],[joni,building1,F3,R3],[gale,building2,F4,R4],[ron,building2,F5,R5],[aron,building2,F6,R6]).
I get:
"Error 22 : Instantiation Error"
anyone? I don't understand what I do wrong.
回答1:
I finally did it. This is the answer:
solve([dana,building1,F1,R1],
[noah,building1,F2,R2],
[joni,building1,F3,R3],
[gale,building2,F4,R4],
[ron,building2,F5,R5],
[aron,building2,F6,R6]) :-
assign([1,2,3],[F1,F2,F3]),
assign([1,2,3],[F4,F5,F6]),
assign([3,4,5],[R1,R2,R3]),
assign([3,4,5],[R4,R5,R6]),
F3 > F2,
F3>F1,
F2 =:= F4,
R5 =:= R6-1,
F5 =:= F4+1,
( F4 =:= 3, R4 =:= 5
; F5 =:= 3, R5 =:= 5
; F6 =:= 3, R6 =:= 5
).
assign(_,[]).
assign(Digs,[D|Vars]):-
del(D,Digs,Digs1),
assign(Digs1,Vars).
del(X,L,L1):-
remove(X,L,L1).
回答2:
% all zebra-like problems solved in CLP or ASP very easy.
% ECLiPSe CLP
:-lib(ic).
ap(Apart1,Rooms1,Apart2,Rooms2) :-
Apart1 = [Dana,Joni,Noah], Rooms1 = [DanaRm,JoniRm,NoahRm],
Apart2 = [Ron,Gale,Aron], Rooms2 = [RonRm,GaleRm,AronRm],
Apart1 :: [1..3], Rooms1 :: [3..5],
Apart2 :: [1..3], Rooms2 :: [3..5],
alldifferent(Apart1), alldifferent(Rooms1),
alldifferent(Apart2), alldifferent(Rooms2),
Joni #= 3, % so Dana Noah = 1..2
Noah #= Gale,
RonRm #= AronRm + 1, % so RonRm = 4..5 and AronRm=3..4
Ron #= Gale + 1, % so Ron = 2..3 and Gale=1..2
% building2 3floor is 5room. Gale cant be 3. so Ron=3 or Aron=3.
% but AronRm cant be 5 so Aron cant be 3. So Ron is 3 and RonRm is 5.
% ...but in search of holy declarativity lets Prolog to figure that :-)
( Ron #= 3, RonRm #= 5
; Gale #= 3, GaleRm #=5
; Aron #= 3, AronRm #=5
),
labeling(Apart1),labeling(Rooms1),
labeling(Apart2),labeling(Rooms2).
solve:-
ap(A1,R1,A2,R2),
write(A1),write(R1),write(A2),write(R2),nl.
run :-
statistics(hr_time, Start),
(\+ (solve, false)),
statistics(hr_time, End), Time is End - Start,
write('All solutions found in '), write(Time), write(' seconds'), nl.
/* hardware: pentium4-1mb-3.0ggz at ddr1-333mhz
software: eclipse-6.2.24 on slackware-14.0
[eclipse 1]: [apart].
apart.pl compiled 4160 bytes in 0.18 seconds
[eclipse 2]: run.
[1, 3, 2][3, 4, 5][3, 2, 1][5, 3, 4]
[1, 3, 2][3, 5, 4][3, 2, 1][5, 3, 4]
[1, 3, 2][4, 3, 5][3, 2, 1][5, 3, 4]
[1, 3, 2][4, 5, 3][3, 2, 1][5, 3, 4]
[1, 3, 2][5, 3, 4][3, 2, 1][5, 3, 4]
[1, 3, 2][5, 4, 3][3, 2, 1][5, 3, 4]
All solutions found in 0.00655293464660645 seconds
more or less, we have only 1 solution. but we not have any info about
size of rooms in first building. and because of that we just get all 6
possibly combinations for it.
*/
来源:https://stackoverflow.com/questions/31652482/a-building-riddle-in-prolog