Предикат не работает

Я новичок в прологе, и я действительно не понимаю, как все работает на самом деле.

Предоставление следующей базы знаний, из упрощенной социальной сети:

% user(nickname,email,city,friends_list)
user(nick0,mail0,lisbon,[nick1,nick8]).
user(nick1,mail1,lisbon,[nick0,nick3, nick5, nick9]).
user(nick2,mail2,london,[nick5,nick7,nick8]).
user(nick3,mail3,madrid,[nick1,nick4]).
user(nick4,mail4,paris,[nick1, nick3, nick2, nick5, nick6]).
user(nick5,mail5,madrid,[nick1, nick4, nick2]).
user(nick6,mail6,lisbon,[nick3,nick2]).
user(nick7,mail7,berlin,[nick3, nick5]).
user(nick8,mail8,berlin,[nick3, nick5, nick7]).
user(nick9,mail9,london,[nick1, nick4]).

Мне нужен предикат places(NU,LC), который генерирует список городов (LC) с городами, в которых количество пользователей больше или равно (NU).

Пример:

места(0,ЛК).

LC = [(Лиссабон,3), (Лондон,2), (Мадрид,2), (Париж,1), (Берлин,2)]

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

places(NU,LC):-
findall(X,user(_,_,X,_),List),
findall(Z,(user(_,_,Z,_),member(Z,List), Z>=NU),LC).

Это может быть простая проблема, но я все еще изучаю пролог.


person SaintLike    schedule 03.09.2013    source источник


Ответы (1)


Конечно, ответ будет зависеть от того, какую систему Пролога вы используете, потому что могут быть доступны библиотеки, решающие запрос за один вызов. Чтобы придерживаться предикатов ISO (ну, кроме member/2):

places(NU, LC) :-
    setof(City, User^Mail^Friends^user(User,Mail,City,Friends), Cities),
    findall((City, Count),
        (member(City, Cities),
         findall(_, user(_,_,City,_), L),
         length(L, Count),
         Count >= NU), LC).
person CapelliC    schedule 03.09.2013
comment
Есть ли способ представить список без повторяющихся городов? как в моем примере выше? Я знаю, что замена setof на findall дает мне список как единственное решение, но города повторяются - person SaintLike; 03.09.2013