Скачиваний:
201
Добавлен:
17.06.2016
Размер:
2.69 Mб
Скачать

Объявление ссылочных типов

Когда система обнаруживает при выходе из предложения свободную пере-

менную, то выдается предупреждение. Если при этом вы нажмете F10, то пе-

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

типа. Для того, чтобы не нажимать F10 при каждой компиляции вы должны яв-

но объявить тип переменной как ссылочный (reference) в секции типов

(domains). Это также необходимо при создании проекта (т.е. программы,

состоящей из нескольких модулей); когда в программе появляется свободная

переменная, относящаяся к глобальному типу, вы уже не отделаетесь простым

нажатием F10.

Необходимо заметить, что следующие предопределенные типы не могут

быть объявлены как ссылочные: file, reg, db_selector, bt_selector и

place.

Ссылочные типы и массив trail

Поскольку применение ссылочных типов вызывает ряд дополнительных

проверок, применение ссылочных типов вызывает некоторое увеличение време-

ни выполнения программы. Однако, применение ссылочных типов облегчает ре-

шение целого ряда задач, и поэтому в Турбо Прологе существуют средства

для уменьшения этого времени.

При объявлении ссылочных типов в Турбо Прологе используется массив

trail. Массив trail используется для запоминания ссылочных переменных.

Это необходимо, поскольку при передаче значения ссылочной переменной в

Турбо Прологе выполняется перезапись ссылочной записи. При работе с обыч-

ными типами значения передаются с помощью параметров. Вы можете изменить

размер массива Trail с помощью директивы компилятора trail, а также с по-

мощью команды O/C//Trail Array из меню системы.

Поскольку все переменные относящиеся к одному и тому же типу обраба-

тываются одинаково, то объявление какого-нибудь базового типа в качестве

ссылочного является не самым удачным решением. Например, в следующем

фрагменте программы тип refinteger объявляется как ссылочный тип для це-

лого типа. При каждом появлении типа refinteger он будет обрабатываться

как ссылочный, а переменные типа integer будут обрабатываться как пере-

менные целого типа.

domains

refinteger = reference integer

predicates

p(refinteger)

clauses

p(_).

Применение ссылочного типа

Правильным является применение ссылочных типов лишь в тех местах,

где это действительно необходимо, а во всех остальных случаях использо-

вать переменные обычного типа. В Турбо Прологе вы можете преобразовывать

переменные ссылочного типа в переменные обычного типа, где это необходи-

мо. Вы можете создать, например, предикат, который преобразует ссылочный

целый тип в обычный целый тип с помощью следующего фрагмента:

domains

refint = reference integer

predicates

conv(refint,integer)

clauses

conv(X,X).

В Турбо Прологе преобразование переменной из ссылочного в обычный

тип происходит автоматически (как это выполняется в предложении conv, в

котором Х преобразуется из refint в integer). Необходимо отметить, что

ссылочной переменной должно быть присвоено фактическое значение прежде,

чем переменная будет преобразована к обычному типу. Аналогичным образом,

если вы пытаетесь преобразовать переменную из одного ссылочного типа в

другой (например, из reference integer в reference char), вы должны быть

уверены, что переменная является связанной. В противном случае будет вы-

дано сообщение: "Free variable are not allowed here".

Обращайте внимание на автоматическое преобразование типов при полу-

чении новой свободной ссылочной переменной путем обращения к free, напри-

мер:

free(X), Y=X, bind_integer(X),...

или получения свободной переменной при помощи предиката = (равно), напри-

мер:

Y=X,bind_integer(X),...

В этих примерах при использовании предикатов free и = возникают

трудности при получении правильного типа. Механизм проверки типов пытает-

ся определить тип переменной во время слежения с возвратом при помощи

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

типов будет выбран тип char (поскольку тип char может быть преобразован к

типу integer).

С помощью ссылочного типа вы можете получать значения переменных,

которым эти значения были присвоены несколько позже. Вы можете также соз-

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

Пример

Для того, чтобы поближе познакомиться с работой ссылочного типа,

попробуйте ввести ряд целевых утверждений с применением хорошо знакомых

предикатов member и append:

/* Program CH19EX04.PRO */

domains

refinteger = integer

reflist = reference refinteger*

predicates

member(refinteger, reflist)

append(reflist, reflist, reflist)

clauses

member(X, [X|_]).

member(X, ([_|L]) :- member(X, L).

append([], L, L).

append([X|L1], L2, [X|L3]) :- append(L1, L2, L3).

Загрузите эту программу, затем запустите ее, нажав Alt-R и введите

следующие целевые утверждения:

member(1,L).

member(X,L),X=1

member(1,2),member(2,L).

X=Y,member (Y,L),X=3.

member(1,L0,append(L,[2,3],L1).

append(L,L,L1),ember(1,L).

L1=[1,2,3],append(L2,L2,L3),append(L1,L1,L3).

Сравните полученные ответы с тем, что вы предполагали получить.

Соседние файлы в папке Документация