序言矩阵处理柱

prolog matrix treating column

我正在使用矩阵,其中每个子列表都是一行:

Matrix =[[-,-,-,-,a,-],
         [-,-,-,-,b,-],
         [-,-,-,-,a,-],
         [-,-,-,-,d,a],
         [-,-,-,-,a,a],
         [-,-,a,a,a,a],
         [-,-,-,-,d,a]].

我的目标是查找子列表中是否有四个连续的位置具有发送的相同字符。

veryRow(_,[]).
veryRow(X,[T|TS]) :- row(X,T), veryRow(X,TS).
row(X,[A,B,C,D|_]) :- A \= X; B \= X; C \= X; D \= X.
row(X,[_|Xs]):- row(X,Xs).

当子列表包含四个连续元素时必须 return 为真。

我的输入是:

veryRow(a,[[-,-,-,-,a,-],
         [-,-,-,-,b,-],
         [-,-,-,-,a,-],
         [-,-,-,-,d,a],
         [-,-,-,-,a,a],
         [-,-,a,a,a,a],
         [-,-,-,-,d,a]]).

因为没找到?

谢谢

从头开始,我认为veryRow需要重新考虑。这个名字并不令人满意,因为它没有很好地描述规则的作用。但我会保留原样,让您选择一个更合适的名称(也许 four_in_a_row 或类似的名称)。

基本情况 veryRow(_, []). 是有问题的。它成功地将任何元素作为第一个参数,将空列表作为第二个参数,但这些参数在逻辑上不满足该规则应该决定的要求(第一个参数作为第二个中的元素连续出现 4 次)争论)。所以让我们抛开这个规则。

你的第二条规则也有问题:

veryRow(X,[T|TS]) :- row(X,T),!, veryRow(X,TS).

这条规则说 X[T|TS] 中是连续的 if X 在 [=21= 中是连续的] XTS中是连续的。这显然是不正确的,因为如果 X 中至少有一个 连续 [T|TS],而不是 all行。您插入的剪切不会改变此含义。

当然,作为一个简单的基本情况,以下内容是正确的,即元素连续出现在列表的头部:

veryRow(X, [T|_]) :- row(X, T).

请注意,这就是基本情况所需的全部内容。一旦 row(X, T) 成功,它就会成功,并且不应进行进一步的调用。但是如果它失败了怎么办(XT 中不是连续的)?然后你需要你的其他子句来处理列表的其余部分:

veryRow(X, [_|Ts]) :- veryRow(X, Ts).

这简单地说,如果XTs.[=37中连续,X[_|Ts]中连续=]

如果 Ts[],这最终会失败,这很好,因为它不是真的。

你应该摆脱你的削减,这条规则将适用于它找到四个连续元素的每种情况。如果有多个这样的情况,你会得到多个 successes/solutions。如果只希望成功一次,可以使用once/1:

onceVeryRow(X, L) :- once(veryRow(X, L)).


您对 row/2 的第一次实施在您更改它之前很好(并且删除了剪切):

row(X, [X, X, X, X|_]).
row(X, [_|T]) :-
    row(X, T).