Tutorial Prolog
Tutorial Prolog
PROLOG
1. 2.
Click to edit Master text styles Click to edit Master text styles
Second level Second level
● Third level ● Third level
● Fourth level ● Fourth level
● Fifth level ● Fifth level
3 4
Click to edit Master text styles Click to edit Master text styles
Second level Second level
● Third level ● Third level
model, tot ceea ce nu este stiut de program, deci afirmat explicit ca fiind adevarat in program, este
considerat fals.
-- Prologul modeleaza negatia ca esec al satisfacerii unui scop (negatia ca insucces), aceasta fiind de
• Simbol…………………………..Sens
:- daca
, conjunctie
; disjunctie
_ variabila universala
(semnifica orice)
• O fapta Prolog este o clauza fara corp, adica de forma H. Ea reprezinta o clauza care este tot timpul
Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog:
-
-parinte(tom,bob).
Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale
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.
Obs. Acest program simplu nu contine (inca) reguli (ci doar fapte).
X=bob
Y=pat
?- urmas(liz, tom).
Cum lucreaza Prologul 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).
sora (X, Y) :-
parinte (Z, X),
parinte (Z, Y),
feminin (X).
• Interogarea Prologului:
Ø Obiecte particulare
Ø Relatii particulare
predicatelor)
Ø numere
exemplu, numele X15 intervine in doua clauze diferite, atunci el semnifica doua
variabile diferite.Fiecare ocurenta a lui X15 in interiorul aceleiasi clauze
semnifica insa o aceeasi variabila). Cuprins
BACK NEXT
• Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic,
care formeaza componentele structurii.
Ex: poseda(mihai, carte(prolog, clocksin, 1981))
Ø Sunt folosite la reprezentarea structurilor de date (liste, arbori)
ØDesi alcatuite din mai multe componente, sunt tratate de program ca obiecte
ØOperatori aritmetici:
Exemplu:
?- f(a, X) == f(a, Y).
no
- Operatorul =:= face numai evaluare aritmetica si nici o instantiere; semnificatia lui
X =:= Y este: valorile expresiilor aritmetice X si Y sunt egale.
Diferenta dintre operatorii = si =:=
?- 1+2 =:= 2+1. ?-1+2=2+1
yes no
BACK
- Inegalitatea a doua expresii aritmetice Cuprins
se stabileste cu operatorul NEXT
=\=
Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor
careurmeaza. Acesti operatori forteaza evaluarea argumentelor lor.
X > Y (X este mai mare ca Y)
X < Y (X este mai mic ca Y)
X >= Y (X mai mare sau egal decat Y)
X <= Y (X mai mic sau egal cu Y)
X =:= Y (valorile lui X si Y sunt egale)
X =\= Y (valorile lui X si Y nu sunt egale)
Operatii aritmetice
- Exista proceduri incorporate care pot fi utilizate pentru efectuarea operatiilor
aritmetice.
-Efectuarea operatiilor aritmetice trebuie sa fie ceruta in mod explicit de catre
ar fi <, =< etc. (vezi folia anterioara). Acesti operatori forteaza evaluarea
argumentelor lor.
•Operatorul infixat mod da restul unei impartiri intregi.
implementare. (De obicei se refera la impartirea reala, iar div la cea intreaga).
•Comentariile in Prolog sunt precedate de caracterul %
precedenta 0;
ü un argument de tip structura are precedenta egala cu cea a functorului
operator.
- Semnificatiile lui x si y in stabilirea tipului operatorului sunt urmatoarele:
ü x reprezinta un argument (operand) cu precedenta strict mai mica decat
•Prolog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail –
un predicat:
Østandard,
Øfara argumente,
•Introducerea unui predicat fail intr-o conjunctie de scopuri, de obicei la sfarsit (caci
dupa fail nu se mai poate satisface nici un scop), determina intrarea in procesul de
backtracking.
•Daca fail se intalneste dupa predicatul cut, nu se mai face backtracking.
ion
ana vasile
mihai rodica
Fiecare nod desemnează o persoană iar legătura directă între noduri reprezintă relaţia
“părinte”
(de exemplu ion este părintele anei şi al lui vasile). Soluţia nerecursivă impune
definirea de reguli pentru fiecare grad de descendenţă:
stramos(X, Y) : - parinte(X, Y).
stramos(X, Y) : - parinte(X, Z), parinte( Z, Y).
stramos(X, Y) : - parinte(X, Z1), parinte( Z1, Z2), parinte( Z1, Y).
BACK Cuprins NEXT
De fiecare dată când mergem mai adânc în arborele de familie, trebuie să definim o
nouă regulă.
acest lucru este fără îndoială ineficient din punct de vedere al programării, deoarece un
program este util şi eficient numai dacă rezolvă cazuri generale şi nu doar cazuri
particulare ale unei probleme. Există o cale mai eficientă de a defini relaţia “strămoş”.
Observăm că pentru orice X şi
Y din arborele de familie, X este strămoş pentru Y dacă există un Z astfel încât X este
părinte al
lui Z şi Z este strămoş al lui Y. Astfel, putem scrie următoarea clauză:
stramos(X, Y) : - parinte(X, Z), stramos( Z, Y).
În această definiţie predicatul “stramos” apare şi în corpul regulii şi în corpul ei.
Definiţiile de acest fel se numesc definiţii recursive, iar relaţii pe care le desemnează
se numesc relaţii
recursive. În exemplu nostru controlul relaţiei “stramos” dintre maria şi
mihai este ilustrat de
nivelurile diagramei următoare:
maria maria maria
strămoş
ion ion strămoş ion
nivel 0 strămoş
ana ana
nivel 1
mihai
nivel 2
parinte(maria, Z)
Z/ion
stramos(ion, ana)
X/ion, Y/ana
parinte(ion, Z), stramos(Z, ana)
parinte(ion, Z)
Z/ana Z/vasile
stramos(ana, ana) stramos(vasile, ana)
X/ana, Y/ana X/ana, Y/ana
parinte(ana, Z), stramos(Z, ana) parinte(vasile, Z), stramos(Z, ana)
parinte(ana, Z) parinte(vasile, _)
Z/mihai Z/rodica no
stramos(mihai, ana) stramos(rodica, ana)
X/ana, Y/ana X/ana, Y/ana
parinte(mihai, Z), stramos(Z, ana) parinte(rodica, Z), stramos(Z, ana)
parinte(mihai,_) parinte(rodica,_)
no no
Ø A doua problemă conţine instanţele “generale” ale problemei, ale căror soluţii se găsesc
în cadrul aceluiaşi grup influenţează modul de execuţie, deoarece ele sunt inspectate în
vederea resatisfacerii în ordinea în care sunt trecute. Ordinea în care sunt aşezate grupurile
de clauze nu prezintă importanţă.
§ Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea. În urma
unificării variabilele libere devin legate. Legarea variabilelor este locală (numele unei
variabile dintr-o clauză nu are nici o legătură cu acelaşi nume dintr-o altă clauză).
§ Pentru satisfacerea scopului, sau satisfacerea corpului unei reguli PROLOG utilizează
utilizând predicatul not. Clauza not(p(arg1, arg2,…, argn)) este satisfăcută dacă şi numai
dacă
clauza p(arg1, arg2,…, argn) nu se poate satisface.
§ PROLOG admite recursivitatea în sensul că acelaşi nume de predicat poate apare şi în
capul unei reguli şi în corpul ei. În situaţia în care se utilizează definiţii recursive este
necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive).
Stilul Edinburg
Scrierea termenilor
Predicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran. Predicatul nl muta
“cursorul” la o linie noua.
?- write ('Hello_ther e ) , nl, write('Goodbye').
Hello there
Goodbye
true.
De notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple). Varianta writeq a lui write
va afisa si ghilimelele.
Exista doua streamuri permanent deschise: user_imput si user_output, corespunzand intrarii si iesirii la consola.
Deschiderea streamurilor
Predicatul open(Filename, Mode, Stream, Obtions) deschide un stream.
Inchiderea streamurilor
Predicatul close(Stream, Obtions) inchide Stream cu obtiunile Obtion.
close(Stream) este versiunea fara obtiuni.
Obtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare, fisierul se considera inchis, fara sa ridice
o eroare.
Proprietati ale streamurilor
Predicatul stream_property(Stream, Property) poate fi folosit pentru detectarea proprietatilor.
Citirea termenilor
read_term(Stream, Term, Obtions)
read_term(Term, Obtions)
read(Stream, Term)
read(Term)
Scrierea termenilor
write_term(Stream, Term, Obtions)
write_term(Term, Obtions)
write(Stream, Term)
Write(term)