Значение индикаторов режима инстанцирования в аргументах предикатов Пролога

Глядя на документацию по Прологу, подписи предикатов иногда записываются следующим образом:

foo(:Bar, +Baz, -Qux, ?Mop)

Что :, +, - а также ? и как я могу их интерпретировать? Кроме того, это единственные, которые существуют или их больше?

2 ответа

Решение

Эти префиксные операторы в этом контексте представляют режимы создания экземпляров, то есть они сообщают вам, какие аргументы должны быть переменными или создаваться при вызове предиката. Они также сообщают вам, будет ли аргумент (возможно, далее) создан при вызове. Они также могут быть использованы, чтобы сказать вам, что аргумент будет каким-то образом интерпретироваться мета предикатом, который вы вызываете. Некоторые из этих режимов реализации являются стандартными, другие зависят от системы. Наиболее обычными являются:

- - аргумент должен быть несвязанным (вероятный выходной аргумент)

+ - аргумент должен быть связан (входной аргумент)

? - аргумент может быть связанным или не связанным

@ - аргумент больше не будет создаваться при вызове

: - аргумент будет каким-то образом интерпретирован мета (часто неоднозначно)

0 - аргумент будет интерпретирован как цель и назван так

N - где N - натуральное число; аргумент будет интерпретироваться как замыкание, которое будет состоять из N дополнительные аргументы для построения цели, которая будет называться

Различные системы предоставляют другие или разные режимы реализации. Например, для указания того, что аргумент должен быть заземлен при вызове предиката, или для указания, что аргумент должен быть индикатором предиката или что он будет интерпретироваться как тело правила грамматики. Вам нужно будет обратиться к документации системы Prolog, которую вы используете для деталей.

Объявления режимов впервые появились в компиляторе DECsystem-10 в конце 1970-х годов. Руководство пользователя DECsystem-10 1978-09 является одним из первых описаний. Мотивация дана 1982-11-10:

Такая информация позволяет компилятору генерировать более компактный код, лучше используя хранилище времени выполнения. В частности, экономия времени хранения может быть очень существенной. Объявления режима также помогают другим людям понять, как работает ваша программа.

DECsystem-10

+ - аргумент всегда будет НЕ переменным

- - аргумент всегда будет переменной

? - без ограничений

Обратите внимание, что эти декларации применяются к каждой цели. В частности, они относятся к рекурсивным целям. Таким образом, следующее объявление режима плюс его определение подразумевают, что второй аргумент не является частичным списком. Таким образом, цель member(A, [c|_]) не будет соответствовать. Таким образом, интерфейс и реализация являются несколько взаимозависимыми, что может привести к довольно сложным случаям, когда необходимо учитывать объединения, выполняемые самим предикатом.

:- mode member(?, +).
member(X, [X|_]). % member(X, [X,.._]) in DEC10
member(X, [_|L]) :-
   member(X, L).

В случае, если объявление режима нарушается конкретной целью, объявление либо игнорируется, либо выдает ошибку, которая в то время означала выписывание сообщения об ошибке и сбой. Интерпретатор DECsystem-10 всегда игнорировал объявления.

Таким образом, в глубине 1970-х годов руководство пользователя DEC 10 дало толкование двух объявлений режима: первое - предписывающее, которое выдает ошибки в случае, если вызывающий режим не соблюдает режимы. Второй - совершенно неформальный, игнорирующий объявления режима во время выполнения. Первый используется в стандарте Prolog, последний встречается в документации некоторых систем Prolog.

Пролог ISO/IEC: Шаблон и режимы подраздел

Стандарт Prolog (ISO/IEC 13211-1:1995, 2007, 2012) использует следующий формат для определения встроенных предикатов. Он начинается с подпункта.1 Описание, .2 Шаблон и режимы, .3 Ошибки и, необязательно, продолжается.4 Примеры,.5 Встроенные предикаты с начальной загрузкой.

8.1.2 Шаблон и режимы

Спецификация как для типа аргументов, так и для
из них должны быть созданы для встроенного предиката
быть довольным. Случаи образуют взаимоисключающий набор.

...

Конкретные режимы:

+ - аргумент должен быть создан.

@ - лайк + и аргумент должен оставаться неизменным.

- - аргумент должен быть переменной, которая будет создана, если цель достигнута.

? - нет требования к режиму, аргумент может быть переменной или экземпляром.

Если предикат был вызван с другим режимом, instantiation_error или же uninstantiation_error производится. Если тип не совпадает, type_error производится. Таким образом, программист может предвидеть множество ошибок, просто взглянув на подраздел "Шаблон" и "Режим", не читая подробные условия ошибок.

Другие системы

Системы, отличающиеся от ISO, также отличаются друг от друга точной интерпретацией режимов. Многие выполняют молчаливый сбой в случае, если ошибка типа будет уместна Они рассматривают объявления режима как средство для указания случаев, когда ожидается, что предикат будет работать с неопределенным значением в противном случае. Часто - интерпретируется примерно следующим образом. Так как нет фактической ссылки, которая определяет значение, это то, что я собрал неофициально:

- - аргумент является "выходным аргументом". Это означает, что он будет объединен с результирующим сроком после достижения цели. Таким образом, аргумент является стойким. Часто ошибка не связана с таким аргументом.

Более современный документ находится здесь: https://www.swi-prolog.org/pldoc/man?section=modes

Есть аналогичные аннотации для мета-предикатов, которые должны иметь meta_predicateдирективы, чтобы обеспечить правильное добавление модулей при вызове. https://www.swi-prolog.org/pldoc/doc_for?object=(meta_predicate)/1

Другие вопросы по тегам