Материал: Волченков Логическое программирование язык пролог 2015

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Пример 3.6. Печатаются «в столбик» квадраты чисел натурального ряда, пока очередной квадрат не превысит число 1000:

печать_квадратов :– N = 1, квадрат(N, R), write(R), nl,

условие(R), !.

квадрат(N, R) :– R is N^2.

квадрат(N, R) :– N1 is N+1, квадрат(N1, R).

условие(R) :– R > 1000.

UDR-метод (метод «user defined repeat»)

Есть некоторое безвозвратное действие(X), вырабатывающее значение выходного параметра X. Это действие должно многократно повторяться, пока значение параметра X не станет удовлетворять некоторому условию. Для того, чтобы действие стало возвратным, используется встроенный предикат repeat/0. Его семан-

тику поясняет следующее «определение»: repeat.

repeat :– repeat.

Подцель repeat записывается перед подцелью действие(X) в правой части правила, реализующего цикл.

Пример 3.7. Печатаются «в столбик» вводимые пользователем слова, пока не будет введено слово finish:

печать_слов :– repeat, read(W), write(W), nl, условие(W). условие(W) :– W == finish.

Подцель repeat при первом вызове срабатывает без всяких условий. После невыполнения условия осуществляется возврат к этой подцели. Согласно 2-му правилу создаётся новая подцель repeat, которая опять срабатывает без каких-либо условий. И т.д.

4. Встроенный предикат определения новой операции

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

51

Использование таких структур облегчает чтение многих запи-

сей, например вместо знает(Джон, Мери) и человек(Сократ) бо-

лее естественны и понятны записи: Джон знает Мери и Сократ человек.

Для инфиксной структуры в языке Пролог есть специальное название: операция. Функтор такой структуры называется оператором, аргументы структуры – операндами.

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

Пусть, например, @ и # – операторы каких-то бинарных операций над числами. Как понимать следующую запись:

2 # 3 @ 4 @ 5 # 6?

Во-первых, надо знать, какая операция из двух имеет более высокий приоритет, а во-вторых, – правоили левоассоциативной является каждая из них. Естественно, что «узнать» это Прологсистема должна до начала логического вывода, поэтому в начале базы данных часто записываются директивы вида

:- op(700, xfy, #). :- op(600, yfx, @).

В директивах применяется встроенный предикат Пролога op/3, все аргументы которого – входные параметры. 1-й аргумент – значение приоритета определяемой операции, 2-й аргумент – спецификация ассоциативности, 3-й аргумент – знак оператора.

Значение приоритета операции важно только по отношению к значениям приоритета других операций: меньше (выше) или больше (ниже).

Значения второго аргумента означают следующее: yfx – левоассоциативная операция,

xfy – правоассоциативная операция, xfx – неассоциативная операция,

yf и fy – допускающие вложенность

(например: not not true),

xf и fx – не допускающие вложенности

(например: Джон человек человек).

Таким образом, в выражении 2 # 3 @ 4 @ 5 # 6 операции применяются в следующем порядке: ( 2 # ((( 3 @ 4 ) @ 5 ) # 6)).

52

На следующей лекции будут рассмотрены ещё несколько типов встроенных предикатов, а также популярные в Прологе рекурсивные методы программирования. Для более детального знакомства с этими вопросами автор рекомендует книги Дж. Стобо [5] и Дж. Малпаса [6].

53

Лекция 4

Основы программирования на Прологе (продолжение)

В данной лекции, в дополнение к тому, что рассматривалось в предыдущей лекции, представлены ещё две категории встроенных предикатов: 1) для преобразования структур данных и 2) для про-

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

метод исходящей рекурсии.

1. Встроенные предикаты преобразования структур

Рассмотрим только четыре из множества таких предикатов.

Предикат name/2.

Данный предикат преобразует атомоподобный терм (атом, число или строку) в список кодов символов, из которых этот терм состоит. Или наоборот, список кодов – в атомоподобный терм. Например:

?– name(ася, X). →

X = [1072, 1089, 1103]

?– name(X, [97, 98, 98,

97]). → X = abba

Предикат functor/3.

Данный предикат анализирует структуру произвольного вида (1-й аргумент): определяет её имя (2-й аргумент) и её арность (3-й аргумент). Или наоборот – синтезирует структуру произвольного вида (1-й аргумент) по известному имени (2-й аргумент) и арности (3-й аргумент). Например:

?– functor(f(a, b, c), X, Y).

→

X = f, Y = 3

?– functor(X, f, 3). →

X = f(_, _, _)

54

Предикат arg/3.

В отличие от предыдущих предикатов этот предикат работает только «в одну сторону»: его спецификация arg/(i, i, o). Для заданной структуры произвольного вида (2-й аргумент) по номеру ее компонента (1-й аргумент) находится значение этого компонента (3-й аргумент). Например:

?– arg(2, f(a, b, c), X). ?– arg(2, [a, b, c, d], X).

→X = b

→X = [b, c, d]

«В обратную сторону» предикат arg/3 работать не может – по значению компонента структуры нельзя находить его номер.

Предикат =../2.

Данный предикат преобразует структуру произвольного вида (1- й аргумент) в список (2-й аргумент). Или наоборот – список в структуру. Голова списка (1-й элемент) – имя структуры, хвост списка (2-й элемент) – компоненты структуры. Таким образом, длина списка на единицу больше числа компонентов структуры. Примеры:

?– f(a, b, c) =.. X. ?– X =.. [f, a, b, c].

→X = [f, a, b, c]

→X = f(a, b, c)

2. Примеры предикатов обработки списков

Список, как уже было отмечено, является наиболее используемой структурой данных Пролога. Поэтому в разных реализациях Пролога (в разных Пролог-системах) почти всегда присутствуют встроенные предикаты обработки списков: member/2, append/3, reverse/2, sort/2 и т.д. Но иногда их приходится определять. Приведем определения этих предикатов без комментариев. (Автор оставляет слушателям или читателям возможность самостоятельно изучить их семантику непосредственно по определениям.)

55

Источник: https://studfile.net/preview/16708744/