Смекни!
smekni.com

Интерпретатор языка Пролог (стр. 7 из 15)

5. Если после своего выполнения условие вернуло значение False, то запускается механизм обратного прохода. Уничтожается последний элемент TSubStackNode, и программа возвращается к предыдущему условию и пытается найти новое решение для него.

6. Если все условия были выполнены, то формируются выходные параметры и функция возвращает истину. В противном случае, программа возвращается к пункту 1 и пытается найти еще одно предложение, соответствующее входным данным.

7. Если были исчерпаны все предложения и ни для одно не было найдено решения, то необходимо возвратить False.

2.3.1 Выполнение обращений к базам данных

Обращение к базе данных происходит с помощью SQL-запросов.

При первом обращении к базе данных создается объект SQL-запроса и сам запрос.

Формат SQL-запроса

SELECT <поле1>,…,<полеN>

FROM <имя базы данных>

WHERE

<поле1>=<значение1> and

<поле2>=<значение2> and

<полеN>=<значениеN>

В запросе используются только условия-равенства, так как в Прологе при сопоставлении значении на входе в предикат используется только сравнение.

В список условий помещаются только те поля, значения которых на входе определены.

При первом обращении к базе берется первая запись из запроса.

При последующих вызовах базы данных (в случае обратного пути в бэктрекинге) объект SQL-запроса не создается, а используется ранее созданный, и применяется функция Next для доступа к следующей записи.

Таким образом, доступ к базе данных осуществляется как обычным предикатам, которые состоят только из предложений-фактов.

2.3.2 Вычисление арифметических выражений

На основе построенного при компиляции дерева арифметического выражения достаточно несложно, используя рекурсию, вычислить выражение.

На вход функции поступает объект с деревом арифметического выражения и объект со списком переменных, созданных ранее программой.

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

Дерево может состоять из одного элемента, если это константа или переменная. На этом шаге рекурсия заканчивается и возвращается значение константы или переменной (если до этого в списке переменных ее не значилось, то создается новая переменная).

2.4 Объекты, используемые компилятором и интерпретатором

2.4.1 Объекты переменных TPrologVariable, TPrologVariables,

TPrologVariableList, TPrologVariableStruct

Для преставления переменных всех типов (целые, дробные, строки, логические, списки, структуры) служит класс TPrologVariable. Для определения типа переменной служит поле iType. В поле Data хранится указатель на данные, соответствующие типу. Для простых типов (целые, дробные, строки, логические) – это указатель на соответствующий тип. Конструктор создает переменную без типа. Деструктор автоматически освобождает память для переменной любого типа. Для этого класса опеределены следующие методы:

1. procedure CreateVariable(DomainType:string; vName:string) - создание переменной типа DomainType с именем vName;

2. procedure DestroyVariable - уничтожение переменной (эта процедура не является деструктором, так как не уничтожает сам объект, а только освобождает память)

3. function CreateCopy:TPrologVariable - создание точной копии переменной;

4. procedure AssignVariable (v:TPrologVariable) - присваивание значения переменной.

Для представления списков введен класс TPrologVariableList, в котором хранится имя типа списка, имя типа элемента списка, тип представления списка (в виде перечисления элементов или «голова-хвост»), а также динамический массив, содержащий объекты TPrologVariable, являющиеся элементами списка.

В структурах (TPrologVariableStruct) аналогично хранится имя типа структуры, массив с типами элементов структуры и динамический массив с элементами структуры.

Следует отметить, что в классе TPrologVariable, могут храниться как переменные, так и константы. У константы поле Name - пустая строка.

Класс TPrologVariables позволяет организовать к пакету переменных:

1. procedure AddVariable(v:TPrologVariable) - добавление переменной в список переменных;

2. function AddNewVariable:TPrologVariable - создание и добавление новой переменной в список;

3. procedure DeleteVariable(n:integer) procedure DeleteVariable(vName:string) procedure DeleteLastVariable - удаление переменной по ее индексу или по имени, либо последнюю переменную в списке;

4. function VariableByName(vName:string):TPrologVariable - доступ к конкретной переменной по ее имени;

5. property Variables[ind:integer]:TPrologVariable - свойство, оргназиующее доступ к переменным как к массиву переменных.

2.5.2 Стандартные функции и предикаты

Все стандартные функции и предикаты имеют одинаковые параметры.

Объявление функции выглядит следующим образом:

TStdFunction=function (Args:TPrologVariables):TPrologVariable;

Args – пакет с входными параметрами.

Функция возвращает значение в виде переменной TPrologVariable.

Объявление функции, выполняющая работу предиката:

TStdPredicate=function (VarPacket:TPrologVariables; BackTracking:Boolean):Boolean;

VarPacket – пакет с параметрами к предикату

BackTracking – логическая переменная, которая установлена в True, если предикат был вызван на обратном пути алгоритма бэктрекинга.

Функция возвращает логическое значение, которое должен возвратить предикат после своего выполнения.

2.6 Представление Пролог-программы в виде объектов

Для хранения откомпилированной Пролог-программы используются три класса TPrologTerm, TPredicateClause и TProgramPredicate.

TPrologTerm служит для хранения одного условия внутри предложения. В нем хранится тип условия (выражение, предикат, база данных), позиция условия в тексте Пролог-программы, а также указатель (Data) на объект представляющий данное условие (TSubTermPredicate, TSubTermExtData, TSubTermExpression).

TSubTermPredicate служит для хранения условий-предикатов. В данном классе есть следующие поля:

1. Name :String - имя предиката;

2. StandardPredicate :Boolean - True - если предикат стандартный;

3. Params :TVariablesArray - параметры для вызова предиката;

4. NoInverse :Boolean - признак наличия или отсутствия инверсии перед вызовом предиката.

TSubTermExtData аналогичен классу TSubTermPredicate за исключением того, что в нем нет поля StandardPredicate.

TSubTermExtData предназначен для представления арифметических выражений. Он представляет собой рекурсивный объект с полями LeftHand и RightHand для представления выражений левой и правой частей выражения. Данный класс содержит следующие поля:

1. Operation :TExpressionOperation - тип операции;

2. FuncName :String - имя функции, если Operation=eoFunction;

3. Operand :TPrologVariable - переменная или константа, если Operation=eoVariable;

4. LeftHand :TSubTermExpression - левая часть выражения;

5. RightHand :TSubTermExpression - правая часть выражения

6. FuncParams :array of TSubTermExpression - параметры функции, если Operation=eoFunction.

TPredicateClause хранит в себе одно предложение. Параметры предложения хранятся в массиве Params, а условия - в Terms.

TProgramPredicate хранит полную информацию о предикате. Объект этого класса используется как на этапе компиляции, так и на этапе интерпретации. Он хранит имя предиката (Name), типы параметров, текст предиката, все лексемы предиката, а также массив с предложениями предиката.

Класс TPrologProgram хранит всю информацию о Пролог-программе:

· Описания типов (Domains);

· Описания баз данных (ExtData);

· Предикаты (TProgramPredicate);

· Массив со стеком (Stack);

· Массив с контрольными точками (BreakPoints);

· Имя запускаемого предиката (StartPredicate);

· Флаг работы программы (OnTheRun).

2.7 Основные модули

Модуль CompileUnit. В данном модуле определяется класс пролог-программы - TPrologProgram, а также два класса, использующихся при запуске интерпретатора: TStackNode и TSubStackNode. Модуль CompileUnit является ядром интерпретатора.

Модуль ProgramClasses. В данном модуле описываются основные классы, использующиеся в объектах TPrologProgram, TStackNode и TSubStackNode как контейнерные:

– TLexemRecord - представляет одну лексему, выделенную из текста программы;

– TPrologVariable - представляет переменную во время выполнения пролог-программы.

– TPrologVariableList - контейнерный класс, использующийся в TPrologVariable, для представления списков;

– TPrologVariableStruct - контейнерный класс, использующийся в классе TPrologVariable, для представления структур;

– TPrologVariables - класс, представляющий собой список переменных TPrologVariable с возможностью доступа к переменной по имени;

– TSubTermPredicate - класс использующийся в TPrologTerm для представления обычного предикатного условия в предложении;

– TSubTermExtData - класс использующийся в TPrologTerm для представления предикатного условия вызова базы данных в предложении;

– TSubTermExpression - класс использующийся в TPrologTerm для представления арифметических выражений в предложении;

– TPrologTerm - класс использует TSubTermPredicate, TSubTermExtData, TSubTermExpression как контейнерные для представления одного условия в предложении;

– TPredicateClause - использует массив объекстов TPrologTerm и TPrologVariable для представления одного предложения в программе;

– TProgramDomain - класс использующийся в TPrologProgram как контейнерный для описания типов;

– TProgramExtData - класс использующийся в TPrologProgram как контейнерный для описания баз данных;

– TProgramPredicate - класс использующийся в TPrologProgram как контейнерный для описания предикатов;

– TPrologFile - класс использующийся в TPrologProgram как контейнерный для описания файлов открытых во время выполнения программы;

Модуль PrologRunTime описывает класс ошибок TRunTimeError, а также все функции и встроенные предикаты Пролога.

MainFormUnit - модуль описания главной формы TMainForm;

ProgFormUnit - модуль описания окна инспектора TProgForm;

DomConstrFormUnit - модуль описания конструктора типов TExtDataForm;

ExtDataFormUnit - модуль описания конструктора баз данных TExtDataForm;