Как определить (и назвать) соответствующие предикаты сравнения безопасных терминов в ISO Prolog?

Стандартный порядок терминов (ISO / IEC 13211-1 7.2 Порядок терминов) определяется для всех терминов, включая переменные. Хотя для этого есть хорошее применение - подумайте о реализацииsetof/3, это делает многие иначе понятные и логичные использования встроенных в 8.4 Term сравнений декларативным кошмаром со всеми бесами (краткой формой для императивных конструкций). 8.4 Срок сравнения функций:

8.4 Срок сравнения

8.4.1 (@ = <) / 2, (==) / 2, (\ ==) / 2, (@ <) / 2, (@>) / 2, (@> =) / 2.
8.4.2 сравнить / 3.
8.4.3 сортировать / 2.
8.4.4 keysort / 2.

Чтобы привести пример, рассмотрим:

?- X @< a.
true.

Это удается, потому что

7.2 Срок заказа

Заказterm_precedes (3.181) определяет, является ли или
не терминX термин предшествует терминуY.

ЕслиX а такжеY одинаковые термины тогдаX term_precedes Y
а такжеY term_precedes X оба ложные.

ЕслиX а такжеY имеют разные типы:X term_precedesY если
типX предшествует типуY в следующем порядке:
variable предшествуетfloating point предшествуетinteger
предшествуетatom предшествуетcompound.

ПРИМЕЧАНИЕ. - Встроенные предикаты, которые проверяют порядок терминов
определены в 8.4.
...

И, таким образом, все переменные меньше, чемa, Но однаждыX создается экземпляр:

?- X @< a, X = a.
X = a.

результат становится недействительным.

Так что это проблема. Чтобы преодолеть это, можно либо использовать ограничения, либо придерживаться только основного поведения и, следовательно, произвестиinstantiation_error.

7.12.2 Классификация ошибок

Ошибки классифицируются по формеError_term:

а) Должна быть ошибка установления, когда
аргумент или один из его компонентов является переменной, и
требуется конкретный аргумент или компонент. Она имеет
формаinstantiation_error.

Таким образом, мы точно знаем, что результат хорошо определен, пока не возникает ошибка создания экземпляра.

За(\==)/2уже естьdif/2 который использует ограничения илиiso_dif/2 который производит чистую ошибку экземпляра.

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.

Ответы на вопрос(8)

Ваш ответ на вопрос