Основная проблема таких предикатов, как integer/1
, atom/1
и т. Д., Заключается в том, что они не монотонны .
Возьмем, к примеру, ?- integer(5).
, что успешно.Но более общая цель, ?- integer(X).
, терпит неудачу !
Для декларативной отладки и автоматически сгенерированных объяснений мы ожидаем, что, если цель успешна, каждое обобщение этогоцель не должна потерпеть неудачу.
"Надлежащим" (то есть, если вы хотите, чтобы хорошие монотонные предикаты имели декларативный смысл) было бы, чтобы integer/1
вызвал ошибку создания экземпляра назапросы типа ?- integer(X).
на том основании, что у него недостаточно информации, чтобы ответить на вопрос в данный момент.Вместо integer/1
вы должны использовать must_be/2
из library(error)
для получения этого поведения звука:
?- must_be(integer, X).
ERROR: Arguments are not sufficiently instantiated
must_be/2
ведет себя монотонно, что в целом является хорошим свойством.
Расширение только комментария: проблема в том, что (по крайней мере, если приведенные выше примеры верны), ваш предикат больше не является истинным отношением, потому что цели теперь не являются коммутативными: ?- X = 0, X = Y, addUnique([X,Y,3],3).
успешно, но простой обмен порядком целей не даеттот же результат, потому что ?- X = Y, addUnique([X,Y,3], 3), X = 0.
терпит неудачу.
Такие явления являются обычным следствием использования мета-логических предикатов.Декларативным решением таких проблем являются ограничения , см., Например, dif/2
.Они монотонны, коммутативны и, как правило, намного проще для понимания.