Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник_Final.doc
Скачиваний:
59
Добавлен:
09.11.2019
Размер:
10.39 Mб
Скачать

3.6. Списковые структуры

Пролог работает с такими структурами данных как бинарные деревья и структурные списки, причем списки являются частным случаем бинарных деревьев.

Для выполнения операций, связанных с обработкой текстов, в таких языках программирования как LISP необходимо наличие операции следования. В Пролог-программе процедура следования задаётся в виде списковой структуры данных.

Список – представляет собой упорядоченный набор объектов (элементов списка), следующих друг за другом. Элементы списка должны принадлежать к одному и тому же доменному типу. В теле программы список задается с помощью символа «*».

Пример.

domains

list_num = integer * /* список целых чисел */

predicates

num (list_num)

или

domains

list_num = element * /* список чисел типа element */

element = integer /* тип element определен как целое*/

Список в Пролог-программе − это совокупность термов, разделенных запятыми и заключенных квадратные в скобки.

Пример.

["Лена", "Петр", "Олег", "Сергей"];

[1, 2, 3, 6, 9, 3, 4];

[3.2, 4.6, 1.1, 2.64, 100.2];

[yesterday, today, tomorrow];

[element01] – список из одного элемента;

[ ] – пустой список;

G = graf ([a, b, c, d], [r(a, b), r(b, c), r(b, d), r(d, c)]) – описание графа в виде совокупности списков его вершин и дуг (ребер).

Для повышения наглядности программ в Прологе предусматриваются специальные средства списковой нотации, позволяющие представлять списки не только в традиционном виде [элемент_1, элемент_2, ... , элемент_N], но и в бинарной форме: [H | T] , где H (Head) – это голова списка, T (Tail) – хвост или окончание списка, а знак «|» служит разделителем. Например, список [a, b, c, d] может быть записан следующими способами:

  • [a] | [b, c, d];

  • [a, b] | [c, d];

  • [a, b, c] | [d];

  • [a, b, c, d] | [ ].

Следует отметить, что аргумент Т может быть определен рекурсивно, т.е. может сам являться списком и в свою очередь также состоять из головы и хвоста. Для ограничения рекурсии в любом списке Пролог-программе используют символ пустой список [3].

Пример.

Программа вычисления суммы элементов векторов X и Y, представленных в виде списков: X = (x1, x2, ... , xN) и Y = (y1, y2, ... , yN).

domains

vector = integer*

predicates

product (vector, vector, integer)

goal

product ([1, 2, 3], [7, 8, 9], Rez),

write ("Rez = ", Rez).

clauses

product([ ], [ ], 0).

product ([X | Xs], [Y | Ys], S) :- product (Xs, Ys, Sp),

S = X + Y + Sp.

Поясним работу программы. Рекурсивное правило описывает отсроченные вычисления (табл. 3.2). После рекурсивного вызова остается невыполненным хвост правила, конец которого помещается в стек до тех пор, пока не произойдет сопоставление с первым вариантом правила. После того как это произойдет, частичная сумма Sp получит значение 0, и все накопленные в стеке хвостовые вычисления будут выполнены в обратном порядке.

Таблица 3.2.

Вызов предиката

Подстановки

Хвостовые вычисления

Результат вычислений

product ([1, 2, 3], [7, 8, 9], Rez)

X = 1, Y = 7,

Xs = [2, 3], Ys = [8, 9],

Rez=S

S=X*Y+Sp

S=1*7+43=50

product ([2, 3], [8, 9], Sp)

X’ = 2, Y’= 8,

Xs’ = [3], Ys’ = [9],

Rez=Sp

Sp=X’*Y’+Sp

Sp=2*8+27=43

product ([3], [9], S’)

X’’ = 3, Y’’ = 9,

Xs’’ = [2, 3], Ys’’ = [8, 9],

Sp=Sp’

Sp’=X’*Y’+Sp

Sp’=3*9+0=27

product ([ ], [ ], Sp’’)

Xs’’ = [ ], Ys’’ = [ ],

Sp’’ = 0

Sp’’=0