Sunteți pe pagina 1din 16

IA

Laborator 2


Scopul: Insusirea ideilor fundamentale de programare in Prolog, structura unui program Prolog,
tipuri de date, exemple

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:
S
1
S
2
... S
n
S
care are, in logica cu predicate de ordinul intai semnificatia declarativa conform careia
S
1
S
2
... S
n
implica S, adica daca S
1
si S
2
... si S
n
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 S
1
si S
2
... si S
n

si poate fi executata ca o procedura a unui limbaj de programare recursiv, unde S este antetul
procedurii si S
1
, S
2
, ... S
n
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 S
1

si S
2
... si S
n
.

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, 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 Prolog, care este considerat succesorul Turbo Prolog-ului
si PDC Prolog. Prolog este un mediu de programare complet, bazat pe limbajul de programare
Prolog. Prolog contine tot ce este necesar pentru implementarea aplicatiilor: mediu grafic de
dezvoltare, compilator, link-editor si depanator. 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.).

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 obiect


2. 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.

2.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.

2.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.

2.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 Prolog considera aceasta variabila ca fiind o variabila anonima.

Nota: Compilatorul 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.


2.4 Reguli

O regula Prolog exprima un fapt care depinde de alte fapte si este de forma:
S :- S
1
, S
2
, S
n
.

Fiecare S
i
, 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 S
1
, S
2
, S
n
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.

3. Structura programelor 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 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. 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.

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. 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 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, 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 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 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.

4. Tipuri de date
Programele 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:

1.Tipul elementar:

A.Standard
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 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 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


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 "_".


5. Exemple

5.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


5.2 Exemple de reguli

In continuare sunt prezentate o serie de reguli, precum si implementarea lor in 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".

6. Exercitii

1. Se va urmari programul de mai jos, in care s-a declarat o baza de cunosatinte pentru o firma
care se ocupa cu vnzarea masinilor.

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?

2. Se da urmatoarea baza de cunostinte:

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

mama(Persoana, Copil) :-
parinte(Persoana, Copil),
fem(Persoana).
bunica(Bunica, Nepot) :-
parinte(Persoana, Nepot),
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)


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

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


4. Se considera fisierul de mai jos:

tata(X) :- tata(X, _).
tata(alex).
tata(ion, vasile).
tata(george, ana).


Rulati programul cu scopul tata(X) si explicati rezultatul rularii (intr-un fisier Notepad).

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