Проблема с bagof / 3 в Прологе - PullRequest
2 голосов
/ 10 июня 2011

Насколько я понимаю, предикаты setof / 3 и bagof / 3 могут использоваться для генерации списка решений проблемы. (ссылка на руководство по gprolog) .

Как и ожидалось, решения для следующего запроса - это a, b и c.

?- nth(_, [a,b,c], X).                 
X = a ? ;
X = b ? ;
X = c ? ;
yes

А теперь я попробую это:

?- setof(X, nth(_, [a,b,c], X), ListOfSolutions).
ListOfSolutions = [a] ? ;
ListOfSolutions = [b] ? ;
ListOfSolutions = [c]
yes

По моему мнению, решение должно было быть [a, b, c]. Что я делаю не так?

Я использую gprolog 1.4.0 для Mac OS.


Редактировать: Решение

Что мне действительно нужно, так это оператор (^) / 2, но приведенный здесь ответ был полностью правильным, большое спасибо за помощь Если у кого-то есть подобная проблема, вот мой текущий код для выбора ячеек из трехмерной сетки.

% selectFLR(?Grid, ?ClassId, ?TDayIdD, ?HourId, -ListOfFLR)
% ---------------------------------------------------------
selectFLR(Grid, ClassId, DayId, HourId, ListOfFLR) :-
    bagof(FLR, ClassId^DayId^HourId^selectSingleFLR(Grid, ClassId, DayId, HourId, FLR), ListOfFLR).

selectSingleFLR(Grid, ClassId, DayId, HourId, FLR) :-
    nth(ClassId, Grid, Class),
    nth(DayId, Class, Day),
    nth(HourId, Day, FLR).

Ответы [ 2 ]

2 голосов
/ 10 июня 2011

Нет, не должно. nth (_, [a, b, c], X) дает 1 решение для X каждый раз. setof (и bagof) работают как:

setof(Things, GoalCondition, Bag)

Если вы зададите Things как X, а X из nth / 3 будет (как показано в примере выше) просто одной переменной каждый раз, setof просто создаст список этой единственной переменной. Будут возможны и другие возможные объединения, но он просто сделает Мешок из 1 предмета, который каждый раз находится в Вещи.

Формально: предикаты bagof и setof коллекций урожая для отдельных привязок свободных переменных в цели. setof возвращает отсортированную версию коллекции без дубликатов ... findall действует как bagof со всеми свободными переменными, автоматически определяемыми количественно. Кроме того, findall возвращает пустой список [], если цель не достигнута, а bagof завершается неудачей.

Короче говоря, используйте findall: P

1 голос
/ 22 апреля 2012

Попробуйте написать так:

findall((A,B,C,D,E), coursemeetings(A,B,C,D,E),L)
...