0% au considerat acest document util (0 voturi)
5 vizualizări20 pagini

Lab 2

Încărcat de

iurie taralunga
Drepturi de autor
© All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd
0% au considerat acest document util (0 voturi)
5 vizualizări20 pagini

Lab 2

Încărcat de

iurie taralunga
Drepturi de autor
© All Rights Reserved
Respectăm cu strictețe drepturile privind conținutul. Dacă suspectați că acesta este conținutul dumneavoastră, reclamați-l aici.
Formate disponibile
Descărcați ca PDF, TXT sau citiți online pe Scribd

IA

Laborator 2

Scopul: Insusirea ideilor fundamentale de programare in Prolog, instalare Visual Prolog 7.2
Personal Edition, utilizare PIE

PARTEA 1: SUPORT LABORATOR

1. Introducere

Inceputul programarii logice poate fi atribuit lui R. Kowalski si A. Colmerauer si se situeaza la


inceputul anilor '70. Kowalski a plecat de la o formula logica de tipul:
S1 ∧ S2 ∧ ... Sn → S
care are, in logica cu predicate de ordinul intai semnificatia declarativa conform careia
S1 ∧ S2 ∧ ... Sn implica S, adica daca S1 si S2 ... si Sn sunt fiecare adevarate atunci si S este
adevarat, si a propus o interpretare procedurala asociata. Conform acestei interpretari, formula de
mai sus poate fi scrisa sub forma:
S daca S1 si S2 ... si Sn
si poate fi executata ca o procedura a unui limbaj de programare recursiv, unde S este antetul
procedurii si S1, S2, ... Sn corpul acesteia. Deci, pe langa interpretarea declarativa, logica, a unei
astfel de formule, formula poate fi interpretata procedural astfel: pentru a executa S se executa S1
si S2 ... si Sn.

In aceeasi perioada, A. Colmerauer si colectivul lui de cercetare de la Universitatea din Marsilia


au dezvoltat un limbaj de implementare a acestei abordari, pe care l-au denumit Prolog, abreviere
de la "Programmation et Logique". De atunci si pana in prezent, limbajul Prolog s-a impus ca
cel mai important limbaj de programare logica si s-au dezvoltat numeroase implementari, atat ale
unor interpretoare, cat si ale unor compilatoare ale limbajului. Limbajul Prolog a fost dezvoltat
ca un instrument pentru programarea si rezolvarea de probleme care implicau reprezentari
simbolice de obiecte si relatii intre obiecte, fiind considerat un limbaj cu fundament matematic
solid.

Limbajul Prolog este un limbaj declarativ sustinut de o componenta procedurala. Spre deosebire
de limbajele procedurale, cum ar fi C sau Pascal, in care rezolvarea problemei este specificata
printr-o serie de pasi de executie sau actiuni, intr-un limbaj declarativ problema este specificata
prin descrierea universului problemei si a relatiilor sau functiilor existente intre obiecte din acest
univers. Exemple de astfel de limbaje sunt cele functionale, de exemplu Lisp, Scheme, ML, si
cele logice, de exemplu Prolog. Solutia problemei nu mai reprezinta o executie pas cu pas a unei
secvente de instructiuni. Modul de executie a programului depinde in primul rand de definitiile
relatiilor, de modul de inferenta si de controlul explicit realizat interactiv de catre programator.
Desi initial a fost gandit pentru un set restrans de probleme, Prolog a devenit cu timpul un limbaj
de uz general, fiind o unealta importanta in aplicatiile de inteligenta artificiala. Pentru multe
probleme, un program Prolog are cam de 10 ori mai putine linii decat echivalentul lui in Pascal.

In 1983, cercetatorii din Japonia au publicat un plan ambitios de creare a unor calculatoare de
generatia a 5-a pentru care Prolog era limbajul de asamblare. Planul nu a reusit, dar acest proiect
a marcat o dezvoltare deosebita a interpretoarelor si compilatoarelor de Prolog, precum si o
crestere mare a numarului de programatori in acest limbaj.

Multe clase de probleme pot fi rezolvate in Prolog, existand anumite categorii care sunt
rezolvabile mult mai usor in Prolog decat in orice alt limbaj procedural. Astfel de probleme sunt
in principal cele dedicate prelucrarii simbolice sau care necesita un proces de cautare a solutiei
intr-un spatiu posibil de transformari ale problemei. De asemenea, limbajul Prolog are
aplicabilitate in gestiunea bazelor de date relationale, inteligenta artificiala, logica matematica,
demonstrarea teoremelor, sistemele expert, ingineria arhitecturala etc.

Exemple de medii de programare ce utilizeaza limbajul Prolog (care ruleaza pe


microcalculatoare de tip IBM/PC, fie sub sistemul de operare DOS, fie sub sistemul Windows)
sunt: Turbo Prolog (produs al firmei Borland), ARITY Prolog, Visual Prolog, Amzi Prolog,
SWI-Prolog etc. Trebuie amintit si faptul ca exista si variante de sisteme Prolog sub Unix, de
exemplu, GNU Prolog, SWI-Prolog sau sub X Windows.

In cadrul acestui laborator se va studia Visual Prolog, care este considerat succesorul Turbo
Prolog-ului si PDC Prolog. Visual Prolog este un mediu de programare complet, bazat pe
limbajul de programare Prolog. Visual Prolog contine tot ce este necesar pentru implementarea
aplicatiilor: mediu grafic de dezvoltare, compilator, link-editor si depanator. Visual Prolog
include o biblioteca ce ofera acces la API, punand la dispozitia programatorului instrumente
pentru: interfata utilizator grafica, baze de date ODBC/OCI, precum si Internet (socket, ftp, http,
cgi etc.).

Visual Prolog este recomandat pentru implementarea sistemelor expert, planificare, precum si
altor probleme de inteligenta artificiala.

O caracteristica generala a programelor ce utilizeaza Prolog-ul este aceea ca programatorul


specifica fapte si relatii despre obiecte, iar sistemul Prolog gaseste (prin inferenta) noi relatii
despre obiecte.

2. Instalarea Visual Prolog

Visual Prolog a ajuns in acest moment la versiunea 7.2, disponibila pentru Windows
Vista/XP/2000. Visual Prolog 7.2 Personal Edition poate fi downloadata gratuit de la:
[Link] Pentru instalare este suficient sa parcurgeti
wizardul de instalare.
3. Prezentarea mediului de programare Visual Prolog

Pentru lansare, mergeti in meniul Start -> All Programs Visual Prolog 7.2 Personal Edition ->
Visual Prolog. La lansare pe ecran este afisata o fereastra al carei meniu principal (meniul bara)
consta din submeniurile:
File
Edit
View
Insert
Project
Build
Debug
Go to
Tools
Web
Window
Help

Meniurile sunt de tip drop-down, in continuare fiind prezentate pe scurt meniurile si o serie de
optiuni utilizate frecvent:
 File – ofera optiunile pentru gestiunea fisierelor, astfel:
o New in New Package – permite crearea unui nou fisier intr-un pachet nou;
o New in Existing Package (CTRL + ALT + N) - permite crearea unui nou fisier
intr-un pachet existent
o Open (F8) – permite incarcarea unui fisier existent;
o Close – inchide fisierul curent;
o Save (F2) – permite salvarea fisierului curent;
o Save As… – permite salvarea fisierului curent sub alt nume (deci, practic,
modificarea numelui unui fisier);
o Print – permite listarea la imprimanta;
o Exit (Alt + F4) – iesirea totala in sistemul de operare (inchidere VP).

 Project
• New (Ctrl + Shift + N) – permite crearea unui proiect nou;
• Open (Ctrl + Shift + N) – permite incarcarea/crearea unui proiect;
• Close – permite inchiderea unui proiect;
• Save (Ctrl+S) – permite salvarea unui proiect;

 Build
• Compile (Ctrl+F7) – utilizat pentru compilarea unui modul;
• Build (Ctrl + Shift + B) – folosit pentru compilarea si link-editarea unui proiect;
• Rebuild All (Ctlr + Alt + Shift + B) – permite compilarea si link-editarea tuturor
fisierelor din cadrul unui proiect, chiar daca s-au operat sau nu modificari de la
ultima compilare (spre deosebire de comanda Build, care realizeaza o verificare a
timpului fisierului si recompileaza doar fisierele care au fost modificate de la
ultima compilare);
• Execute (Ctrl + F5) – pentru compilarea, link-editarea unui proiect in vederea
obtinerii executabilului, si lansarea in executie a respectivului proiect;

In orice moment se poate apela Help-ul, apasand tasta functionala F1.

4. Entitatile limbajului Prolog

Limbajul Prolog este un limbaj logic, descriptiv, care permite specificarea problemei de rezolvat
in termenii unor fapte cunoscute despre obiectele universului problemei si a relatiilor existente
intre aceste obiecte. Executia unui program Prolog consta in deducerea implicatiilor acestor fapte
si relatii, programul definind astfel o multime de consecinte ce reprezinta intelesul sau
semnificatia declarativa a programului.

Un program Prolog contine urmatoarele entitati:


- fapte despre obiecte si relatiile existente intre aceste obiecte;
- reguli despre obiecte si relatiile dintre ele, care permit deducerea (inferarea) de noi fapte
pe baza celor cunoscute;
- intrebari (interogari), numite si scopuri, despre obiecte si relatiile dintre ele, la care
programul raspunde pe baza faptelor si regulilor existente.

4.1 Fapte

Faptele sunt predicate de ordinul intai de aritate n considerate adevarate. Ele stabilesc relatii intre
obiectele universului problemei. Numarul de argumente ale faptelor este dat de aritatea (numarul
de argumente) corespunzatoare a predicatelor.

Interpretarea particulara a predicatului si a argumentelor acestuia depinde de programator.


Ordinea argumentelor, odata fixata, este importanta si trebuie pastrata la orice alta utilizare a
faptului, cu aceeasi semnificatie. Multimea faptelor unui program Prolog formeaza baza de
cunostinte Prolog. Se va vedea mai tarziu ca in baza de cunostinte a unui program Prolog sunt
incluse si regulile Prolog.

4.2 Scopuri

Obtinerea consecintelor sau a rezultatului unui program Prolog se face prin fixarea unor scopuri
care pot fi adevarate sau false, in functie de continutul bazei de cunostinte Prolog. Scopurile sunt
predicate pentru care se doreste aflarea valorii de adevar in contextul faptelor existente in baza
de cunostinte. Cum scopurile pot fi vazute ca intrebari, rezultatul unui program Prolog este
raspunsul la o intrebare (sau la o conjunctie de intrebari). Acest raspuns poate fi afirmativ, yes,
sau negativ, no. Se va vedea mai tarziu ca programul Prolog, in cazul unui raspuns afirmativ la o
intrebare, poate furniza si alte informatii din baza de cunostinte.
4.3 Variabile

In Prolog, argumentele faptelor si intrebarilor pot fi obiecte particulare, numite si constante sau
atomi simbolici. Predicatele Prolog, ca orice predicate in logica cu predicate de ordinul I, admit
ca argumente si obiecte generice numite variabile. In Prolog, prin conventie, numele
argumentelor variabile incepe cu litera mare (sau cu liniuta de subliniere), iar numele
constantelor simbolice incepe cu litera mica. O variabila poate fi instantiata (legata) daca exista
un obiect asociat acestei variabile, sau neinstantiata (libera) daca nu se stie inca ce obiect va
desemna variabila.

Variabilele Prolog sunt locale, nu globale, astfel incat daca doua clauze contin fiecare cate o
variabila numita X, atunci vor exista, de fapt, doua variabile distincte X.

La fixarea unui scop Prolog care contine variabile, acestea sunt neinstantiate, iar sistemul
incearca satisfacerea acestui scop cautand printre faptele din baza de cunostinte un fapt care
poate identifica cu scopul, printr-o instantiere adecvata a variabilelor din scopul dat. Este vorba
de fapt de un proces de unificare a predicatului scop cu unul din predicatele fapte existente in
baza de cunostinte.

La incercarea de satisfacere a scopului, cautarea se face intotdeauna pornind de la inceputul


bazei de cunostinte. Daca se intalneste un fapt cu un simbol predicativ identic cu cel al scopului,
variabilele din scop se instantiaza conform algoritmului de unificare si valorile variabilelor astfel
obtinute sunt afisate ca raspuns la satisfacerea acestui scop.

In cazul in care exista mai multe fapte in baza de cunostinte care unifica cu intrebarea pusa exista
mai multe raspunsuri la intrebare, corespunzand mai multor solutii ale scopului fixat. Prima
solutie este data de prima unificare si exista atatea solutii cate unificari diferite exista. La
realizarea primei unificari se marcheaza faptul care a unificat si care reprezinta prima solutie. La
obtinerea urmatoarei solutii, cautarea este reluata de la marcaj in jos in baza de cunostinte.
Obtinerea primei solutii este de obicei numita satisfacerea scopului iar obtinerea altor solutii,
resatisfacerea scopului. La satisfacera unui scop cautarea se face intotdeauna de la inceputul
bazei de cunostinte. La resatisfacerea unui scop, cautarea se face incepand de la marcajul stabilit
de satisfacerea anterioara a acelui scop.

Sistemul Prolog, fiind un sistem interactiv, permite utilizatorului obtinerea fie a primului
raspuns, fie a tuturor raspunsurilor. in cazul in care, dupa afisarea tuturor raspunsurilor, un scop
nu mai poate fi resatisfacut, sistemul raspunde no.

Daca o variabila apare doar o data intr-o clauza si numele incepe cu liniuta de subliniere, atunci
compilatorul Visual Prolog considera aceasta variabila ca fiind o variabila anonima.

Nota: Compilatorul Visual Prolog nu face distinctie intre literele mici si mari care apar in nume,
cu exceptia primei litere. Deci, urmatoarele doua nume pot fi folosite pentru a accesa aceeasi
variabila: SourceCode si SOURCECODE.
4.4 Reguli

O regula Prolog exprima un fapt care depinde de alte fapte si este de forma:
S :- S1, S2, …Sn.

Fiecare Si, i = 1,n si S au forma faptelor Prolog, deci sunt predicate, cu argumente constante,
variabile sau structuri. Asa dupa cum s-a precizat, faptul S care defineste regula, se numeste
antet de regula, iar S1, S2, …Sn formeaza corpul regulii si reprezinta conjunctia de scopuri care
trebuie satisfacute pentru ca antetul regulii sa fie satisfacut.

:- = if
, = and
; = or

In conditiile existentei regulilor in baza de cunostinte Prolog, satisfacerea unui scop se face
printr-un procedeu similar cu cel prezentat in sectiunea 4.2, dar unificarea scopului se incearca
atat cu fapte din baza de cunostinte, cat si cu antetul regulilor din baza. La unificarea unui scop
cu antetul unei reguli, pentru a putea satisface acest scop trebuie satisfacuta regula. Aceasta
revine la a satisface toate faptele din corpul regulii, deci conjunctia de scopuri. Scopurile din
corpul regulii devin subscopuri a caror satisfacere se va incerca printr-un mecanism similar cu
cel al satisfacerii scopului initial.

4. Structura programelor Visual Prolog

Un program Prolog contine urmatoarele sectiuni:


- domains;
- predicates;
- goal;
- clauses;
- constants;
- databases.

Nu toate sectiunile sunt obligatorii (domains, goal).

Clauses contine fapte si reguli (care au fost prezentate mai sus), sau mai precis in aceasta
sectiune se definesc predicatele. Argumentele unei clauze sunt in ordine bine definita, fiecare
argument avand un anume tip. Sectiunea CLAUSES trebuie sa inceapa cu cuvantul cheie
CLAUSES. Asa cum s-a specificat, atat faptele, cat si regulile trebuie sa se termine cu punct (.).

De exemplu, afirmatia "Popescu lucreaza la biroul aprovizionare" poate fi exprimata in Prolog


astfel:
lucreaza('Popescu', biroul_aprovizionare)

Modul de formulare al clauzei sau mai precis, ordinea argumentelor este in totalitate la
latitudinea programatorului. Astfel, afirmatia anterioara poate fi exprimata si astfel:
lucreaza(biroul_aprovizionare, 'Popescu')

Oricare dintre aceste doua variante este corecta pentru Visual Prolog, singurul criteriu de selectie
fiind doar perceptia utilizatorului. O forma odata folosita trebuie respectata cu consecventa in
intregul program.
In clauza urmatoare, primul argument este o variabila:
lucreaza(Persoana, biroul_aprovizionare)

Predicates este acea sectiune care contine fiecare predicat ce apare citat in clauze si precizeaza
tipul argumentelor. Se spune ca reprezinta descrierea "ideala" a clauzelor.

Deci predicates este un fel de catalog al tuturor predicatelor utilizate, care arata ce nume au
aceste predicate, fiecare predicat ce argumente are: cate, in ce ordine, de ce tip (ca un fel de
sectiune a declaratiilor de functii in C). Fiecare predicat apelat in clauze trebuie sa respecte
numele si argumentele unui predicat descris in predicates. Daca nu respecta tipul si ordinea
argumentelor, se obtin erori. Totusi, se admite ca doua nume de predicat identice sa aiba un
numar diferit de argumente. In acest caz, se recomanda ca cele doua declaratii sa fie una dupa
alta, atat in predicates, cat si in clauses. Se spune ca un predicat are aritate (numarul de
argumente) multipla. Visual Prolog va accepta aritatea multipla, in interior va considera totusi ca
e vorba de predicate diferite, cu nume identic.

Numele predicatului este un sir de caractere care poate contine litere, cifre si semnul "_", dar
care incepe obligatoriu cu o litera (preferabil, litera mica). Daca un nume de predicat este
compus din mai multe cuvinte, acestea se pot lega intre ele folosind semnul "_". Lungimea
maxima a numelui de predicat este de 250 caractere.

In urmatorul exemplu, primul argument este o variabila anonima:


lucreaza(_, biroul_aprovizionare)

In concluzie, predicatele trebuie declarate in sectiunea de predicate, definite in sectiunea de


clauze, iar la apel, in functie de numarul si tipul argumentelor se va alege definitia
corespunzatoare.

In sectiunea domains se poate realiza redenumirea unor domenii standard pentru a le da o


semantica mai precisa, precum si declararea unor noi structuri de date.

Sectiunile domains si predicates pot fi declarate globale, astfel:


global domains
global predicates

Odata scrise definitiile, ele pot fi incluse in unul sau mai multe programe cu:
include nume_fis
O alta sectiune este databases, care reprezinta o sectiune speciala pentru declararea unor fapte
care se doresc a fi o parte a unei baze de date dinamice. Astfel, uneori este necesara actualizarea
faptelor din program (modificare, stergere, adaugare) in timpul rularii programului. Intr-un astfel
de caz, faptele constituie o baza de date dinamica sau interna. Visual Prolog pune la dispozitie
mai multe predicate pentru gestiunea bazelor de date (assertz, asserta etc.). Aceasta sectiune
poate fi declarata global.

Sectiunea goal trebuie sa apara in program - in acest caz fiind vorba despre varianta compilator,
la rulare programul executa acest goal, cauta prima solutie si nu afiseaza variabilele interne de
lucru (goal declarat). Cand apare in program, in general, sectiunea goal este dupa sectiunile
predicates si clauses. Un program Visual Prolog poate contine doar o singura sectiune goal.
Sectiunea goal contine o clauza sau un sir de clauze conectate logic (cu and si/sau or): goal
complex (compus din mai multe subgoal-uri legate logic). Acest goal poate fi un predicat cu sau
fara argumente, iar argumentele, daca apar, pot fi variabile (variabile anonime sau nu) sau
obiecte. Acest goal se termina cu punct.

Dandu-se fapte, reguli si unul sau mai multe goal-uri, pentru fiecare goal, Visual Prolog executa
urmatoarele operatii:
• il cauta printre fapte;
• daca nu-l gaseste ca fapt, cauta pentru el regula de deductie si verifica conditiile
regulii, considerand pe rand variantele (daca exista);
• fiecare conditie devine un subgoal.

Scopul este demonstrat daca toate subscopurile sunt demonstrate. Cand un subobiectiv esueaza,
Prolog se intoarce la subobiectivele anterioare si continua cu alte valori ale variabilelor. Aceasta
tehnica este denumita „backtracking”.
Sectiunea constants permite declararea unor constante (constante simbolice). Sectiunea poate sa
apara oriunde in program, cu conditia sa fie declarata constanta inainte de utilizarea ei. Constanta
e vizibila in toate clauzele, dar valoarea constantei nu se poate modifica in timpul executiei
programului. Forma generala:
constants
nume _constanta=valoare

In Visual Prolog sunt constante numele de obiecte (siruri de caractere) si numerele (intregi sau
reale). Nu conteaza daca ea este declarata cu litere mici sau mari, spre deosebire de toate
celelalte date din Visual Prolog. Astfel pi, Pi sau PI vor referi aceeasi constanta. Ca regula
generala se cere ca in sectiunea de constante, constantele sa fie declarate cu litera mare, dar in
sectiunea de clauze, acestea trebuie sa fie scrise cu litera mica, pentru a se distinge de variabile.
Valoare poate fi orice obiect, de orice tip definit.

Exemple:
constants
Titlu="SALARII LUNARE"
Expr=l+7*(47-12)
Pi=3.14
G=9,8
Computer=mcintosh

Pentru constante nu sunt permise definitii recursive, de exemplu x = 2 * x / 2.

Intr-un program pot fi mai multe sectiuni de declaratii pentru constante, dar constantele trebuie
sa fie declarate inainte de a fi utilizate. Constantele declarate au durata de viata incepand din
momentul declaratiei pana la sfarsitul fisierului sursa, precum si in orice fisier inclus dupa
declaratii.

5. Tipuri de date
Programele Visual Prolog contin obiecte si relatii dintre aceste obiecte. Obiectele sunt entitati
distincte ale lumii reale (obiecte reale – fizice) sau abstracte (obiecte abstracte). In Prolog,
obiectele sunt reprezentate prin nume simbolice. Regulile sintactice aplicate la formarea numelor
simbolice pentru obiecte permit definirea mai multor tipuri de obiecte:

[Link] elementar:

[Link]
A1. caracter - char: un caracter incadrat intre doua caractere apostrof;
A2. intreg - integer: intreg cuprins in intervalul [-32768, 32767];
A3. real - real: numar real, echivalent cu double din C si al carui modul este in intervalul [1e-

307, 1e308]

A4. sir - string: secventa de caractere, ce este implementata ca un pointer la un tablou

terminat prin zero, ca si in C. Pentru siruri sunt permise doua formate:

• secventa de litere, numere si liniuta de subliniere, in care primul caracter nu este


majuscula (de ex., numar_telefon);
• secventa de caractere incadrata intre ghilimele, maxim 250 caractere (de exemplu, „sir de
caractere”);

A5. simbol - symbol: analog ca la tipul string, cu diferenta ca primul caracter este litera mica
(in reprezentarea interna string-ul si simbolul gen string nu sunt identice; pentru simbol se
construieste un tabel, el este unic si regasit la fiecare citare - practic se lucreaza cu adresa lor,
deci se constata o mare rapiditate de acces; in cazul string-urilor, acestea sunt tratate caracter cu
caracter)

A6. fisier - file: nume simbolic de fisier


A7. selector de arbore binar - bt_selector: selectorul unui arbore este un numar natural, cu
valoarea minima 0, prin care se face referinta in program la arborele binar; baza externa de
cunostinte are atasat un arbore binar sau mai multi arbori, prin care se asigura cautarea in baza de
cunostinte

A8. domeniu - place: locul ocupat de un fisier

B. Definit de utilizator

Sunt tipuri de date complexe, cum poate fi lista:


- de tipuri elementare
- de tipuri compuse

In afara celor mentionate anterior, mai trebuie amintite si urmatoarele tipuri de date, pentru care
s-a notat in paranteza intervalul: short (intervalul +32768, 32767), ushort (valori in intervalul 0,
65535), long (intervalul –2147483648, 2147483647), ulong (0, 4294967295), unsigned (valori in
intervalul 0, 4294967295), byte (0, 255), sbyte (-128, 127), word (0, 65535), dword (0,
4294967295).

O valoare intreaga poate fi precedata de 0x sau 0o, indicand sintaxa hexazecimala, respectiv
octala. Trebuie specificat faptul ca in declaratiile domain, cuvintele cheie signed si unsigned pot
fi utilizate impreuna cu byte, word, si dword:
DOMAINS
i8 = signed byte

Un obiect sau o variabila care este de un tip, nu poate apare in locuri (pe pozitii) unde se cere alt
tip. Exceptie fac cateva tipuri standard pentru care exista conversie automata.
Conversiile automate admise sunt:

- intre string si symbol;


- intre integer, char si real (char e reprezentat ca un cod ASCII - deci numeric; analog, un
integer poate fi considerat un cod ASCII; orice intreg e un real).

Obs. importanta: Tipurile utilizator nu pot fi echivalate unul cu altul.

Din cele prezentate mai sus, rezulta o prima utilitate a declararii de tipuri, aceea de a declara
tipuri specifice, care pe de o parte fac ca programul sa fie mai lizibil, pe de alta parte definesc
clase peste datele utilizate. O alta utilitate este aceea de a defini - cum se va vedea mai tarziu -
tipuri complexe.

Se reaminteste faptul ca in Prolog numele obiectelor incep cu litera mica, putand fi urmata de
cifre, litere sau semnul "_".
6. PIE: Prolog Inference Engine

In continuare se vor verifica cateva exemple in PIE, unul din exemplele ce insotesc mediul
Visual Prolog. Inainte de a incepe trebuie instalat si construit exemplul PIE. Aceasta se va face in
felul urmator:

• Se selecteaza „Install Examples” din meniul de start Windows (Start -> Programs -
>Visual Prolog 7.0 -> Install Examples)
• Se deschide proiectul PIE in mediul de dezvoltare vizual (VDE) si se ruleaza programul.

Odata rulat, acesta va arata ca in figura de mai jos:

• Se deschide un nou fisier si se introduce textul din exemplu:


• In timp ce fereastra de editare este activa se alege Engine->Reconsult. Astfel,
mecanismul va incarca continutul fisierului iar in fereastra Dialog ar trebui sa apara un
mesaj de forma:

Reconsulted from: ...\pie\Exe\[Link]

Reconsult incarca tot ceea ce este in editor, fara a face o salvare a continutului fisierului. Pentru
salvare trebuie specificat explicit (File->Save).
File->Consult va incarca continutul de pe disc indiferent daca fisierul este deschis sau nu pentru
editare.

• Acum putem trece la rezolvarea scopurilor. Intr-o linie libera din fereastra Dialog se
introduce scopul (fara ?- in fata). Spre exemplu:

• Atunci cand cursor-ul este plasat la sfarsitul liniei, se va apasa Enter. PIE va considera
textul de la inceputul liniei pana la pozitia cursor-ului ca fiind scopul dorit. Rezultatul ar
trebui sa fie de forma:
7. Exemple

7.1. Exemplu – definirea unor relatii de familie

Faptul ca Tom este parinte al lui Bob se poate scrie in Prolog astfel:
parinte(tom, bob).

Aici parinte este numele relatiei, iar tom si bob sunt argumentele sale.

Program Prolog care defineste relatii de familie:


parinte(pam, bob).
parinte(tom, bob).
parinte(tom, liz).
parinte(bob, ann).
parinte(bob, pat).
parinte(pat, jim).

Programul consta din 6 clauze. Fiecare dintre aceste clauze declara un fapt despre relatia parinte.
Spre exemplu, parinte(tom, bob) este o instantiere particulara a relatiei parinte. In general, o
relatie se defineste ca fiind multimea tuturor instantierilor sale.

Nota! Acest program simplu nu contine (inca) regului (ci doar fapte).

Interogari Prolog

Vrem sa aflam daca Bob este parinte al lui Pat. Aceasta intrebare este comunicata
sistemului Prolog astfel:
parinte(bob, pat).

Raspunsul Prologului va fi
yes

Alte exemple de interogari:


parinte(liz, pat).
no
parinte (tom, ben).
no

• Cine este parintele lui Liz?


parinte(X, liz).
X = tom

• Cine sunt copiii lui Bob?


parinte (bob, X).
X = ann;
X= pat;

• Cine este parinte al cui?


parinte(X, Y).
X = pam
Y = bob;
X = tom
Y = bob;
X = tom
Y = liz;

• Cine este un bunic al lui Jim? adica
(1) Cine este parinte al lui Jim? Presupunem ca acesta este un Y.
(2) Cine este parinte al lui Y? Presupunem ca acesta este un X.
(1) si (2) necesita urmatoarea interogare compusa:

parinte(Y, jim), parinte(X, Y).

Raspunsul Prologului este:


X = bob
Y = pat

Nota! Interogarea

parinte(X, Y), parinte(Y, jim).

va produce acelasi rezultat.

• Cine sunt nepotii lui Tom?


parinte(tom, X), parinte (X, Y).
X = bob
Y = ann;
X = bob
Y = pat
• Ann si Pat au un parinte comun?
parinte(X, ann), parinte(X, pat).
X = bob

Vom extinde programul prin introducerea unor fapte noi. Introducem, mai intai, urmatoarele
fapte:

feminin(pam).
masculin(tom).
masculin(bob).
feminin(liz).
feminin(pat).
feminin(ann).
masculin(jim).
sex(pam, feminin).
sex(tom, masculin).
sex(bob, masculin).
urmas(liz, tom).

Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite
parinte.

Pentru toti X si toti Y, Y este urmas al lui X daca X este parinte al lui Y.

Aceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula:

urmas(Y, X) :- parinte(X, Y).

Interogarea Prologului cand baza de cunostinte contine si aceasta regula:

urmas(liz, tom).

Cum lucreaza Prolog acum?

Intrucat nu exista fapte referitoare la urmasi, trebuie folosita regula, astfel: variabilele X si Y vor
fi instantiate in felul urmator

X = tom si Y = liz

Dupa instantiere se obtine un caz particular al regulii generale. Acest caz


particular este:

urmas(liz, tom) :- parinte(tom, liz).


Corpul regulii reprezinta partea de conditie, iar antetul ei partea de concluzie. Prolog incearca sa
determine daca partea de conditie este adevarata i.e. daca parinte(tom, liz) este adevarat. In acest
moment, scopul initial, urmas(liz,tom), a fost inlocuit cu subscopul parinte(tom, liz). Noul scop
este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza de cunostinte). Aceasta
inseamna ca partea de concluzie este, de asemenea, adevarata, iar Prolog va raspunde la intrebare
cu yes.

Introducem acum relatii de familie suplimentare:

• relatia mama, definita astfel:


mama (X, Y) :- parinte (X,Y), feminin (X).

• relatia bunic, definita astfel:


bunic (X, Z) :- parinte (X, Y), parinte(Y, Z).

• relatia sora, definita astfel:


sora (X, Y) :-
parinte (Z, X),
parinte (Z, Y),
feminin (X).

Interogari Prolog:

• daca ann si pat sunt surori


sora (ann, pat).
yes

• cine este sora lui Pat


sora (X, pat).
X = ann;
X = pat

Nota! Relatia sora ar trebui sa fie definita dupa cum urmeaza:

sora (X, Y) :-
parinte (Z, X),
parinte (Z, Y),
feminin (X),
diferit (X, Y).

unde predicatul diferit (X,Y) trebuie definit astfel incat el sa fie satisfacut daca si numai daca X
e diferit de Y.

Reguli recursive

• relatia predecesor: un predecesor poate fi direct (parinte)


predecesor (X, Z) :- parinte (X, Z).

sau indirect
predecesor (X, Z) :-
parinte (X, Y),
parinte (Y, Z).
predecesor (X, Z):-
parinte (X, Y1),
parinte (Y1, Y2),
parinte(Y2, Z).

Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la orice adancime,
definitia ei trebuie gandita in felul urmator:

• Pentru toti X si Z, X este predecesor al lui Z daca Exista un Y astfel incat


(1) X este parinte al lui Y si
(2) Y este un predecesor al lui Z.

Clauza Prolog corespunzatoare (recursiva) este:


Predecesor (X,Z) :-
parinte (X,Y),
predecesor (Y,Z).

Definirea relatiei predecesor:


- consta din doua reguli, una care se refera la predecesori directi si cealalta la predecesori
indirecti. Definitia completa este urmatoarea:

predecesor (X, Z) :-
parinte (X,Z).
predecesor (X, Z) :-
parinte (X, Y),
predecesor (Y, Z).

Exemplu de interogare Prolog (care sunt succesorii lui Pam):


predecesor (pam, X).
X = bob;
X = ann;
X = pat;
X = jim

7.2 Exemple de reguli


In continuare sunt prezentate o serie de reguli, precum si implementarea lor in Visual Prolog:

1. "Daca o persoana (X) are sex masculin si este adult, atunci X este un barbat." - in acest
caz premisa este o clauza compusa, formata din doua clauze simple asociate prin
conectorul "si".

barbat(X):- sex_masculin(X), adult(X).

2. Notiunea de parinte poate fi definita astfel:

parinte(X, Y):- tata(X, Y); mama(X, Y)

Deoarece Prolog permite si utilizarea variabilelor anonime, notiunea de parinte poate fi


formulata astfel:
parinte(X, _):- tata(X, _); mama(X, _)
care are urmatoarea interpretare: "o persoana este parinte daca este fie tatal, fie mama cuiva".

PARTEA 2: EXERCITII

Nota: Cuvintul cheie nondeterm specifica faptul ca la un moment dat pot exista mai multe
instante ale unui fapt fact_N. Cuvintul cheie determ specifica faptul ca la un moment dat poate
exista o singura instanta a unui fapt fact_N.

Tema 1 : Se va urmari programul [Link], in care s-a declarat o baza de cunosatinte pentru o
firma care se ocupa cu vânzarea masinilor.

predicates
%marca, km, vechimea, culoarea
nondeterm masina(symbol,real,integer,symbol)
nondeterm camion(symbol,real,integer,symbol)

clauses
masina(chrysler, 130000, 3, rosu).
masina(ford, 90000, 4, argintiu).
masina(datsun, 8000, 1, rosu).
camion(ford, 80000, 6, verde).
camion(datsun, 50000, 5, roz).
camion(toyota, 25000, 2, negru).

Cerinte : Se va rula aplicatia si se vor determina urmatoarele:


• masina cu 130000 km si 3 ani vechime
• masinile rosii
• camioanele roz
• camioanele datsun roz
• este adevarat ca exista o masina ford argintie, cu 90000km, 4 ani
vechime?

Tema 2: Se va urmari programul [Link]:

predicates
nondeterm masc(symbol)
nondeterm fem(symbol)
nondeterm parinte(symbol, symbol) % primul este parintele pentru al doilea
nondeterm mama(symbol, symbol)
nondeterm bunica(symbol, symbol)

clauses
masc(vasile).
masc(alex).
fem(elena).
fem(ioana).
parinte(vasile, alex).
parinte(elena, alex).
parinte(alex, ioana).

mama(Persoana, Copil) if
parinte(Persoana, Copil) and
fem(Persoana).
bunica(Bunica, Nepot) if
parinte(Persoana, Nepot) and
mama(Bunica, Persoana).

O varianta a ultimei reguli este:


bunica(Bunica, Nepot):-
parinte(Persoana, Nepot),
parinte(Bunica, Persoana),
fem(Bunica).

Cerinte: Se va nota raspunsul primit in cazul urmatoarelor scopuri. Pentru fiecare scop,
explicati intr-un fisier Notepad modul de functionare.

• parinte(elena, alex)
• parinte(Parinte, alex)
• mama(Parinte, alex)
• bunica(Bunica, ioana)
• parinte(Tata, Copil), masc(Tata)

Tema 3: Adaugati noi fapte in program pentru a exprima urmatoarele:


• Parintii lui Vasile sunt Gheorghe si Maria.
• Parintii Ioanei sunt Alex si Sanda.

Tema 4: Se considera fisierul [Link]:

domains
pers = symbol
predicates
nondeterm tata(pers)
nondeterm tata(pers, pers)
clauses
tata(X) if
tata(X, _).
tata(alex).
tata(ion, vasile).
tata(george, ana).

Tema 5: Rulati programul [Link] cu scopurile de mai jos si explicati rezultatul rularii
(intr-un fisier Notepad).

tata(X).

Observatii
1. S-a declarat un predicat cu aritati diferite, cu urmatoarea semantica intuitiva:
- tata (pers) - inseamna ca pers este tata (al cuiva);
- tata(pers1, pers2) - inseamna ca pers1 este tatal lui pers2 (s-a notat pers1 si pers2
pentru a se putea face distinctia).
2. S-a redenumit domeniul standard symbol pentru a se sugera ca argumentele vor fi persoane.
3. Scopul intern tata(X) se va evalua folosind prima clauza.

S-ar putea să vă placă și