Лабораторна №4

Лабораторна робота №4.

Предикати. Частина 2.

Мета роботи: Отримати уявлення про предикатів Visual Prolog.

Завдання: Реалізувати новий варіант програми з малювання карти.

4.1. Отримайте початкові відомості про логічні зв'язки Visual Prolog.

4.2. Отримайте інформацію про імплікацію Visual Prolog.

4.3. Визначення пропозиції Хорну.

4.4. Оголошення типів та шаблону потоку.

4.5. Оголошення режимів детермінізму

4.6. Предикати малювання

4.7. GDI об'єкт.Створіть новий проектdrawMap.

4.1. Логічні зв'язки.

Якщо P1 і P2 предикати, P1ІP2 дорівнюєtrueякщо P1 і P2 рівніtrue. Послідовність предикатів, пов'язаних логічнимиІназивається кон'юнкцією. У Пролозі предикати кон'юнкції поділяються комами:

Імплікація цезв'язка,зображувана символом:-, який означаєякщо. Таким чином,

drawThem(Win):- connections(Win), drawCities(Win).

означає, що виdrawThemнаWin, якщо ви намалюєтеconnectionsнаWinіdrawCitiesнаWin.

4.3. Пропозиції Хорна.

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

city ("Salt Lake", pnt (30, 40)).

city ("Yellowstone", pnt (200, 100)).

Однопредикатні пропозиції Хорна називаються фактами. У цьому прикладі факти встановлюють відношення між містом та його координатами. Доменом цих предикатівє набір пар, що складаються з назви міста та його координат. Пропозиція Хорна може також мати вигляд

де Ti та H – предикати. Так,

є прикладом пропозиції Хорну. У реченні Хорна частина, розташована до знака:-, називаєтьсяhead– голова (заголовок). Частина, розташована після знака:-називаєтьсяtail- хвіст. У прикладі головою єdrawThem(Win), а хвостом -connections(Win), drawCities(Win).

Набір речень Хорна з однаковим заголовком визначає предикат. Наприклад, чотири пропозиції Хорна про міста визначають предикатcity/2, та

drawThem(Win) :- connections(Win), drawCities(Win).

drawThem : (windowHandle) procedure (i).

Оголошення типу свідчить, що аргументWinпредикатуdrawThem(Win)має типwindowHandle. Оголошення режиму стверджує, що аргументdrawThem/1може бути вхідним, тобто, він є константою, не вільної перемінної. У цьому випадку предикат приймає дані через свій аргумент.

Якщо предикат передбачається використовувати лише всередині його класу, він оголошується якclasspredicate– предикат класу. Приклади:

Однопредикатні пропозиції Хорна можуть бути оголошені як факти. Наприклад:

city: (string Name, pnt Position).

Аргументиconn/2- пара значень типуpnt. Типpntвизначений у класіvpiDomains. Щоб використовувати його у класіdraw, є дві можливості. Можна явно назвати клас, якого належитьpnt:

conn: (vpiDomains::pnt, vpi::Domains::pnt).

чи інакше, можна відкрити цей клас усередині класуdraw.

open core, vpiDomains, vpi

4.5. Оголошення режимів детермінізму

Щоб оголосити, чи має предикат одне рішення або кілька, використовуються такі ключові слова:

determпредикат може завершитися невдало (fail), або успішно (succeed), з одним рішенням.

Цей вид предикатів завжди завершується успішно і має одне рішення. Предикатиconnections/1таdrawCities/1, визначені в Лист. 3, процедури, і можуть бути оголошені так:

connections:(windowHandle) procedure (i).

Дравеннауки:(windowHandle) procedure (i).

multiпредикат не може завершитися невдало і має безліч рішень.

city:(string Name, pnt Position) nondeterm.

conn:(pnt, pnt) nondeterm.

Якщо предикату є безліч рішень, і одне з його рішень не задовольняє предикату в кон'юнкції, Пролог робитьbacktrack- відкат, і пропонує інше рішення в спробі задовольнити кон'юнкції. Погляньте на пропозицію Хорна:

drawLine(Win, P1, P2), fail.

nondetermфактconn(P1, P2)надає дві точки, які використовуються процедуроюdrawLine(Win, P1, P2)для малювання прямої лінії. Потім Пролог намагається задовольнити предикатуfail, який завжди закінчується невдало, відповідаючи своїй назві. Отже, Пролог робить відкат і пробує інше рішення, доки він не вичерпає всі можливості, і не

спробує друге реченняconnection/1, яке завжди успішно.

4.6. Предикати малювання

Вони вимагають дескриптор (handle1)вікна, яке підтримуватиме малюнки та креслення. Ось як ви можете отримати дескриптор:

onPaint(S, _Rectangle, _GDIObject) :-

W= S:getVPIWindow(), draw::drawThem(W).

Усередині класуdrawпередаватиметься дескрипторW. Наприклад, у реченні

drawThem(Win) :- connections(Win), drawCities(Win).

він передається вconnections/1, де він є першим аргументомdrawLine/3:

connections(Win) :- conn(P1, P2), drawLine(Win, P1, P2), fail.

ПредикатdrawLine(Win, P1, P1)креслить лінію зP1уP2на вікніWin. Як ви знаєте,P1іP2- точки, якpnt(10, 20).Інший предикат, з яким ви знайомі, це

drawEllipse(W, rct(X1, Y1, X2, Y2))

який креслить еліпс на вікніW. Еліпс вписаний у прямокутникrxt(X1, Y1, X2, Y2), де

X1, Y1- координати верхнього лівого кута, іX2, Y2- координати нижнього правого кута.

Вивчимо можливість використання методів так званогоGDI об'єкта. Наступний приклад показує, як це працює.

Project Settings. Створіть проект:drawMapObj

Створіть пакет:plotter.

Створіть форму всерединіplotter:map.

Project Tree/TaskMenu.mnu. УвімкнітьFile/New.

Build/ Buildвідкомпілюйте програму,

Project Tree/TaskWindow.win/Code Expert. Додати

Створіть клас. Створіть класdrawусередині пакетаplotter. Не забудьте вимкнути “Create objects”.

Ви знайдете нову версію класуdrawна лист.1, 2.

onPaint(_S, _Rectangle, GDIObject) :-