Согласно строке комментария к исходному сообщению, вы определили популярность как «человека, которого кто-то знает». Так как - в вашей базе знаний - все кем-то известны, все популярны.
Предполагая, что «популярный человек - это тот, кого все знают, но популярный человек знает только других популярных людей»; если мы хотим знать, популярен ли X:
- Нам нужно либо подсчитать всех людей, которые знают X, а затем сравнить это с количеством людей;
- Или нам нужно убедиться, что никогда не бывает так, чтобы кто-то не знал X.
Я сосредоточусь на втором способе сделать это, используя forall. Найдите время и проведите несколько тестов самостоятельно, чтобы понять, как это работает. Вот пример того, что вы можете сделать:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
).
Если вы запустите это, вы получите Алису и Питера в качестве ответов.
Но если мы включим другое условие:
popular(X): - person(X),
forall(
( person(Y),
X \= Y
),
knows(Y,X)
),
forall(
knows(X,Z),
popular(Z)
).
В последней строке говорится, что X должен знать исключительно популярных людей... и теперь, если вы запустите это, вы, скорее всего, получите "выход из локального стека" - это бездонное рекурсивное определение сильный>.
Вам всегда нужно проверить, популярен ли кто-то, чтобы узнать, популярен ли кто-то, чтобы узнать, популярен ли кто-то... Попробуйте подумать о проблеме и о том, почему это так. Есть ли способ проверить, популярен ли кто-то, без необходимости проверять, популярен ли кто-то еще? Что, если кто-то «знает» себя? Что, если два человека знают друг друга? Это может потребовать немного более сложного подхода к решению.
Кстати, обратите внимание, что ваше определение человека возвращает несколько людей — каждый является человеком для каждого человека, которого они знают. Помимо того, что каждая проверка занимает намного больше времени (поскольку нужно проверить больше «людей»), это может быть проблемой, если вы решите использовать первый подход (подсчет).
Разве не имеет смысла явно определить, кто такие люди, а затем определить «знание» как отношения между людьми?
person('Alice').
person('Bob').
knows('Alice','Bob').
person
vmg
schedule
12.11.2014
person
какX
— это человек, еслиX
знает кого-то (не имеет значения, кого). And you've defined
popular`, поскольку ``X` популярен, еслиX
— это человек (они кого-то знают), и если кто-то знаетX
я>. Поскольку каждый в вашей базе данных кого-то знает, и каждый в вашей базе данных кого-то знает, то по вашему определению все популярны. - person lurker   schedule 11.11.2014popular
. Если он дает вам неверный ответ (то есть, все люди), это означает, что ваше определениеpopular
неверно. Подумайте, что значит бытьpopular
логическим (попытайтесь выразить это на нормальном языке), а затем выразите это на Прологе. - person lurker   schedule 11.11.2014