0
votes

Hello guys I'm still newbie, I still don't know how to solve this puzzle with Prolog, I did some try and seems wrong and incomplete and this is the question:

At a musical recital five students (John, Kate, Larry, Mary and Nick) performed five musical pieces. Two by Bach, two by Mozart and one by Vivaldi. There were three violinists and two pianists. Each student performed only one piece, and played only one instrument. Find the order of the students, their respective instruments and the composer, with the following conditions:

  1. The composers were not played consecutively. Vivaldi was played last and Mozart was played first.

  2. There was one piano piece that was played between two violin pieces, and two violin pieces between the first and last piano piece.

  3. There were no piano pieces by Mozart.

  4. Kate played third.

  5. John played a piece by Mozart, and was immediately followed by Nick, who played the piano.

  6. Mary did not play a piece by Vivaldi.

and here my half-code :

List=[
  musicians(_,_,_,_),
  musicians(_,_,_,_),
  musicians(_,_,_,_),
  musicians(_,_,_,_),
  musicians(_,_,_,_)],
member(musicians(1,_,_,mozart),List) ,
member(musicians(5,_,_,vivaldi),List) ,
member(musicians(_,_,P1,mozart),List) ,P1\==piano,
member(musicians(3,kate,_,_),List) ,
member(musicians(_,john,_,mozart),List) ,
member(musicians(N1,nick,piano,_),List) ,N1==john_num+1,
member(musicians(_,mary,_,C1),List) ,C1\==vivaldi,
  1. I don't know how to write the #2 statement about piano and violin.
  2. I don't know how to write nick statement after John N1==john_num+1,
  3. nah I'm just stuck to solve this problem using Prolog, even tho I already know the answer but totally new in prolog and still confused after read the tutorial.
1

1 Answers

0
votes

I've done this sort of thing many times. First, you need a function to do the solving:

 solve(List) :- % and now you can go on to define List, etc.

Here's how I do it: the generate and test method.

solve(List) :-
   generate(List),
   verify(List).

generate(List) would generate all possible solutions and verify would only allow the ones that match the constraints. That's the basic method. I usually interleave verifying into generating the parts, to throw out bad solutions as soon as I can.

Your solution using member is interesting, and might work, but you'll still need to generate a thing before you can test it. For example, this won't work:

member(musicians(_,mary,_,C1),List) ,C1\==vivaldi

because at the end of member C1 isn't bound, so C1\=vivaldi will necessarily fail. But this would work:

member(C1,[bach, mozart]), member(musicians(_,mary,_,C1),List)

The #2a problem also yields to this:

member(ViolinNumber1,[1,2,3,4,5]), member(ViolinNumber2,[1,2,3,4,5]),
member(PianoNumber,[1,2,3,4,5]),
ViolinNumber1 < PianoNumber, PianoNumber < ViolinNumber2, 
member(musicians(ViolinNumber1,_,violin,_),List),
member(musicians(ViolinNumber2,_,violin,_),List),
member(musicians(PianoNumber,_,  piano ,_),List)

You get through that, you know you've got a piano piece between two violin pieces.

It might be a good idea to require that the order be unique from the beginning, that is, that there aren't two pieces in the #2 slot (say):

List=[
    musicians(1,_,_,_), % and so on