理解形式的Prolog列表结构:[(...),(...),...]

时间:2017-02-26 00:00:36

标签: prolog

我正在为Prolog做作业,我必须设计一个程序,创建一个4种不同颜色(蓝色,红色,绿色和黄色)的巫师帽网格,每个帽子有4个不同的字母之一(w) ,x,y和z)。帽子必须以这样的方式排列,即没有任何行或列有两个颜色相同的帽子或帽子中有相同字母的帽子。

我目前正在设计方法以确保行没有重复。该方法称为validRow(L),它的方法调用必须如下:

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

但是我对方法调用的结构感到困惑。我理解Prolog中的列表和树,但是从来没有看到一个列表,其中的括号内的元素不是树。

到目前为止,这是我的代码:

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)
  ).

当我运行跟踪时,我看到编译器在尝试输入(...)元素时突然失败。我想这是因为它不是一个有头和尾的列表。

这是我的追踪:

[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.

这是我不知道的列表结构,还是方法调用结构不正确?

1 个答案:

答案 0 :(得分:0)

(1, 1, red, w)是一个(复合)术语。它在结构上等同于(foo(1), bar(1), colour(red), foo(w))之类的东西。你不能遍历它,但你可以模式匹配它!

一般来说,你可以在prolog中使用各种奇特的结构并与之合作 - 例如1+foo(X*2) = Y + foo(Y*4*2)