Ответ 1
Для проектирования чистых интерфейсов в Prolog я рекомендую прочитать стандарт Prolog, см. iso-prolog.
В частности, конкретный формат кодирования встроенных предикатов, который включает определенный стиль документации, а также способ передачи ошибок. См. 8.1. Формат встроенных определений предикатов ISO/IEC 13211-1:1995. Вы найдете определения в этом стиле в Интернете Cor.2 и Пролог пролога.
Хорошим примером библиотеки, которая следует за соглашениями об ошибках ISO, вплоть до буквы (и пока не стандартизирована), является реализация library(clpfd)
в SICStus и SWI. Хотя обе реализации принципиально отличаются в своем подходе, они используют соглашения об ошибках в своих лучших интересах.
Назад к ISO. Это формат ISO для встроенных предикатов:
x.y.z Название /Arity
В начале может быть короткое необязательное неофициальное замечание.
x.y.z.1 Описание
Дается декларативное описание, которое начинается очень часто с самой общей цели с использованием описательных имен переменных, чтобы они могли быть упомянуты позже. Если значение предиката вообще не декларативно, оно либо указано "истинно", либо какое-то другое ненужное вводящее в действие слово "унифицирует", "собирает". Позвольте мне привести пример:
8.5.4 copy_term/2
8.5.4.1 Описание
copy_term(Term_1, Term_2)
истинно, если ifTerm_2
объединяется с терминомT
, который является переименованной копией (7.1.6.2) вTerm_1
.
Таким образом, это унифицирует большой красный предупреждающий знак: никогда не думайте, что этот предикат является отношением, его можно понять только процедурно. И тем более он (неявно) утверждает, что определение во втором аргументе устойчиво.
Другой пример: sort/2
. Это теперь отношение или нет?
8.4.3 sort/2
8.4.3.1 Описание
sort(List, Sorted)
истинно, если ifSorted
объединяется с отсортированным спискомList
(7.1.6.5).
Так, опять же, никакого отношения. Удивлены? Посмотрите 8.4.3.4 Примеры:
8.4.3.4 Примеры
...
sort([X, 1], [1, 1]). Succeeds, unifying X with 1. sort([1, 1], [1, 1]). Fails.
При необходимости добавляется отдельное процедурное описание, начиная с "Процедурно". Он снова не покрывает никаких ошибок. Это одно из больших преимуществ стандартных описаний: все ошибки отделяются от "делать", что помогает системным ошибкам программиста (= пользователя встроенных). Справедливости ради следует отметить, что это немного увеличивает бремя разработчика, который хочет оптимизировать вручную и на индивидуальной основе. Такой оптимизированный код часто подвержен тонким ошибкам.
x.y.z.2 Шаблон и режимы
Здесь дается исчерпывающая, одна или две строковые спецификации режимов и типов аргументов. Обозначения очень похожи на другие обозначения, которые нашли свое начало в объявлениях режима DECsystem-10.
8.5.2.2 Шаблон и режимы
arg(+integer, +compound_term, ?term)
Существует, однако, большая разница между подходом ISO и Covington et al. который носит неформальный характер и указывает, как программист должен использовать предикат. Подход ISO описывает, как будет себя вести встроенный - в частности, какие ошибки следует ожидать. (Из вышеприведенных ошибок 4 ошибки плюс одна дополнительная ошибка, которая не может быть видна из вышеприведенной спецификации, см. Ниже).
x.y.z.3 Ошибки
Даны все условия ошибки, каждый в своем собственном подпункте, пронумерованном в алфавитном порядке. Кодекс в 7.12 Ошибки:
Когда выполняется более одного условия ошибки, ошибка, сообщаемая процессором Prolog, зависит от реализации.
Это означает, что каждое условие ошибки должно содержать все предварительные условия, в которых оно применяется. Все они. Условия ошибки не читаются, как if-then-elsif-then...
Это также означает, что кодировщик должен приложить дополнительные усилия для поиска хороших условий ошибки. Это все в пользу фактического пользователя-программиста, но, конечно, немного боль для кодификатора и разработчика.
Многие условия ошибки непосредственно следуют из спецификации, указанной в xyz2 в соответствии с ПРИМЕЧАНИЯми в 8.1.3 Ошибки и в соответствии с 7.12.2. Классификация ошибок (summary). Для встроенного предиката arg/3
ошибки a, b, c, d следуют из спецификации. Только ошибка e не выполняется.
8.5.2.3 Ошибки
a)
N
- переменная —instantiation_error
.b)
Term
- переменная —instantiation_error
.c)
N
не является ни переменной, ни целым числом —type_error(integer, N)
.d)
Term
не является ни переменной, ни составным термином
—type_error(compound, Term)
.e)
N
- целое число меньше нуля
—domain_error(not_less_than_zero, N)
.
x.y.z.4 Примеры
(необязательно).
x.y.z.5 Загруженные встроенные предикаты
(необязательно). Определяет другие предикаты, которые настолько похожи, они могут быть "загружены".