Jump to content

Синтаксис и семантика Пролога

Синтаксис соответственно и семантика Пролога . , языка программирования , представляют собой наборы правил, которые определяют, как пишется программа на Прологе и как она интерпретируется Правила изложены в стандарте ISO/IEC 13211. [1] хотя существуют различия в реализациях Пролога .

Типы данных

[ редактировать ]

Пролог является динамически типизированным . Он имеет единственный тип данных term , который имеет несколько подтипов: атомы , числа , переменные и составные термины .

Атом . — это имя общего назначения, не имеющее внутреннего значения Он состоит из последовательности символов, которая анализируется программой чтения Пролога как единое целое. Атомы обычно представляют собой простые слова в коде Пролога, написанные без специального синтаксиса. Однако атомы, содержащие пробелы или некоторые другие специальные символы, должны быть заключены в одинарные кавычки. Атомы, начинающиеся с заглавной буквы, также необходимо заключать в кавычки, чтобы отличать их от переменных. Пустой список, написанный [], тоже атом. Другие примеры атомов включают x, blue, 'Taco', и 'some atom'.

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

Переменные обозначаются строкой, состоящей из букв, цифр и символов подчеркивания и начинающейся с заглавной буквы или подчеркивания. Переменные очень похожи на переменные в логике, поскольку они являются заполнителями для произвольных терминов. Переменная может быть создана (привязана к определенному термину) посредством унификации . Одно подчеркивание ( _) обозначает анонимную переменную и означает «любой термин». В отличие от других переменных, подчеркивание не представляет одно и то же значение везде, где оно встречается в определении предиката.

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

Примеры сложных терминов: truck_year('Mazda', 1986) и 'Person_Friends'(zelda,[tom,jim]). Составные термины с функторами, объявленными как операторы, могут быть записаны в префиксной или инфиксной записи. Например, условия -(z), +(a,b) и =(X,Y) также можно записать как -z, a+b и X=Y, соответственно. Пользователи могут объявлять произвольные функторы как операторы с различным приоритетом, чтобы обеспечить нотации, специфичные для предметной области. Обозначение f/n обычно используется для обозначения термина с функтором f и арностью n .

Особые случаи сложных терминов:

  • Списки определяются индуктивно: атом [] это список. Составной термин с функтором . (точка) и арность 2, второй аргумент которой является списком, сам является списком. Для обозначения списков существует специальный синтаксис: .(A, B) эквивалентно [A|B]. Например, список .(1, .(2, .(3, []))) также можно записать как [1 | [2 | [3 | []]]]или даже более компактно, как [1,2,3].
  • Строки : последовательность символов, заключенная в кавычки, эквивалентна списку (числовых) кодов символов, обычно в локальной кодировке символов или Unicode , если система поддерживает Unicode.

Пролог-программы

[ редактировать ]

Программы на Прологе описывают отношения, определяемые посредством предложений. Чистый Пролог ограничен предложениями Хорна , полным по Тьюрингу первого порядка подмножеством логики предикатов . Существует два типа предложений: факты и правила. Правило имеет вид

Head :- Body.

и читается как «Голова верна, если Тело истинно». правила Тело правила состоит из вызовов предикатов, которые называются целями . Встроенный предикат ,/2 (имеется в виду 2-арный оператор с именем ,) обозначает соединение целей, а ;/2 обозначает дизъюнкцию . Союзы и дизъюнкции могут появляться только в теле, а не в начале правила.

Предложения с пустым телом называются фактами . Пример факта:

cat(tom).

что эквивалентно правилу:

cat(tom) :- true.

другой пример:

X is 3+2.

и когда вы запустите его, результат будет

 X=5
 Yes.


Встроенный предикат true/0 всегда верно.

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

mother_child(trude, sally).
 
father_child(tom, sally).
father_child(tom, erica).
father_child(mike, tom).
 
sibling(X, Y)      :- parent_child(Z, X), parent_child(Z, Y).
 
parent_child(X, Y) :- father_child(X, Y).
parent_child(X, Y) :- mother_child(X, Y).

Это приводит к тому, что следующий запрос оценивается как истинный:

?- sibling(sally, erica).
Yes

Это достигается следующим образом: изначально единственный совпадающий заголовок предложения для запроса sibling(sally, erica) является первым, поэтому доказательство запроса эквивалентно доказательству тела этого предложения с соответствующими привязками переменных, т. е. соединением (parent_child(Z,sally), parent_child(Z,erica)). Следующая цель, которую необходимо доказать, — это крайняя левая цель этого соединения, т. е. parent_child(Z, sally). Этой цели соответствуют два заголовка статей. Система создает точку выбора и пробует первую альтернативу, тело которой father_child(Z, sally). Эту цель можно доказать, используя тот факт father_child(tom, sally), поэтому привязка Z = tom генерируется, и следующей целью, которую необходимо доказать, является вторая часть приведенного выше союза: parent_child(tom, erica). Опять же, это можно доказать соответствующим фактом. Поскольку все цели могут быть доказаны, запрос завершается успешно. Поскольку запрос не содержал переменных, пользователю не сообщается ни о каких привязках. Запрос с переменными, например:

?- father_child(Father, Child).

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

Обратите внимание, что в приведенном выше коде запрос ?- sibling(sally, sally). также преуспевает. При желании можно было бы добавить дополнительные цели для описания соответствующих ограничений.

Циклы и рекурсия

[ редактировать ]

Итерационные алгоритмы могут быть реализованы с помощью рекурсивных предикатов. Системы Пролога обычно реализуют хорошо известную технику оптимизации, называемую оптимизацией хвостового вызова (TCO), для детерминированных предикатов, демонстрирующих хвостовую рекурсию или, в более общем плане, хвостовые вызовы: кадр стека предложения отбрасывается перед выполнением вызова в хвостовой позиции. Таким образом, детерминированные предикаты хвостовой рекурсии выполняются с постоянным пространством стека, как циклы в других языках.

Разрез ( !) внутри правила не позволит Прологу выполнить возврат любых предикатов за вырезом:

predicate(X) :- one(X), !, two(X).

потерпит неудачу, если первое найденное значение X для чего one(X) правда, приводит к two(X) будучи ложным.

Анонимные переменные

[ редактировать ]

Анонимные переменные _ никогда не привязаны к значению и могут использоваться в предикате несколько раз.

Например, поиск в списке по заданному значению:

contains(V, [V|_]).
contains(V, [_|T]) :- contains(V, T).

Отрицание

[ редактировать ]

Встроенный предикат Пролога \+/1 предоставляет отрицание как отказ , что позволяет проводить немонотонные рассуждения. Цель \+ illegal(X) в правиле

legal(X) :- \+ illegal(X).

оценивается следующим образом: Пролог пытается доказать illegal(X). Если доказательство этой цели может быть найдено, первоначальная цель (т. е. \+ illegal(X)) терпит неудачу. Если доказательств не найдено, первоначальная цель достигнута. Таким образом, \+/1 префиксный оператор называется «недоказуемым» оператором, поскольку запрос ?- \+ Goal. успешна, если цель недоказуема. Этот вид отрицания является правильным , если его аргумент «основной» (т. е. не содержит переменных). Разумность теряется, если аргумент содержит переменные. В частности, запрос ?- legal(X). теперь нельзя использовать для перечисления всего, что является законным.

Семантика

[ редактировать ]

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

predicate1(X) :-
  predicate2(X,X).
predicate2(X,Y) :-
  predicate1(X),
  X \= Y.

Учитывая этот порядок, любой запрос формы

?- predicate1(atom).

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

predicate2(X,Y) :-
  X \= Y,
  predicate1(X).

тот же запрос приведет к результату «Нет» за очень короткое время.

Определенные грамматики предложений

[ редактировать ]

Существует специальная нотация, называемая грамматиками определенного предложения ( DCG ). Правило, определенное через -->/2 вместо :-/2 расширяется препроцессором ( expand_term/2, средство, аналогичное макросам в других языках) в соответствии с несколькими простыми правилами переписывания, в результате чего получаются обычные предложения Пролога. В частности, переписывание снабжает предикат двумя дополнительными аргументами, которые можно использовать для неявного связывания состояния, аналогично монадам в других языках. DCG часто используются для написания анализаторов или генераторов списков, поскольку они также предоставляют удобный интерфейс для перечисления различий.

Пример парсера

[ редактировать ]

Более крупный пример покажет потенциал использования Пролога при синтаксическом анализе .

Учитывая предложение, выраженное в форме Бэкуса-Наура :

<sentence>    ::=  <stat_part>
<stat_part>   ::=  <statement> | <stat_part> <statement>
<statement>   ::=  <id> = <expression> ;
<expression>  ::=  <operand> | <expression> <operator> <operand>
<operand>     ::=  <id> | <digit>
<id>          ::=  a | b
<digit>       ::=  0..9
<operator>    ::=  + | - | *

Это можно написать на Прологе с использованием DCG, что соответствует прогнозирующему анализатору с упреждающим просмотром одного токена:

sentence(S)                --> statement(S0), sentence_r(S0, S).
sentence_r(S, S)           --> [].
sentence_r(S0, seq(S0, S)) --> statement(S1), sentence_r(S1, S).
 
statement(assign(Id,E)) --> id(Id), [=], expression(E), [;].
 
expression(E) --> term(T), expression_r(T, E).
expression_r(E, E)  --> [].
expression_r(E0, E) --> [+], term(T), expression_r(plus(E0,T), E).
expression_r(E0, E) --> [-], term(T), expression_r(minus(E0, T), E).
 
term(T)       --> factor(F), term_r(F, T).
term_r(T, T)  --> [].
term_r(T0, T) --> [*], factor(F), term_r(times(T0, F), T).
 
factor(id(ID))   --> id(ID).
factor(digit(D)) --> [D], { (number(D) ; var(D)), between(0, 9, D)}.
 
id(a) --> [a].
id(b) --> [b].

Этот код определяет связь между предложением (представленным в виде списка токенов) и его абстрактным синтаксическим деревом (AST). Пример запроса:

?- phrase(sentence(AST), [a,=,1,+,3,*,b,;,b,=,0,;]).
AST = seq(assign(a, plus(digit(1), times(digit(3), id(b)))), assign(b, digit(0))) ;

AST представлен с использованием терминов Пролога и может использоваться для применения оптимизаций, компиляции таких выражений в машинный код или для прямой интерпретации таких операторов. Как это типично для реляционной природы предикатов, эти определения можно использовать как для анализа и генерации предложений, так и для проверки соответствия данного дерева заданному списку токенов. Используя итеративное углубление для справедливого перечисления, в конечном итоге будет сгенерировано каждое произвольное, но фиксированное предложение и соответствующий ему AST:

?- length(Tokens, _), phrase(sentence(AST), Tokens).
 Tokens = [a, =, a, (;)], AST = assign(a, id(a)) ;
 Tokens = [a, =, b, (;)], AST = assign(a, id(b))
 etc.

См. также

[ редактировать ]
  1. ^ ISO/IEC 13211: Информационные технологии. Языки программирования. Пролог . Международная организация по стандартизации , Женева.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: e5371d70ac2cf377ddb052aff1e3b04e__1686515760
URL1:https://arc.ask3.ru/arc/aa/e5/4e/e5371d70ac2cf377ddb052aff1e3b04e.html
Заголовок, (Title) документа по адресу, URL1:
Prolog syntax and semantics - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)