ISO-Prolog (ISO/IEC 13211-1:1995, включая Cor.1: 2007, Cor.2: 2012) предлагает следующее встроенные предикаты для тестирования типа термина:
8.3 Типовое тестирование
1 вар /1. 2 атом /1. 3 целое число /1. 4 поплавка /1. 5 атомных /1. 6 Соединение /1. 7 nonvar/1. 8 количество /1. 9 вызываемым /1. 10 земля /1. 11 acyclic_term/1.
Внутри этой группы есть те, чья цель состоит исключительно в том, чтобы протестировать для определенного экземпляра, то есть 8.3.1 var/1
, 8.3.7 nonvar/1
, 8.3.10 ground/1
, и те, которые предполагают, что член достаточно инстанцируется таким образом, что тест типа безопасен. К сожалению, они сочетаются с тестированием для конкретного экземпляра.
Рассмотрим цель integer(X)
, которая терпит неудачу, если X
- невариантный член, который не является целым числом и, когда X
является переменной. Это разрушает многие желательные декларативные свойства:
?- X = 1, integer(X).
true.
?- integer(X), X = 1.
false.
В идеале второй запрос будет либо успешным, используя какую-либо форму coroutining; или он выдаст ошибку создания 1 в соответствии с классификацией ошибок . В конце концов:
7.12.2 Классификация ошибок
Ошибки классифицируются в соответствии с формой Error_term:
a) При возникновении ошибки при создании аргумент или один из его компонентов - переменная, а также требуется экземпляр аргумента или компонента. Он имеет форма
instantiation_error
....
Обратите внимание, что эта неявная комбинация тестирования экземпляров и тестирования типов приводит к многочисленным ошибкам в программах Prolog, а также здесь на SO.
Быстрое исправление этой ситуации заключалось бы в том, чтобы добавить явный тест перед каждым встроенным тестом, либо дословно, как
( var(T) -> throw(error(instantiation_error,_)) ; true),
integer(T), ....
или более компактно, так как
functor(T, _,_),
integer(T), ....
он может быть даже
T =.. _,
integer(T), ...
Мой вопрос двоякий:
Как обеспечить эту функциональность на уровне пользователя?
и, чтобы сделать это также немного сложным:
Какова самая компактная реализация более безопасного
atomic/1
, записанного в ISO-Prolog?
1 Другими менее желательными параметрами могут быть петли или создать ошибку ресурса. Еще предпочтительнее неправильного результата.