Думайте о (\ +) / 1 не как логическое отрицание, а как "не доказуемое".\+ na(a, What)
успешен тогда и только тогда, когда na(a, What)
не доказуемо.Поскольку na(a, What)
дает по крайней мере одно решение и, следовательно, доказуемо, его отрицание (в этом смысле) не удается .(\ +) / 1, таким образом, является логически неполным: в этом случае он терпит неудачу, хотя, как вы заметили, существуют базовые значения, которые могли бы сделать его успешным.Однако (\ + / 1) работает так, как вы ожидаете от логического отрицания, если его аргумент является обоснованным.Поэтому вы можете решить ее, например, с помощью
na(X, Y) :- country(X), country(Y), \+ adj(X, Y).
, где страна / 1 дает наземные экземпляры стран.Другой способ решить это - явно перечислить страны, которые не являются смежными, что возможно, поскольку домен конечен.Преимущество этого подхода в том, что ваши запросы монотонны: добавление новых фактов никогда не приведет к сбою запроса, который ранее был успешно выполнен (это не выполняется при использовании (\ +) / 1, как указано выше).Это хорошее свойство для декларативной отладки.