1

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.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
nofar mishraki
  • 526
  • 1
  • 4
  • 15
  • What is the query that you would like to execute? And are these (that you posted) all the facts and rules you have? If you try to draw a proof tree from your goal, the result comes tono – Dr. Debasish Jana Jul 27 '15 at 12:12
  • @DebasishJana I added the query I execute in the end of the question now,what I posted are all the facts and rules I have. I will try to draw a proof tree.. – nofar mishraki Jul 27 '15 at 12:22
  • 1
    (This has some resemblance with a [tag:zebra-puzzle] altough it is not exactly one) – false Jul 27 '15 at 12:33
  • @false I think it's very helpful :) Thank you. – nofar mishraki Jul 27 '15 at 12:37

2 Answers2

2

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).
false
  • 10,264
  • 13
  • 101
  • 209
nofar mishraki
  • 526
  • 1
  • 4
  • 15
  • 2
    What about rewriting your solution to use `library(clpfd)`? (Available in SICStus, SWI, YAP and many more) – false Jul 27 '15 at 14:05
  • @false Good idea.Thank you. – nofar mishraki Jul 27 '15 at 14:07
  • 2
    You can then state things like `F3 > F2` **before** `assign/3`! Thus avoiding much backtracking. – false Jul 27 '15 at 14:08
  • 2
    You can then also express an assignment with CLP(FD) constraints: `assignment(Ns, Vs) :- pairs_keys_values(Pairs, Ns, Os), maplist(=(1), Os), global_cardinality(Vs, Pairs).` This further helps to avoid backtracking. – mat Jul 27 '15 at 14:27
0
% 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.
*/
PC Luddite
  • 5,883
  • 6
  • 23
  • 39
  • 1
    Code-only answers are rarely good. You might want to move the comments and put them as paragraphs explaining the code. – PC Luddite Oct 02 '15 at 06:26