Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мет_для_лаб_Мтзкіт_2011.docx
Скачиваний:
3
Добавлен:
01.12.2018
Размер:
126.32 Кб
Скачать

Модульне програмування на visual prolog

В.1 Структура модульної програми на Visual Prolog

Програма з декількох модулів має один головний модуль і декілька допоміжних модулів. Модулі програми взаємодіють через виклики певних процедур і фактів.

Всі модулі програми оформлюються подібно програмі з одного модуля, тобто мають секції опису предикатів і доменів(типів даних) і секції тверджень.

Відміна головного модуля від інших модулів лише в тому, що головний модуль має секцію Goal, а інші модулі не мають.

На Пролозі область реалізації містить локальні описи доменів і предикатів і локальні твердження. Локальні описи і твердження можуть застосовуватися тільки в модулю, в якому вони знаходяться.

З локальних тверджень складаються процедури модуля.

Область інтерфейсу містить глобальні описи доменів і описи глобальних предикатів. Кожна глобальна секція починається словом Global.

Глобальні секції Predicates і Facts містять опис предикатів, якими записані твердження процедур і динамічні факти. Такі процедури і факти, можна викликати з інших модулів.

В програмі може бути лише одна неіменована секція Facts. Тому, якщо є одна глобальна секція Facts, то в будь-якому модулі можуть бути лише іменовані локальні секції Facts.

Глобальні факти з характеристикою single можуть розміщуватися тільки в головному модулі. Причому секція Goal повинна розміщуватися перед секцією Clauses, у якій розташований.

Глобальні динамічні факти створюють окремий модуль програми.

Порядок розміщення локальних і глобальних секцій у програмі не важливий.

Порядок об’явлення глобальних доменів і глобальних предикатів у різних модулях може бути різним.

Крім того, головний модуль повинен мати всі глобальні об’яви програми, а інші модулі можуть мати тільки ті описи, що вони застосовують. Тобто різні модулі програми можуть мати різний вміст глобальних об’яв.

Такий підхід дозволяє створювати бібліотеки в об’єктних кодах з процедурами, що застосовує вся програма.

В.2 Глобальні описи предикатів

Для кожного глобального предикату треба вказати набір можливих конкретизацій параметрів.

Наприклад, Global Predicates

nondeterm str_len(string, integer) - (i, o) (i, i) (o, i)

Якщо конкретизація параметрів не вказана, то по замовчанню всі параметри процедури вважаються вхідними.

Глобальним може бути предикат - функція, що написаний на мові Visual Prolog. При об’яві предикату - функції перед функтором вказують його тип.

Наприклад. Global Predicates

nondeterm integer kvadrat(integer) - (i)

Пролог може викликати програму написану на іншій мові програмування. Таку програму об’являють в програмі на Пролозі , як зовнішній предикат. Об’ява зовнішнього предикату повинна містити мову. Наприклад, для використання програми на мові С, треба об’явити:

Global Predicates

pro_c(integer, integer) - (i, o) language c

В.3 Приклад модульної програми

Розглянемо приклад модульної програми. Програма обчислює вік людини. Вона містить головний модуль і два допоміжних. Модулі програми дуже малі. Це допоможе краще зрозуміти структуру програми.

Головний модуль «Р1» видає повідомлення, що буде обчислено вік людини. Модуль «Р11» пропонує ввести поточний рік і вводить його. Модуль «Р12» пропонує ввести рік народження і вводить його.

Після чого головний модуль обчислює вік людини і виводить його.

Для створення модульної програми ми відокремимо інтерфейси модулів від секцій реалізацій модулів.

Модулі програми, що подані нижче не містять глобальних об’яв.

/*Головний модуль Р1*/

Include “P1.inc”

Predicates

do

Goal

do.

Clauses

do:-write("Підрахуємо ваш вік "), nl, рік_народження(Рік_н),

рік_поточний(Рік_п), Вік= Рік_п - Рік_н,

write("Ваш вік ", Вік).

/*Модуль Р11*/

Include “P1.inc”

Clauses

рік_поточний (Рік_п):- write("Введіть поточний рік"), nl, readint(Рік_п).

/*Модуль Р12*/

Include “P1.inc”

Clauses

рік_народження (Рік_н):- write("Введіть рік народження "),nl, readint(Рік_н).

Створимо файли з глобальних доменів для кожного модуля свій. Аналогічно створимо файли з глобальних предикатів для кожного модуля свій.

/* Project: P1 FileName: p11.DOM */

Global domains

рік_пот = integer

/* Project: P1 FileName: p11.PRE */

Global Predicates

рік_поточний (рік_пот)-(o)

/* Project: P1 FileName: p12.DOM */

Global domains

рік_нар = integer

/*Project: P1 FileName: p12.PRE*/

Global Predicates

рік_народження (рік_нар)-(o)

Такий підхід дозволяє за допомогою директив include та експерту застосувань злити автоматизовано всі файли в один P1.inc, а злитий файл включити в кожний модуль програми за директивою Include “P1.inc”.

Структура файлу P1.inc після злиття файлів подана нижче.

/* Project:p1 FileName: P1.INC*/

global domains

DB_SELECTOR = browselist_db % For treebrowser tool

FILE = fileselector1; fileselector2 % To be edited

include "p11.dom"

include "p11.pre"

include "p12.dom"

include "p12.pre"

Компілятор за директивою Include “P1.inc” в кожному модулі включає файл P1.inc в модуль. Після чого переглядає включені об’яви і знаходячи знову директиви Include знову включає в модулі об’яви.

Такий метод працює надійніше, ніж програміст буде сам вибирати з кожного модуля глобальні об’яви включати їх у головний модуль.

В.4 Створення модульної програми експертом застосування

Програму, що складається з декількох модулів, неможливо взагалі створити без опції Project. Для реалізації такої програми треба мати засоби опису структури програми з модулів.

Після створення проекту і головного модуля створити новий модуль і додати його до структури програми можна за опцією NEW.

Опція NEW

Опція відкриває каталог проекту. Пропонується ввести ім’я модуля для створення файлу у каталозі проекту опцією «open». В файлі буде зберігатися модуль програми на вихідній мові.

У вікні експерту застосування до структури проекту додається модуль з вказаним ім’ям. По замовчанню кожен модуль містить директиву Include “<ім’я головного модуля>.inc”, щоб включити у всі модулі всі глобальні об’яви.

Далі у діалоговому вікні File Inclusions for Module запитується, які файли з глобальними об’явами необхідно створити для поточного модуля і куди включати.

Якщо користувач ще не знає, чи буде модуль містити глобальні предикати і домени, то можна відмовитися від створення файлів. До діалогового вікна можна повернутися за опцією ATTRIBUTES у вікні експерта застосування після написання модуля. На рисунку В.1 показано, які можливості треба обрати, щоб реалізувати описаний метод.

Рисунок В.1- File Inclusions for Module

Опції EDIT і DELETE застосовуються для корегування обраного модуля або вилучання відповідно.

В.5 Команди компіляції та побудови програми

Команда PROJECT/COMPILE MODULE (Ctrl+F9) компілює обраний модуль.

Команда PROJECT/BUILD (Alt+F9) компілює модулі, що були змінені та будує програму.

Команда PROJECT/REBUILD ALL (Ctrl+Alt+F9) компілює всі модулі і будує програму.

Команда PROJECT/LINK ONLY (Shift+F9)

Команда не компілює модулі. Вона будує програму для виконання.

Команда PROJECT/RUN (F9)

Команда компілює модулі, що були змінені, будує програму і запускає програму на виконання.

Команда PROJECT/DEBUG (Ctrl+Shift+F9)

Автоматично створюється вікно проекту і запускається програма DEBUG. У вікні проекту можна обрати модуль налагодження якого відбувається. У налагоджувану можна відкрити декілька вікон для перегляду результатів прогону. Повернутися у середовище VDE можна за опцією File/Exit (Alt-x).

Команда PROJECT/ PROJECT TREE (Ctrl+T)

Після компіляції проекту командою можна подивитися дерево проекту. Щоб одержати текст модуля у вікні достатньо натиснути двічі лівою кнопкою миші на файлі.

Додаток Д

ОБ’ЄКТНО-ОРІЄНТОВАНЕ ПРОГРАМУВАНННЯ ЗАСОБАМИ МОВИ VISUAL PROLOG

Д.1 Класи та об’єкти

Поняття об’єкту являє собою розвиток поняття складного даного в програмі. Об’єкт об’єднує дане і методи, що виконують операції на цим даним.

В об’єктно-орієнтованому програмуванні для типу об’єктів застосовують поняття домену. Тобто, під типом об’єкту розуміють область(домен) до якої він належить.

Опис спільних властивостей та методів всіх об’єктів домену у програмі називають класом.

В програмі назва класу вважається назвою домену.

Опис класу має секцію інтерфейсу і секцію реалізації.

Інтерфейс класу

Інтерфейс класу обмежується ключовими словами Class і endclass.

У інтерфейсі класу визначають глобальні домени, глобальні предикати для процедур та фактів.

Визначені домени та предикати застосовуються для опису глобальних тверджень, за допомогою яких записуються глобальні процедури(методи об’єктів, що породжуються цим класом).

По замовчанню доступ до глобальних процедур, фактів і до об’єктів, які визначаються глобальними доменами вільний для всього проекту(Public).

Глобальні предикати в секції Facts застосовують для запису динамічних фактів, доступних об’єктам інших класів.

У інтерфейсі класу можна розташувати декілька глобальних секцій Domains, Predicates, Facts.

Секція реалізації

Секція реалізації класу обмежується ключовими словами Implement і endclass. Термін імплемент означає реалізувати.

У секції класу Implement можна розташувати декілька локальних секцій Domains, Predicates, Facts і одну секцію Clauses.

У об’єктно-орієнтованій програмі не можна застосовувати неіменовані секції Facts.

В секції Clauses розташовані глобальні та локальні процедури, статичні і динамічні факти необхідні для роботи об’єктів класу. Область їх видимості визначається секціями інтерфейсу і реалізації.

Створення та вилучення об’єктів класу

Кожен клас може породжувати у програмі будь-яку кількість об’єктів, подібно тому, як будь-яка кількість даних може належать одному типу даних. Кількість об’єктів залежить від завдання.

Для породження об’єктів у кожному класі існує стандартний метод new(), що створює об’єкт цього класу. Такий метод називають конструктором об’єкту.

Виклик конструктора new() записується: ім’я_класу:: new().

Після створення об’єкту конструктор повертає посилку на об’єкт, щоб звертатися до нього. Щоб застосовувати посилку, при створенні об’єкту її треба привласнити змінній.

Наприклад:

R= ім’я_класу:: new()

Кожен клас має також стандартний метод delete(), який вилучає створений класом об’єкт. Такий метод називають деструктором об’єкту. Деструктор звільнює динамічно виділену оперативну пам'ять під об’єкт.

Виклик деструктора записується: ім’я_класу:delete()

Реалізація програми об’єктно-орієнтованим методом

Розглянемо приклад програми, що містить один клас, який породжує один об’єкт.

Завдання: Одержати відомості про результати сесії студентів однієї групи і вивести їх на екран.

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

Class група

predicates

nondeterm do()

endclass група

Implement група

facts-st

nondeterm stud(string,integer)

clauses

stud("Петренко",76).

stud("Сидоров",75).

do():-stud(П, Бал),write("Прізвище ", П,"\n","Середній бал ", Бал),nl,fail.

do().

endclass група

goal

R1= група::new,R1:do().

Вивід: Прізвище Петренко

Середній бал 76

Прізвище Сидоров

Середній бал 75

У програмі клас «група» створює один об’єкт, бо завдання вимагає роботу з однією групою. Об’єкт класу створюється у цілі програми. Посилка на об’єкт розміщується у змінній R1. Змінна застосовується при виклику методу do() з цілі.

Властивості об’єкту описуються фактами про студентів групи. Кожен факт пов’язує прізвище студента з його середнім балом.

Поведінка об’єкту показує, які дії може виконати об’єкт над своїми фактами. Поведінка об’єкту визначається його методом do(). Метод do() виводить вміст фактів на екран.

При виводу вмісту певного факту змінюється стан об’єкту, який характеризується значеннями змінних об’єкту П і Бал.

Треба розуміти, що факти, що подані у секції реалізації класу, будуть присутні у кожному об’єкту класу при його створенні.

Щоб факти у різних групах відрізнялися, треба вводити у кожний об’єкт свої факти про студентів.

Розглянемо це докладніше в програмі.

Завдання. Ввести дані про результати сесії групи 420, 421. Вивести результати на екран.

Створимо два об’єкту одного класу.

class група

Predicates

nondeterm do()

nondeterm do1()

endclass група

implement група

facts-st

nondeterm stud(string,integer)

nondeterm studforma(string,string)

clauses

studforma(“Прізвище ”, “Середній бал”).

do():-studforma(Т1,Т2),nl,write(Т1,Т2),nl,stud(П,Бал), write(П," ",Бал), nl, fail.

do().

Do1():-write("Прізвище? "), readln(П), write("Середній бал? "), readint(Бал), assert(stud(П, Бал)).

endclass група

goal

R1=група::new,R1:do1(),R2=група::new,R2:do1(),R1:do,R2:do, R1:delete, R2:delete.

Вивід:

Прізвище? Петренко

Середній бал? 78

Прізвище? Коваленко

Середній бал? 76

Прізвище Середній бал

Петренко 78

Прізвище Середній бал

Коваленко 76

В клас «група» додано новий метод do1(), який поповнює факти про студентів груп.

З прикладу видно, що об’єкт з посилкою у змінній R2 відрізняється від об’єкту з посилкою у змінній R1. У кожному об’єкту факти індивідуальні.

В той же час факт studforma постійно присутній у кожному об’єкту.

Індивідуальні властивості відрізняють об’єкт від інших об’єктів цього класу. Змінні об’єкту вказують на індивідуальні властивості об’єкту.