Стандартный порядок терминов (ISO / IEC 13211-1 7.2 Порядок терминов) определяется для всех терминов, включая переменные. Хотя есть хорошие применения для этого представления о реализации setof/3
, это делает многие в остальном чистые и логичные использования встроенных в 8.4 Сравнение терминов декларативным кошмаром с бесами (краткая форма для императивных конструкций) повсюду. 8.4 Особенности сравнения терминов:
8.4 Сравнение сроков
8.4.1 (@ = ‹) / 2, (==) / 2, (\ ==) / 2, (@‹) / 2, (@ ›) / 2, (@› =) / 2.
8.4.2 сравнить / 3.
8.4.3 sort / 2.
8.4.4 keysort / 2.
В качестве примера рассмотрим:
?- X @< a.
true.
Это удается, потому что
7.2 Срок действия
Порядок term_precedes (3.181) определяет,
или нет терминX
term-предшествует терминуY
.Если
X
иY
являются идентичными терминами, то обаX
term_precedesY
иY
term_precedesX
являются ложными.Если
X
иY
имеют разные типы:X
термин_представляетY
, если типX
предшествует типуY
в следующем порядке:variable
предшествуетfloating point
предшествуетinteger
предшествуетatom
предшествуетcompound
.ПРИМЕЧАНИЕ. Встроенные предикаты, которые проверяют порядок терминов
, определены в 8.4.
...
Таким образом, все переменные меньше a
. Но как только создается экземпляр X
:
?- X @< a, X = a.
X = a.
результат становится недействительным.
Вот в чем проблема. Чтобы преодолеть это, можно либо использовать ограничения, либо придерживаться только основного поведения и, следовательно, создать _ 25_.
7.12.2 Классификация ошибок
Ошибки классифицируются по форме
Error_term
:a) Должна быть ошибка создания экземпляра, когда аргумент
или один из его компонентов является переменной, и требуется экземпляр аргумента или компонента
. Он имеет формуinstantiation_error
.
Таким образом мы точно знаем, что результат хорошо определен, пока не возникает ошибка создания экземпляра.
Для (\==)/2
уже существует dif/2
, использующий ограничения, или _ 30_, что приводит к чистой ошибке создания экземпляра.
iso_dif(X, Y) :-
X \== Y,
( X \= Y -> true
; throw(error(instantiation_error,iso_dif/2))
).
Итак, о чем мой вопрос: как определить (и назвать) соответствующие предикаты сравнения безопасных терминов в Пролог ISO? В идеале, без явного обхода терминов. Возможно, чтобы уточнить: выше iso_dif/2
не используется явный обход термина. И (\==)/2
, и (\=)/2
просматривают термин внутри, но накладные расходы для этого чрезвычайно низкие по сравнению с явным обходом с (=..)/2
или functor/3, arg/3
.
freeze/2
? - person   schedule 06.05.2015freeze/2
сам по себе не будет работать должным образом, вам скорее понадобитсяwhen/2
с?=
. Пример:lt(X+2,Y+1), X = Y
уже должен выйти из строя. - person false   schedule 06.05.2015