Проверка всех фактов в прологе - PullRequest
0 голосов
/ 01 июня 2018

У меня есть ряд фактов, представляющих ячейку со строкой, столбцом и числом в этой определенной ячейке, и я хочу проверить эти факты так же, как и обычный массив.

Я попробовал эту функцию, но она не работает, я не думаю, что проверяю все свои факты.

allcolored(X,Y) :-
   cell(X,Y,_),
   X1 is X - 1,
   Y1 is Y - 1,
   allcolored(X1,Y1).

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Вместо проверки существования факта для каждой пары индексов в диапазоне, проверьте отсутствие несуществования факта для некоторой пары индексовв диапазоне:

allcolored(X,Y) :- 
    \+ (between(1,X,A), between(1,Y,B), \+ cell(A,B,_)).

это говорит: allcolored(X,Y) выполняется, если нет индексов A, B в допустимых диапазонах (1..X, 1..Y), для которых факт cell(A,B) не существует,

Другими словами, "в данной области нет пустых ячеек" - это то же самое, что и "все ячейки в данной области заполнены" .

0 голосов
/ 01 июня 2018

Если я вас правильно понимаю, вы хотите проверить, охватываются ли 1001 * фактами все позиции в сетке, охватываемой этими координатами, с учетом пары координат X / Y.В качестве аргумента давайте рассмотрим следующие факты:

cell(1,1,100).
cell(1,2,200).
cell(1,3,300).
cell(2,1,110).
cell(2,2,120).
cell(2,3,130).

Глядя на вашу попытку рекурсивного правила, вы пытаетесь проверить, скажем, для данной пары, скажем,2/2 есть факты cell/3 для пар 2/2 и 1/1.Но вы, вероятно, хотите проверить, покрыты ли следующие пары: 2/2, 1/2, 2/1 и 1/1.Как вы можете видеть в этой последовательности, координата X уменьшается до 1, затем координата Y уменьшается, а координата X начинается снова с 2.Так что вам нужно как-то сохранить первоначальное значение X.Это можно сделать с помощью вспомогательного предиката с дополнительным аргументом.Тогда ваш предикат allcolored/2 будет являться вызывающим предикатом для такого предиката, назовем его allcolored_/3:

allcolored(X,Y) :-
   allcolored_(X,Y,X).

Как уже указывал @lurker, в вашем предикате отсутствует базовый случай, где рекурсияможет остановитьсяОчевидным кандидатом для этого была бы пара 1/1:

allcolored_(1,1,_) :-
   cell(1,1,_).

Затем необходимо правило, чтобы описать, что все значения между X и 2 должны быть покрыты cell/3:

allcolored_(X,Y,Max) :-
   cell(X,Y,_),
   X > 1,
   Y >= 1,
   X0 is X-1,
   allcolored_(X0,Y,Max).

И дополнительное правило для описания изменения следующей более низкой Y-координаты, когда X достигло 1:

allcolored_(1,Y,Max) :-
   cell(1,Y,_),
   Y > 1,
   Y0 is Y-1,
   allcolored_(Max,Y0,Max).

Теперь вы можете проверить, является ли сетка, охватываемая указанными вами координатами,на основе фактов cell/3:

?- allcolored(2,2).
true ;
false.

?- allcolored(2,3).
true ;
false.

?- allcolored(3,3).
false.

Обратите внимание, что в приведенном выше коде предполагается, что наименьшая координата в сетке равна 1. Чтобы изменить ее, например, на 0, необходимо заменить 1 в целях X >1, Y >= 1 и Y > 1 на 0.Также обратите внимание, что из-за упорядочения целей (сначала cell/3 целей) вы также можете задавать вопросы типа Какие существуют сетки, которые охватываются фактами cell/3? :

?- allcolored(X,Y).
X = Y, Y = 1 ;
X = 2,
Y = 1 ;
X = Y, Y = 2 ;
X = 2,
Y = 3 ;
X = 1,
Y = 2 ;
X = 1,
Y = 3 ;
false.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...