Различия во встроенных предикатах
Компиляция
В Прологе-10 предусмотрена возможность выборочной компиляции некоторых из ваших утверждений, что позволяет значительно увеличить эффективность программ по времени выполнения и занимаемой памяти. Для этого имеется встроенный предикат, который действует подобно предикату consult, с той лишь разницей, что утверждения из файла не интерпретируются, а компилируются. Эффективность выполнения откомпилированных утверждений может быть увеличена за счет использования так называемых описаний режима, которые позволяют указать, как будут использованы данные утверждения (какие аргументы будут конкретизированы в различных ситуациях). Существуют определенные ограничения на пригодность утверждений для компиляции. Кроме того, системе необходимо задать некоторые другие описания, чтобы она смогла должным образом выполнять смесь интерпретируемых и откомпилированных утверждений.
В Прологе-10 предусмотрены все встроенные предикаты, о которых говорилось в этой книге. Кроме того, он нормально обрабатывает грамматические правила, когда они встречаются в обычном consult. В данном разделе рассматриваются некоторые отличия от приведенных описаний.
Действие предиката display всегда состоит в выдаче аргументов этого предиката на терминал, а не в текущий файл вывода, как было описано.
При рассмотрении арифметических выражений мы говорили, что арифметическое выражение вычисляется только тогда, когда оно задано в качестве второго аргумента предиката is. Во всех других случаях структура вида '24-3' просто обозначает саму себя. В Прологе-10 это не так. Там вычисляются и арифметические выражения, заданные как аргументы других предикатов. Примером этого служат операторы отношения '‹', '=‹' и т. д., а также предикат put. Это означает, что приводимый ниже пример в Прологе-10 будет работать, а в нашем базовом Прологе выдаст ошибку или приведет к неудаче в согласовании цели.
?- 2+4‹12*(2+8).
yes
Еще одна особенность. Структура, представляющая собой список, состоящий из одного числа, рассматривается как арифметическое выражение, значением которого является число. Иными словами в Прологе-10 имеем:
?- X is [25].
X = 25
yes
Благодаря такой комбинации возможностей, вывод одиночных литер может быть задан в мнемоническом виде, например:
?- put("a"), put("b").
ab
yes
(не забывайте, что "а" – это список, состоящий из одного числового кода, соответствующего первой строчной букве алфавита).
Синтаксис отрицания. Предикат с именем notне предусмотрен, но вместо него используется инфиксный оператор '\+' Отсутствует оператор «не равно» ('\=').
Переменные как целевые утверждения. На самом деле это скорее вопрос синтаксиса, чем чего бы то ни было другого. Мы уже видели, как с помощью предиката callможно вызвать целевое утверждение, соответствующее текущему значению переменной Пролога. В Прологе-10 предусмотрен другой способ осуществления этого. Вместо того чтобы вставлять утверждение-цель вида
…, call(X),…
достаточно поставить на место цели саму эту переменную:
…, X,…
При этом использование варианта с callтакже возможно. Более того, при применении к такому утверждению assertaили assertzсистема преобразует цель X в цель call(X).
Задание аргументов для retract.Из-за трудностей, связанных с использованием переменных в качестве целей, в Прологе-10 существуют отличия в том, как должны задаваться тела утверждений в предикате retract.Трудность заключается в том, что когда мы задаем вопрос
?- retract((mother(A,B):- С)).
это может быть истолковано или как просьба об удалении утверждения, имеющего конкретный вид:
mother(A,B):- С.
где в теле утверждения переменная обозначает цель или как просьба об удалении утверждения для предиката motherс любым телом, как, например:
mother(X,Y):- parent(X,Y), female(Y).
Для устранения возможной двусмысленности, в подобных случаях Пролог-10 всегда начинает с замены неконкретизированных переменных, обозначающих одиночные или множественные целевые утверждения в аргументах для retractсоответствующими структурами с функтором call.Таким образом, вопрос
?- retract((mother(A,B):-С)).
фактически рассматривается как
?- retract((mother(A,B):-call(C))).
Если мы хотим удалить первое утверждение для предиката motherнезависимо от его тела, то для этого можно было бы задать:
?- clause(mother(A,B),C), retract((mother(A,B):-С)).
В этом случае первая цель с clauseделает С достаточно конкретизированной, чтобы избежать преобразования.