0
votes

I'm doing homework for Prolog, and I have to design a program that creates a grid of wizard hats of 4 different colours (blue, red, green, and yellow) where each hat has one of 4 different letters (w, x, y, and z). The hats have to be arranged in such a way that no row or column has two hats with the same colour or hats with the same letter in them.

I'm currently designing the method to ensure that rows don't have repeats. The method is called validRow(L), and it's method call must look like:

validRow([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y),(1, 4, blue, z)]).

However I'm confused regarding the structure of the method call. I understand lists and trees in Prolog but have never seen a list with elements in parenthesis inside it that aren't trees.

Here is my code thus far:

validRow(R):-
  colorCheckList(C),
  letterCheckList(L),
  colorCheckList(CCL),
  letterCheckList(LCL),
  checkRed(R,C,CCL),

colorList([blue, red, green, yellow]).
letterList([w, x, y, z]).
colorCheckList([]).
letterCheckList([]).

checkRed([H|T],ColorList,ColorCheckList):-
  H == 'red',
  not(member(H,ColorList)),
  append(H, ColorCheckList).

checkRed([H|T],ColorList,ColorCheckList):-
  ( integer(H) ->
    checkRed(T,ColorList, ColorCheckList)
  ; checkRed(H)
  ).

When I run the trace I see that the compiler suddenly fails when it attempts to enter the (...) element. I think this is because it's not a list with a Head and Tail.

Here is my trace:

[trace] 7 ?- validRow([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y),
(1, 4, blue, z)]).
   Call: (7) validRow([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)]) ? creep
   Call: (8) colorCheckList(_G7733) ? creep
   Exit: (8) colorCheckList([]) ? creep
   Call: (8) letterCheckList(_G7733) ? creep
   Exit: (8) letterCheckList([]) ? creep
   Call: (8) colorCheckList(_G7733) ? creep
   Exit: (8) colorCheckList([]) ? creep
   Call: (8) letterCheckList(_G7733) ? creep
   Exit: (8) letterCheckList([]) ? creep
   Call: (8) checkRed([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)], [], []) ? creep
   Call: (9) (1, 1, red, w)==red ? creep
   Fail: (9) (1, 1, red, w)==red ? creep
   Redo: (8) checkRed([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)], [], []) ? creep
   Call: (9) integer((1, 1, red, w)) ? creep
   Fail: (9) integer((1, 1, red, w)) ? creep
   Redo: (8) checkRed([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)], [], []) ? creep
^  Call: (9) not((1, 1, red, w)==[]) ? creep
^  Exit: (9) not(user: ((1, 1, red, w)==[])) ? creep
   Call: (9) checkRed((1, 1, red, w), [], []) ? creep
   Fail: (9) checkRed((1, 1, red, w), [], []) ? creep  ** Fails here **
   Fail: (8) checkRed([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)], [], []) ? creep
   Fail: (7) validRow([ (1, 1, red, w), (1, 2, green, x), (1, 3, yellow, y), (1, 4, blue, z)]) ? creep
false.

Is this a structure of a list that I'm not aware of, or is the method call structure incorrect?

1
I understand lists and trees in Prolog but have never seen a list with elements in parenthesis. Prolog is dynamically typed, so it can handle anything in a list. - Willem Van Onsem
@WillemVanOnsem Does that mean that the element in parenthesis is a single element, and I cannot traverse through it similarly to how I would traverse a list itself? i.e. separating the head and tail, or something similar? - gsamerica
indeed, it is one element (of the form (X,Y,Z,T)). So your list contains four elements. - Willem Van Onsem
Awesome, thanks for clearing that up. Is there anyway for me to traverse the elements so I can validate the atoms inside them? - gsamerica
Nevermind I found the answer in another thread: you can enter elements of the form (...) with syntax similar to that of traversing a list: (H,T). - gsamerica

1 Answers

0
votes

(1, 1, red, w) is a (compound) term. It is structurally equivalent to something like (foo(1), bar(1), colour(red), foo(w)). You cannot traverse it but you can pattern match it!

In general, you can have all kinds of fancy structures in prolog and work with them - try for example 1+foo(X*2) = Y + foo(Y*4*2)