2016-05-19 2 views
0

Я работаю с матрицей, где каждый подсписком является строкой:пролог матрицы обработки столбца

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

Должен возвращать true, когда подсписку четыре последовательных элемента.

моего imputs является:

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

Потому что не нашли?

Благодаря

+0

'veryRow 'будет терпеть неудачу, как только найдет строку, которая не удастся для' row'. – lurker

+0

но с разрезом «!». Не прекращает выполнение, если строка верна? – Merche

+0

Это никогда не заходит так далеко. Разрезание предотвращает откат только для большего количества растворенных веществ * если * вызов 'row' преуспевает. Для первой строки во втором аргументе 'veryRow (X, [T | TS])' терпит неудачу, потому что 'T' не имеет 4 последовательных' X '. И 'veryRow (_, [])' fail, потому что второй аргумент не пустой список. Таким образом, предикат полностью терпит неудачу. Ваша логика для 'veryRow' требует, чтобы' row' был успешным. – lurker

ответ

1

Начиная с верхней части, я думаю, что veryRow потребности быть переосмыслена. Имя не является удовлетворительным, потому что оно не описывает, что правило делает очень хорошо. Но я оставлю это как есть и оставлю его вам, чтобы выбрать более подходящее имя (возможно, four_in_a_row или что-то в этом роде).

Базовый корпус, veryRow(_, []). проблемный. Он преуспевает для любого элемента в качестве первого аргумента и пустого списка как второго, но эти аргументы логически не соответствуют требованию, согласно которому это правило должно принимать решение (первый аргумент выполняется 4 раза подряд в качестве элемента во втором аргумент). Итак, давайте бросим это правило.

Вашего второе правило также проблематично:

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

Это правило говорит, что X последователен в [T|TS]еслиX последователен в TиX последователен в TS. Это явно неверно, так как вы хотите, чтобы он преуспел, если X последователен в как минимум один строк в [T|TS], а не все строки. Врез, который вы вставили, не меняет этого значения.

Конечно следующее было бы верно в качестве простого базового варианта, который является элементом происходит последовательно в голове списка:

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

отметить, что это все, что нужно для базового случая. Он успешно завершается, как только row(X, T) преуспевает, и дальнейшие вызовы не должны выполняться. Но что, если он не сработает (X не последователен в T)? Тогда вам нужен другой пункт для обработки остальной части списка:

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

Это просто говорит о том, X последователен в [_|Ts] если X последователен в Ts.

Это, в конечном счете, не удастся, если Ts - [], что прекрасно, поскольку это неправда.

Вы должны избавиться от своих разрезов, и это правило будет работать и преуспеть для каждого случая, когда он найдет четыре последовательных элемента. Если таких случаев много, вы получите многократные успехи/решения. Если вы только хотите, чтобы добиться успеха один раз, вы можете использовать once/1:

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


Ваше первое внедрение row/2 было хорошо, прежде чем вы изменили его (и с разрезом удалены):

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

большое спасибо !! действительно. Он работает правильно и, самое главное, понимает. спасибо – Merche

 Смежные вопросы

  • Нет связанных вопросов^_^