tutorial prolog

50
TUTORIAL PROLOG REALIZAT DE BALANOIU CARMEN-EMILIA

Upload: carmen-macota

Post on 25-Jun-2015

872 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Tutorial Prolog

TUTORIAL PROLOG

REALIZAT DE BALANOIU CARMEN-EMILIA

CUPRINS

Scurt istoricProcurare PrologIntroducere

NEXT

Deosebiri intre programarea logica si clasica

Cum utilizam Prolog

Structura unui program in PrologUn exemlu de program prolog

Reguli recursive

Satisfacerea clauzelor in Prolog(Backtracking)

Sintaxa limbajului PrologControlul procesului de Backtracking Cut si FailListe

Recursivitate in Prolog

Operati de intrareiesire

Scurt istoric

Cuvacircntul PROLOG provine de la PROgramming in LOGic Ca limbaj de programare a apărut icircn anul 1972 ca produs al şcolii franceze de informatică (A Colmerauer P Roussel) fiind utilizat iniţial icircn domeniul procesării limbajului natural Un eveniment care a influenţat favorabil evoluţia acestui limbaj a fost conferinţa de la Tokyo din anul 1981 la care japonezii au anunţat programul de realizare a noii generaţii de calculatoare adică a sistemelor de procesare a cunoştinţelor PROLOG a fost ales de cercetătorii japonezi ca limbaj de bază pentru calculatoarele din generaţia a cincea Actualmente acest limbaj se bucură de o extindere din ce icircn ce mai mare şi icircn consecinţă există mai multe dialecte dezvoltate şi implementate atacirct pe min cacirct şi pe microcalculatoare

BACK NEXTCuprins

Procurare Prolog

BACK Cuprins NEXT

Accesati site-ul wwwswi-prologorg

1 2

BACK Cuprins NEXT

43

In functie de sistemul de operare folosit alegeti versiunea de Swi-Prolog care vi se potriveste

Salvati fisierul dupa care il instalati

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 2: Tutorial Prolog

CUPRINS

Scurt istoricProcurare PrologIntroducere

NEXT

Deosebiri intre programarea logica si clasica

Cum utilizam Prolog

Structura unui program in PrologUn exemlu de program prolog

Reguli recursive

Satisfacerea clauzelor in Prolog(Backtracking)

Sintaxa limbajului PrologControlul procesului de Backtracking Cut si FailListe

Recursivitate in Prolog

Operati de intrareiesire

Scurt istoric

Cuvacircntul PROLOG provine de la PROgramming in LOGic Ca limbaj de programare a apărut icircn anul 1972 ca produs al şcolii franceze de informatică (A Colmerauer P Roussel) fiind utilizat iniţial icircn domeniul procesării limbajului natural Un eveniment care a influenţat favorabil evoluţia acestui limbaj a fost conferinţa de la Tokyo din anul 1981 la care japonezii au anunţat programul de realizare a noii generaţii de calculatoare adică a sistemelor de procesare a cunoştinţelor PROLOG a fost ales de cercetătorii japonezi ca limbaj de bază pentru calculatoarele din generaţia a cincea Actualmente acest limbaj se bucură de o extindere din ce icircn ce mai mare şi icircn consecinţă există mai multe dialecte dezvoltate şi implementate atacirct pe min cacirct şi pe microcalculatoare

BACK NEXTCuprins

Procurare Prolog

BACK Cuprins NEXT

Accesati site-ul wwwswi-prologorg

1 2

BACK Cuprins NEXT

43

In functie de sistemul de operare folosit alegeti versiunea de Swi-Prolog care vi se potriveste

Salvati fisierul dupa care il instalati

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 3: Tutorial Prolog

Scurt istoric

Cuvacircntul PROLOG provine de la PROgramming in LOGic Ca limbaj de programare a apărut icircn anul 1972 ca produs al şcolii franceze de informatică (A Colmerauer P Roussel) fiind utilizat iniţial icircn domeniul procesării limbajului natural Un eveniment care a influenţat favorabil evoluţia acestui limbaj a fost conferinţa de la Tokyo din anul 1981 la care japonezii au anunţat programul de realizare a noii generaţii de calculatoare adică a sistemelor de procesare a cunoştinţelor PROLOG a fost ales de cercetătorii japonezi ca limbaj de bază pentru calculatoarele din generaţia a cincea Actualmente acest limbaj se bucură de o extindere din ce icircn ce mai mare şi icircn consecinţă există mai multe dialecte dezvoltate şi implementate atacirct pe min cacirct şi pe microcalculatoare

BACK NEXTCuprins

Procurare Prolog

BACK Cuprins NEXT

Accesati site-ul wwwswi-prologorg

1 2

BACK Cuprins NEXT

43

In functie de sistemul de operare folosit alegeti versiunea de Swi-Prolog care vi se potriveste

Salvati fisierul dupa care il instalati

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 4: Tutorial Prolog

Procurare Prolog

BACK Cuprins NEXT

Accesati site-ul wwwswi-prologorg

1 2

BACK Cuprins NEXT

43

In functie de sistemul de operare folosit alegeti versiunea de Swi-Prolog care vi se potriveste

Salvati fisierul dupa care il instalati

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 5: Tutorial Prolog

BACK Cuprins NEXT

43

In functie de sistemul de operare folosit alegeti versiunea de Swi-Prolog care vi se potriveste

Salvati fisierul dupa care il instalati

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 6: Tutorial Prolog

INTRODUCEREUn program este alcătuit din două elemente logica şi controlul Prin termenulldquologicărdquo se desemnează toate noţiunile care stabilesc CE face un program icircn timp ce termenul ldquocontrolldquo semnifică toate noţiunile sintactice care stabilesc CUM o face (de exemplu algoritmul care rezolvă o problemă) Un program scris icircn PASCAL sau vreun alt limbaj de programare tradiţional constă din instrucţiuni care descriu acţiunile ce trebuie executate pas cu pas de cătrecalculator pentru ca programul să producă rezultatul dorit Dimpotrivă un program icircn PROLOG este o bază de natură logică icircn care programatorul defineşte obiecte şi relaţii icircntre aceste obiecte(fie relaţii care există direct icircntre obiecte fie regulile după care se pot deduce alte relaţii sauproprietăţi ale acestora) Obiectele sunt reprezentate icircn PROLOG prin nume simbolice Relaţiile existente icircntre obiecte se definesc cu ajutorul clauzelor Există două feluri de clauze fapte şi reguli Structura sintactică a unui fapt este următoarea nume(arg1 arg2 hellip argn)unde1048766 nume este un nume de predicat adică o succesiune de caractere (alfabetice cifre sau liniuţa de subliniere) avacircnd proprietatea că primul caracter este o literă mică aalfabetului

CuprinsBACK NEXT

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 7: Tutorial Prolog

CuprinsBACK NEXT

1048766 arg1 arg2 hellip argn se numesc argumentele predicatului iar din punct de vedere sintactic pot fi nume de obiecte sau nume de variabilă (un nume de variabilă este o succesiune de caractere astfel icircncacirct primul caracter este o literă mare din alfabet)O regulă este o construcţie sintactică de forma cn+1 - c1 c2hellip cnunde1048766 entităţile c1 c2hellip cn cn+1 sunt de forma nume(arg1 arg2 hellip argk) nume arg1 arg2 hellip argk avacircnd aceeaşi semnificaţie ca icircn cazul unei fapte 1048766 cn+1 se numeşte capul reguli1048766 c1 c2hellip cn formează corpul reguliClauza codifică următorul enunţ ldquoDacă c1 şi c2 şi hellip cn sunt adevărate atunci cn+1 este adevăratărdquoObservăm că orice faptă şi orice regulă se icircncheie cu caracterul ldquordquo iar ldquordquo prezentă icircn corpul regulii suplineşte operatorul ldquoşirdquo Dacă icircn loc de ldquordquo utilizăm ldquordquo atunci icircn locul operatorului ldquoşirdquo se consideră operatorul ldquosaurdquo Prin urmare clauza a - b c codifică enunţul ldquodacă b sau c atunci ardquo

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 8: Tutorial Prolog

Deosebiri intre programarea logica si clasica

CuprinsBACK NEXT

Icircn general icircntr-un limbaj de programare tradiţional un program exprimă o funcţie de la intrarea la ieşirea programului icircn timp ce un program icircntr-un limbaj de programare logică exprimă o relaţie icircntre date Icircntrucacirct relaţiile sunt mai generale decacirct funcţiile programarea logică are posibilităţi mai mari decacirct are programarea tradiţionalăSă luăm drept exemplu un program care citeşte două numere reale şi icircl afişează pe cel mai mare dintre ele Pentru a face diferenţa dintre programarea tradiţională şi programarea logică mai explicită vom da mai icircntacirci programul icircn PASCAL iar apoi acelaşi program icircn PROLOG

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 9: Tutorial Prolog

Program icircn PASCAL

var xy real begin write(lsquonumar1 = lsquo) readln(x) write(lsquonumar2 = lsquo) readln(y) if (x lt y) then writeln(x) else writeln(y)end

Program icircn PROLOG

predicates program mai_mare(realrealreal)clauses program - write(n1=) readreal(X) write(n2=) readreal(Y)mai_mare(XYZ) write(Z) nl mai_mare(XXX) mai_mare(XYY)-XltY mai_mare(XYX)-YltXgoal program

CuprinsBACK NEXT

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 10: Tutorial Prolog

Secţiunea var (din programul PASCAL) şi secţiunea predicates (din programul PROLOG) au un caracter declarativ icircn secţiunea var se declară variabilele reale x şi y iar icircn secţiunea predicates se declară predicatele program (fără argumente) şi mai_mare (cu trei argumente reale) Programul icircn PASCAL este doar un şir de instrucţiuni Aceste instrucţiuni care sunt executate icircn ordinea indicată de program constituie ldquocontrolulrdquo ldquoElementul logicrdquo icircn programul din PASCAL se află icircn relaţia ldquogtrdquo Dimpotrivă programul icircn PROLOG este o colecţie de clauze care descriu complet relaţia de ordine totală a două numere reale icircn speţă predicatul ldquomai_marerdquo Această colecţie de clauze exprimă logica programului care are şi rolul dominant icircntr-un program PROLOG icircn timp ce controlul se află icircn ordinea icircn care aranjăm şi definim predicatele De asemenea lansarea icircn execuţie a unui program PROLOG nu se face definind un punct de icircnceput după care instrucţiunile să fie preluate secvenţial aşa cum se icircntacircmplă icircnlimbajele tradiţionale de programare Execuţia unui program cere definirea unui scop (icircn secţiunea goal) care trebuie verificat pe baza elementelor din program (icircn exemplul nostru scopul este dat de predicatul program)

CuprinsBACK NEXT

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 11: Tutorial Prolog

NEXTCuprinsBACK

O altă diferenţă icircntre programarea logică şi cea clasică constă icircn semnificaţia variabilelorProgramarea icircn PROLOG nu utilizează conceptul de atribuire Actualizarea variabilelor prin obiecte PROLOG date se realizează prin unificare Icircn general cu unificarea se analizează dacă două predicate pot fi identice Dacă ele nu pot fi identice procedura de unificare eşuează Dacă ele pot fi identice unificarea reuşeşte iar rezultatul unificării este actualizarea variabilelor celor două predicate cu anumite de valori astfel icircncacirct cele două predicate să coincidă (ldquomatchrdquo) Pentruactualizare se foloseşte adesea termenul legare (ldquobindingrdquo) sau instanţire O variabilă prezentă icircntr-o clauză are efect local clauzei respective Variabilei i se leagă o valoare iar ieşirea din clauză determină dezlegarea ei de valoare Există o variabilă care joacă un rol special icircn PROLOG ea se numeşte variabilă anonimă şi se reprezintă prin ldquo_rdquo Prezenţa variabilei anonime pe locul unui argument precizează că nu interesează valoarea legată de argument ci numai existenţa unei asemenea valori

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 12: Tutorial Prolog

CUM UTILIZAM PROLOG

Cuprins NEXT

BACK

Pentru a putea utiliza Prolog trebuie mai intai sa deschidem un fisier text(ex notepad) in care vom scrie baza de date si pe care il vom salva cu extensia ldquoplrdquo(ex proiectpl)

Dupa ce am terminat cu fisierul textintram in meniul ldquofilerdquo al Prologuluiunde accesam optiunea ldquoconsultrdquoAlegem fisierul creat mai devreme si suntem gata sa interogam

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 13: Tutorial Prolog

Structura unui program in prolog

CuprinsBACK NEXT

Un program icircn PROLOG este o descriere a unor obiecte şi relaţii existente icircntre acesteobiecte Obiectele sunt reprezentate prin nume simbolice a căror structură sintactică estedeterminată de tipul obiectelor Există două clase de tipuri tipul elementar şi tipul complexTipul elementar poate fi standard sau definit de utilizator Tipurile definite de utilizator sunt de fapt tot tipuri standard dar definite prin nume date de utilizator nume ce sugerează semnificaţia obiectelor de tipul respectiv Tipul complex la racircndul lui se subicircmparte icircn tipul compus şi tipul listă Un nume de tip compus are următoarea structură sintactică nume simbolic urmat de unul sau mai multe tipuri separate prin virgulă şi icircnchise icircntre paranteze rotunde Un obiect de tip listă este un şir de obiecte de acelaşi tip separate prin virgulă şi icircnchise icircntre paranteze drepte Elementele unei liste pot fi de tip elementar sau de tip compusDin punct de vedere sintactic un program icircn PROLOG se compune din unul sau maimulte module Unul dintre module este definit ca modul principal Numai acest modul poate să conţină enunţul unui scop (goal) Icircn general obiectele şi predicatele cu care se lucrează sunt locale fiecărui modul Dacă un nume de predicat sau tip de obiecte este utilizat icircn două module el reprezintă predicate diferite respectiv tipuri diferite

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 14: Tutorial Prolog

CuprinsBACK NEXT

Există icircnsă şi posibilitatea de defini a predicate sau tipuri globale (comune mai multor module) Un modul este alcătuit din mai multe secţiuni Enumerăm mai jos aceste secţiuni precizacircnd şi descrierea sintactică a elementelor ce compun fiecare secţiune icircn parte Utilizăm convenţia de scriere potrivit căreia elementele opţionale sunt icircncadrate icircntre paranteze drepteconstantsconst1 = definiţieconst2 = definiţiehelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se definesc constantele utilizate icircn programdomainstip_util1 [tip_util2 tip_util3 hellip ] = tip1 tip2helliplista1 = tip_elementhelliphelliphelliphelliphelliphelliphelliphelliphelliphelliptip_util1 tip_util2 tip_util3 hellip lista1 reprezintă nume simbolice care desemnează tipuri de obiecte definite de programator tip1 tip2hellip reprezintă o listă de tipuri standard sau de tipuri definite de utilizator Obiectele de tip lista1 sunt liste ale căror elemente sunt de tip tip_elementglobal domainsIcircn această secţiune programatorul defineşte tipurile globale Structura acestei secţiuni este aceeaşi cu cea a secţiunii domains

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 15: Tutorial Prolog

CuprinsBACK NEXT

database [-nume]global database [-nume]Icircn aceste secţiuni se definesc baze de cunoştinţe dinamice predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn)predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSe definesc predicatele local modului Pentru fiecare predicat se specifică numele şi tipulargumentelor saleglobal predicatespredicat1(tip_arg1 tip_arg2 hellip tip_argn) ndash (i o hellip) [language C | pascal |hellip]predicat2(tip_arg1 tip_arg2 hellip tip_argk)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellipIcircn această secţiune se precizează predicatele globale şi tipul argumentelor lor precum şi faptul că anumite argumente sunt de intrare şi altele de ieşire şi eventual limbajul icircn care este scrisă procedura ce corespunde predicatuluiclausespredicat(arg1 arg2 hellip argn)predicatk+1(hellip) - predicat1(hellip) predicat2(hellip) hellip predicatk(hellip)helliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphelliphellip

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 16: Tutorial Prolog

CuprinsBACK NEXT

Această secţiune este destinată definirii clauzelor Toate clauzele care se referă la acelaşi nume de predicat trebuie grupategoalpredicat1(hellip) [ predicat2(hellip) hellip predicatk(hellip)]Scopul (ldquogoalrdquo) unui program PROLOG reprezintă o interogare privind faptele şi regulile definite icircn secţiunea clauses Interogarea se poate realiza icircn două moduri icircn secţiunea goal a programului sau icircn fereastra dialog Oricare formă din acestea o exclude pe cealaltă Structura sintactică a unei interogări este aceeaşi cu structura sintactică a corpului unei regulibull Nu toate secţiunile sunt obligatoriibull Ordinea icircn care aceste trebuie să apară este următoarea directive de compilare domains global domains databas predicates global predicates clausesbull Aşezacircnd directiva trace icircn faţa secţiunii domains se poate controla pas cu pas execuţia unui scopbull Secţiunea goal dacă apare se aşează fie icircnainte fie după secţiunea clausesbull Comentariile pot fi incluse oriunde icircn program Un comentariu este un text care icircncepe cu şi se termină cu bull Scrierea unui program icircn PROLOG este liberă (se pot scrie mai multe clauze pe un racircnd sau o regulă pe mai multe racircnduri etc) Sintaxa cere ca fiecare clauză să se icircncheie cu punctbull Icircn cazul icircn care se utilizează definiţii globale este de preferat ca acestea să sedefinească icircntr-un fişier separat care apoi să fie inclus icircn fiecare modul cu ajutoruldirectivei include care are formainclude ldquonume_fişierrdquo

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 17: Tutorial Prolog

CuprinsBACK NEXT

- Programele Prolog opereaza cu obiecte si cu relatii intre obiecte (fapte sisau clauze)- Negatia joaca un rol foarte important in programarea in acest limbaj deoarece orice proprietate care nu se poate deduce din entitatile programului este considerata falsa deci negatia ei este adevarata-Prolog foloseste un model de rationament minimal numit ipoteza lumii inchise Conform acestui 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 fapt o particularizare a ipotezei lumii inchisebull O clauza Prolog sau regula este de forma H - B1 B2 hellip Bnunde H este capul regulii iar membrul drept constituie corpul regulii (care este o conjunctie sau o disjunctie de scopuri)bull Sensul clauzei Prolog anterioare este If B1 amp B2 amp hellip amp Bn then Hbull In Prolog constantele se scriu cu litera mica iar variabilele cu litera marebull SimbolhelliphelliphelliphelliphelliphelliphelliphelliphelliphellipSens - daca conjunctie disjunctie _ variabila universala (semnifica orice)bull O fapta Prolog este o clauza fara corp adica de forma H Ea reprezinta o clauza care este tot timpul adevarata deoarece nu este conditionata

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 18: Tutorial Prolog

CuprinsBACK NEXT

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 Exista atatea solutii cate unificari diferite exista Obtinerea primei solutii este numita satisfacerea scopului iar obtinerea altor solutii resatisfacerea scopului La satisfacerea unui scopcautarea 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

Obtinerea solutiilor atunci cand baza de cunostinte Prolog contine si reguli

In acest caz unificarea scopului se incearca atat cu fapte din baza de cunostintecat si cu antetul regulilor din bazaLa 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 initialComportarea sistemului Prolog in care se incearca in mod repetat satisfacerea siresatisfacerea scopurilor din conjunctia de scopuri se numeste backtracking

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 19: Tutorial Prolog

Un exemplu de program in Prolog

CuprinsBACK NEXT

(Definirea unor relatii de familie)

-Faptul ca Tom este parinte al lui Bob se poate scrie astfel in Prolog- parinte(tombob)

Aici parinte este numele reletiei iar tom si bob reprezinta argumentele sale

Program Prolog care defineste relatii de familie

parinte(pambob) parinte(tombob) parinte(tomliz) parinte(bobann) parinte(bobpat) parinte(patjim)

Programul consta din 6 clauzeFiecare dintre aceste clauze declara un fapt despre relatia parinteSpre exempluparinte(tombob) este o instantiere particulara a relatiei parinteIn general o relatie se defineste ca fiind multimea tuturor instantierilor sale Obs Acest program simplu nu contine (inca) reguli (ci doar fapte)

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 20: Tutorial Prolog

Interogarea Prologului

CuprinsBACK NEXT

Ex Vrem sa aflam daca Bob este parinte al lui Pat Aceasta intrebare este comunicata sistemului prolog tastandu-se la terminal-parinte(bobpat)Raspunsul Prologului va fiyes

Alte exemple de interogari

-parinte(lizpat) bullCine este parinte al cuino -parinte(XY)-parinte(tomben) X=pamno Y=bobbull Cine eate parintele lui Liz-parinte(Xliz) X=tomX=tom Y=bobbullCine sunt copii lui Bobparinte(bobX) X=tomX=ann Y=lizX=pat no

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 21: Tutorial Prolog

CuprinsBACK NEXT

bull Cine este bunic al lui Jim(1) Cine este parinte al lui Jim Presupunem ca aceste este un Y(2) Cine este parinte al lui Y Presupunem ca acesta este un X

(3) si (2) necesita urmatoarea interogare compusa -parinte(Yjim)parinte(XY)Raspunsul prologului este X=bob Y=patObs Interogarea -parinte(XY)parinte(Yjim)va produce acelas rezultatbullCine sunt nepotii lui Tom -parinte(tomX)parinte(XY) X=bob Y=ann

X=bob Y=pat

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 22: Tutorial Prolog

CuprinsBACK NEXT

bull Ann si Pat au un parinte comun -parinte(Xann)parinte(Xpat) X=bob

Extinderea programului cu reguli

bull Introducem mai intai urmatoarele fapte noi feminin(pam) masculin(tom) masculin(bob) feminin(liz) feminin(pat) feminin(ann) masculin(jim) si sex(pam feminin) sex(tom masculin) sex(bob masculin) hellip si urmas(liz tom) hellip

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 23: Tutorial Prolog

CuprinsBACK NEXT

Obs Relatia urmas poate fi definita intr-un mod mult mai elegant prin folosirea relatiei deja definite parintePentru toti X si toti YY este urmas al lui X dacaX este parinte al lui YAceasta interpretare genereaza o clauza Prolog reprezentata de urmatoarea regula urmas(Y X) - parinte(X Y)bull Interogarea Prologului cand baza de cunostinte contine si aceasta regula - urmas(liz tom)Cum lucreaza Prologul acum Intrucat nu exista fapte referitoare la urmasi trebuiefolosita 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 cazparticular este urmas(liz tom) - parinte(tom liz)- Corpul regulii reprezinta partea de conditie iar antetul ei partea de concluzieProlog incearca sa determine daca partea de conditie este adevarata ie daca parinte(tom liz) este adevarat In acest moment scopul initial urmas(liztom) a fost inlocuit cu subscopul parinte(tom liz)- Noul scop este imediat satisfacut intrucat el reprezinta o fapta Prolog (din baza decunostinte)

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 24: Tutorial Prolog

CuprinsBACK NEXT

- Aceasta inseamna ca partea de concluzie este de asemenea adevarata iar Prologva raspunde la intrebare cu yesbull Introducem acum relatii de familie suplimentare relatia mama definita astfelmama (X Y) - parinte (XY) feminin (X) relatia bunic definita astfelbunic (X Z) - parinte (X Y) parinte(Y Z) relatia sora definita astfelsora (X Y) -parinte (Z X)parinte (Z Y)feminin (X)bull Interogarea Prologului daca ann si pat sunt surori- sora (ann pat)yes cine este sora lui Pat- sora (X pat)X = annX = pat

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 25: Tutorial Prolog

CuprinsBACK NEXT

Obs Relatia sora ar trebui sa fie definita dupa cum urmeazasora (X Y) - parinte (Z X) parinte (Z Y) feminin (X) diferit (X Y)unde predicatul diferit (XY) trebuie definit astfel incat el sa fie satisfacut daca si numaidaca X e diferit de Y Reguli recursive relatia predecesor un predecesor poate fi direct (parinte)predecesor (X Z) - parinte (X Z) sau indirectpredecesor (X Z) - parinte (X Y) parinte (Y Z)predecesor (X Z)- parinte (X Y1) parinte (Y1 Y2) parinte(Y2 Z)

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 26: Tutorial Prolog

CuprinsBACK NEXT

OBS Pentru ca relatia predecesor sa lucreze corect in cazul predecesorilor aflati la oriceadancime definitia ei trebuie gandita in felul urmatorbull 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 ZClauza Prolog corespunzatoare (recursiva) estePredecesor (XZ) - parinte (XY) predecesor (YZ)Definirea relatiei predecesor- consta din doua reguli una care se refera la predecesori directi si cealalta la predecesori indirecti Definitia completa este urmatoareapredecesor (X Z) - parinte (XZ)predecesor (X Z) - parinte (X Y) predecesor (Y Z)Exemplu de interogare a Prologului (care sunt succesorii lui Pam)- predecesor (pam X)X = bob X=patX = ann X=jim

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 27: Tutorial Prolog

CuprinsBACK NEXT

Satisfacerea clauzelor in Prolog (Backtracking)

Presupunem ca programul nu contine reguli ci numai fapte Presupunem ca avem un program ce contine si reguli

1 Programul nu contine reguli ci numai fapteDaca scopul are forma p1 p2 hellip pn se incearca satisfacerea lui de la stanga la dreapta Atunci cand acesta nu contine variabile daca baza de fapte satisface intreg scopul Prolog raspunde cu YES altfel cu NO Daca scopul contine variabile atunci obiectivul este acela de a gasi toate legaturile posibile pentru variabile care sa satisfaca scopul (deci de a da toate solutiile) Mai precis se parcurge baza de fapte si se satisface o data p1 Se trece apoi la satisfacerea lui p2 Daca p2 este satisfacut atunci se trece la p3Daca p2 nu se satisface atunci se dezleaga variabilele lui p1 si se inspecteaza baza de fapte pentru a gasi alte valori care legate de variabilele lui p1 sa resatisfaca p1 apoi se reincearca satisfacerea lui p2 cu noile legaturi Blocarea acestui proces de Backtracking se poate face cu predicatul (ldquocutrdquo) asezat intre doua clauze consecutive pi si pi+1 ale scopului In acest caz nu se incearca resatisfacerea lui pi

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 28: Tutorial Prolog

CuprinsBACK NEXT

Daca programul contine si reguliSatisfacerea scopului se realizeaza in urmatorii pasi a) Presupunem clauzele p1hellip pi au fost satisfacute b) In vederea satisfacerii lui pi+1 se inspecteaza mai intai baza de fapte Daca pi+1 se satisface cu o fapta se trece la pi+2 Daca nu exista elemente in baza de fapte care sa satisfaca pe pi+1 se inspecteaza baza de reguli si se identifica primadintre regulile neluate in consideratie pana in prezent al carei cap se poate unifica cu pi+1 se intra in corpul regulii identificate considerand clauzele care il compun drept componente ale scopului Daca una din clauzele corpului nu poate fi satisfacuta se identifica o alta regula al carei cap sa se unifice cu pi+1 In cazul in care nu exista o asemenea regula se incearca resatisfacereaclauzelor pi pi-1 hellipUnificare Satisfacerea unui scop de tipul X = Y se face prin incercarea de a unifica X cu Y Din aceasta cauza dandu-se un scop de tipul X = Y regulile de decizie care indica daca scopul se indeplineste sau nu sunt1 Daca X este variabila neinstantiata iar Y este instantiata la orice obiect Prolog atunci scopul reuseste Ca efect lateral X se va instantia la aceeasi valoare cu cea a lui Y2 Daca atat X cat si Y sunt variabile neinstantiate scopul X = Y reuseste variabila X este legata la Y si reciproc ie ori de cate ori una dintre cele doua variabile se instantiaza la o anumita valoare cealalta variabila se va instantia la aceeasi valoare3 Atomii si numerele sunt intotdeauna egali cu ei insisi4 Doua structuri (a se vedea sintaxa limbajului) sunt egale daca au acelasi functor acelasi numar de componente si fiecare componenta dintr-o structura este egala cu componenta corespunzatoare din cealalta structura

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 29: Tutorial Prolog

CuprinsBACK NEXT

Sintaxa limbajului Prolog

bull Constantele definesc Obiecte particulare Relatii particulare Constantele sunt de urmatoarele tipuri atomi ndash constante simbolice (desemneaza predicate Prolog sau argumente ale predicatelor) numereAtomii pot fi construiti in 3 moduri ei pot constitui 1) siruri de litere cifre si caracterul ldquounderscorerdquo bdquo_‟ siruri care incep cu o literamica 2) siruri de caractere speciale 3) siruri de caractere incluse intre paranteze simple (ex bdquoSouth_America‟) Numerele majoritatea implementarilor admit o gama de valori cuprinse intre ndash 16383si +16383 dar gama poate fi si mai largabull Variabilele au denumiri care incep cu litere mari numele de variabila poate incepe si cu simbolul ldquo_rdquo ceea ce indica o variabila anonima utilizarea unei variabile anonime semnifica faptul ca nu intereseaza valoarea la care se va instantia acea variabilascopul lexical al unui nume de variabila il constituie o unica clauza (Daca spre exemplu numele X15 intervine in doua clauze diferite atunci el semnifica doua variabile diferiteFiecare ocurenta a lui X15 in interiorul aceleiasi clauze semnifica insa o aceeasi variabila)

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 30: Tutorial Prolog

CuprinsBACK NEXT

bull Structurile sunt obiecte ce desemneaza o colectie de obiecte corelate logic care formeaza componentele structuriiEx poseda(mihai carte(prolog clocksin 1981)) Sunt folosite la reprezentarea structurilor de date (liste arbori)O structura se defineste prin specificareabull numelui structurii (functorul structurii)bullelementelor sau componentelor structuriiDesi alcatuite din mai multe componente sunt tratate de program ca obiecte unice Pentru combinarea componentelor intr-un unic obiect este folosit un functor Acesta va fi radacina arborelui intr-o reprezentare arborescentabull OperatoriOperatori aritmetici- sunt o rescriere infixata a unor structuri si de aceea valoarea expresiei definite cu ei nu este calculata-evaluarea expresiei se face la cerere in cazul in care se foloseste operatorul predefinit infixat is ca in exemplul X is 1+2 (in acest caz se instantiaza variabila X la valoarea 3)Operatori relationali- sunt predicate predefinite infixate- cel mai important este operatorul de egalitate care functioneaza ca si cand ar fi definit prin urmatorul fapt X = X (VEZI satisfacerea unui scop de tipul X = Y prin incercarea de a unificaX cu Y)

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 31: Tutorial Prolog

CuprinsBACK NEXT

Exemplu - X = 1+2 - X is 1+2 X = 1+2 X = 3deoarece in primul caz expresia 1+2 denota o structura (termen) Prolog unde + este functorul iar 1 si 2 sunt argumentele sale Nimic din acest scop nu declanseaza adunareacare este declansata de operatorul is Operatori relationali ndash continuare- Operatorul de inegalitate == se defineste ca un predicat opus celui de egalitate scopul X==Y reuseste daca scopul X=Y nu este satisfacut si esueaza daca X=Y reuseste (semnificatie valorile lui X si Y nu sunt egale)- Predicatul == testeaza echivalenta a doua variabile X==Y reuseste ori de cate ori X=Y reuseste dar reciproca este falsa Este vorba de egalitatea literala a doi termeni- X==Y este adevarat daca termenii X si Y sunt identici adica au exact aceeasi structura si toate componentele corespunzatoare coincid In particular numele de variabile trebuie sa fie aceleasi-Relatia complementara (de non-identitate) este ==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 egaleDiferenta dintre operatorii = si ==- 1+2 == 2+1 -1+2=2+1yes no- Inegalitatea a doua expresii aritmetice se stabileste cu operatorul ==

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 32: Tutorial Prolog

CuprinsBACK NEXT

Valorile expresiilor aritmetice pot fi comparate prin intermediul operatorilor careurmeaza Acesti operatori forteaza evaluarea argumentelor lorX gt Y (X este mai mare ca Y)X lt Y (X este mai mic ca Y)X gt= Y (X mai mare sau egal decat Y)X lt= 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 procedura incorporata is-- Exista proceduri incorporate asociate operatorilor predefiniti + - div si mod- In momentul in care se efectueaza evaluarea toate argumentele trebuie sa fie dejainstantiate la anumite numere-Valorile expresiilor aritmetice pot fi comparate prin intermediul unor operatori cum ar fi lt =lt etc (vezi folia anterioara) Acesti operatori forteaza evaluarea argumentelor lorbullOperatorul infixat mod da restul unei impartiri intregibullOperatorul infixat div da catul unei impartiri intregibullOperatorul poate sa desemneze impartire intreaga sau reala in functie deimplementare (De obicei se refera la impartirea reala iar div la cea intreaga)bullComentariile in Prolog sunt precedate de caracterul

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 33: Tutorial Prolog

CuprinsBACK NEXT

Operatori definiti de utilizator- Definirea de noi operatori de catre programator se face prin introducerea in program a unor clauze de forma speciala numite directive-Definirea de noi operatori se face cu ajutorul directivei op(precedenta_operator tip_operator nume_operator) precedata de simbolul -Exemplu- op (600 xfx are)caz in care este legala expresiacoco are pene- Directivele actioneaza ca o definire de noi operatori ai limbajului in care se specifica numele precedenta si tipul (infixat prefixat sau postfixat) operatorului- Nu se asociaza nici o operatie operatorilor definiti de programator- Operatorii noi astfel definiti sunt utilizati ca functori numai pentru a combina obiecte in structuri si nu pentru a executa actiuni asupra datelor- Exemplu In loc de a utiliza structuraare (coco pene)se poate defini un nou operator are- op (600 xfx are)caz in care este legala expresiacoco are pene- Operatorii sunt atomi iar precedenta lor trebuie sa fie o valoare intreaga intr-un anumit interval si corelata cu precedenta operatorilor predefiniti in limbaj- Tipul operatorilor fixeaza caracterul infixat prefixat sau postfixat al operatorului si precedenta operanzilor sai Tipul operatorului se defineste utilizand una din urmatoarele forme standard

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 34: Tutorial Prolog

CuprinsBACK NEXT

(1) operatori infixati xfx xfy yfx(2) operatori prefixati fx fy(3) operatori postfixati xf yfunde f reprezinta operatorul iar x si y operanzii sai- Utilizarea simbolului x sau a simbolului y depinde de precedenta operandului fata de operator Precedenta operanzilor se defineste astfelun argument intre paranteze sau un argument nestructurat are 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 cea a functorului (operatorului) f precedenta (x) lt precedenta (f)y reprezinta un argument (operand) cu precedenta mai mica sau egala cu cea a functorului (operatorului) f precedenta (y) lt= precedenta (f)- Numele operatorului poate fi orice atom Prolog care nu este deja definit in Prolog Se poate folosi si o lista de atomi daca se definesc mai multi operatori cu aceeasi precedenta si acelasi tip

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 35: Tutorial Prolog

CuprinsBACK NEXT

Exemplu- op (100 xfx [este are])- op (100 xf zboara)coco are penecoco zboaracoco este papagalbozo este pinguin

- Cine are peneCine = coco- Cine zboaraCine = coco- Cine este CeCine = coco Ce = papagalCine = bozo Ce = pinguinnoIn conditiile in care se adauga la baza de cunostinte anterioara si definitia operatorilor daca atunci si si- op (870 fx daca) urmatoarea structura este valida in Prolog- op (880 xfx atunci) daca Animalul are pene- op (880 xfy si) si Animalul zboara atunci Animalul este pasare

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 36: Tutorial Prolog

CuprinsBACK NEXT

CONTROLUL PROCESULUI DE BACKTRACKING CUT SI FAIL

- Predicatul cut notat cu atomul special este un predicat standard fara argumente care se indeplineste (este adevarat) intotdeauna si nu poate fi resatisfacut- Comportarea predicatului cut este urmatoarea(C1) H - D1 D2 hellip Dm Dm+1 hellip Dn(C2) H - A1 hellip Ap(C3) H Daca D1 D2 hellip Dm sunt satisfacute ele nu mai pot fi resatisfacute datorita lui cut (se inhiba backtracking-ul) Daca D1 D2 hellip Dm sunt satisfacute C2 si C3 nu vor mai fi utilizate pentru resatisfacerea lui H Resatisfacerea lui H se poate face numai prin resatisfacerea unuia din scopurile Dm+1 hellip Dn daca acestea au mai multe solutiiObs Exista doua contexte diferite in care se poate utiliza predicatul cut si anume intr-un context predicatul cut se introduce numai pentru cresterea eficientei programului caz in care el se numeste cut verde in celalalt context utilizarea lui cut modifica semnificatia procedurala a programului caz in care el se numeste cut rosu (La cut-ul verde semnificatia procedurala a programului este aceeasi adica nu conteaza ordinea in care se scriu clauzele La un cut rosu efectul programului este total diferit daca se schimba ordinea clauzelor)

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 37: Tutorial Prolog

CuprinsBACK NEXT

Cut rosuIntroducerea unui cut rosu modifica corespondenta dintre semnificatia declarativa si semnificatia procedurala a programelor Prolog El permite exprimarea in Prolog a unorstructuri de control de tipulDaca conditie atunci actiune1altfel actiune2astfeldaca_atunci_altfel (Cond Act1 Act2) - Cond Act1daca_atunci_altfel (Cond Act1 Act2) - Act2Obs Utilizarea predicatului cut in definirea predicatului asociat structurii de control daca_atunci_altfel introduce un cut rosu deoarece efectul programului este total diferit daca se schimba ordinea clauzelorEx Definirea predicatului de aflare a minimului dintre doua numere in doua variantemin1(X Y X) - X=ltY cut verdemin1(X Y Y) - XgtYmin2(X Y X) - X=ltY cut rosumin2(X Y Y)Ordinea clauzelor de definire a lui min1 poate fi schimbata fara nici un efect asupra rezultatului programului In cazul predicatului min2 se utilizeaza un cut rosu asemanator structuriidaca_atunci_altfelDaca se schimba ordinea clauzelor de definire a predicatului min2min2(XYY)min2(X Y X) - X=ltY rezultatul programului va fi incorect pentru valori X lt Y

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 38: Tutorial Prolog

CuprinsBACK NEXT

Predicatul fail

bullProlog permite exprimarea directa a esecului unui scop cu ajutorul predicatului fail ndash un predicatstandardfara argumente care esueaza intotdeaunabullDupa fail nu se mai poate satisface nici un scopbullIntroducerea 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 backtrackingbullDaca fail se intalneste dupa predicatul cut nu se mai face backtrackingExemplul 1 (folosirea predicatului fail pentru a determina esecul)Enuntul ldquoUn individ este rau daca nu este bunrdquo se poate exprima astfelrau (X) - bun (X)failrau (X)Exemplu de program ndash folosirea lui fail pentru a determina eseculbun (gelu)bun (vlad)bun (mihai)rau (X) - bun (X)fail ()rau (X) ()Exemplu de executie a programului- rau (gelu) -rau(petru)no yes- rau (mihai)no

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 39: Tutorial Prolog

CuprinsBACK NEXT

Comentariu- la prima interogare din clauza () avem rau (gelu) daca bun (gelu) care este adevarat din primul fapt al bazei de cunostinte apoi este intotdeauna adevarat si urmeaza fail care genereaza esec datorita existentei lui cut clauza () nu va mai fi utilizata pentru resatisfacerea scopului deci raspunsul ramane no ca si in al doilea caz- la a treia interogare pentru clauza () ar trebui sa am bun (petru) dar acest fapt nu exista in baza de cunostinte deoarece bun(petru) nu a fost satisfacut am voie sa utilizez clauza () clauza () furnizeaza rau (petru) deci satisface scopul curent atunci raspunsul este ldquoyesrdquoObservatie Atunci cand este folosit pentru a determina esecul fail este de obiceiprecedat de cut deoarece procesul de backtracking pe scopurile care il preced este inutil scopul esuand oricum datorita lui failExemplul 2 ndash introducerea predicatului fail pentru a genera procesul de backtracking pe scopurile care il precedrosu (mar)rosu (cub)rosu (soare)afisare (X) - rosu (X) write (X) failafisare (_) ()Comentariu Intrucat pentru fiecare obiect considerat scopul afisare (X) esueaza datorita lui fail se trece la clauza () care afiseaza obiectul respectiv adica raspunde yes Trecerea la clauza () este posibila deoarece prima clauza nu contine cut inainte de fail In acest fel vor fi afisate toate obiectele rosii cunoscute de programul Prolog datorita procesului de backtracking generat de fail in acest fel se realizeaza prin fail o iteratie peste faptele rosu ( ) Clauza afisare (_) este adaugata pentru ca raspunsul final la satisfacerea scopului sa fie afirmativ (Aceasta clauza raspunde yes la orice)

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 40: Tutorial Prolog

CuprinsBACK NEXT

LISTE

O lista este de forma [Cap|Coada] Operatii cu liste1 Apartenenta la o lista- se foloseste predicatul membru(XL) unde X este un obiect si L este o lista X este membru al lui L daca(1) X este capul lui L sau(2) X este membru al cozii lui LADICAmembru(X [X|Coada])membru(X [Cap|Coada])-membru(X Coada)2 Concatenarea- se foloseste relatia conc(L1 L2 L3)- definitia predicatului conc esteconc([ ] L L)conc([X|L1] L2 [X|L3]) - conc(L1 L2 L3)

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 41: Tutorial Prolog

CuprinsBACK NEXT

3 Adaugarea unui element- elementul adaugat devine noul capadd(X L [X|L])4 Stergerea unui element- se foloseste relatia del(X L L1)- definitia predicatului del estedel(X [X|Coada] Coada)del(X [Y|Coada] [Y|Coada1]) - del(XCoada Coada1)Observatie Inserarea unui element intr-o lista poate fi definita folosind relatia del astfelinsert(X Lista ListaMaiMare)-del (X ListaMaiMare Lista)Sublisterelatia sublista([cde] [abcdef]) este adevarata dar sublista([ce] [abcdef]) nu esteadevarataDefinitieS este o sublista a lui L daca(1) L poate fi descompusa in doua liste L1 si L2 si(2) L2 poate fi descompusa in doua liste S si o alta lista L3 adicasublista(SL) - conc(L1L2L) conc(SL3L2)

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 42: Tutorial Prolog

CuprinsBACK NEXT

Recursivitatea in Prolog

Intuitiv recursivitatea se naşte icircn clipa icircn care o schiţă este construită prin reproducerea ei icircnsăşi la o altă scară sau la un alt nivel Icircn cadrul programării recursivitatea este o tehnică care constă icircn posibilitatea de a include icircntr-o procedură apeluri la ea icircnsăşi Icircn PROLOG acesta se traduce prin posibilitatea ca un nume de predicat să apară atacirct icircn corpul unei reguli cacirct şi icircn capul ei De exemplu să presupunem că vrem să definim relaţia ldquostrămoşrdquo icircn vederea examinării următoarei părţi a unui arbore de familie maria ion ana vasile

mihai rodicaFiecare nod desemnează o persoană iar legătura directă icircntre noduri reprezintă relaţia ldquopărinterdquo(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)

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 43: Tutorial Prolog

CuprinsBACK NEXT

De fiecare dată cacircnd mergem mai adacircnc icircn arborele de familie trebuie să definim o nouă regulăacest lucru este fără icircndoială 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 ldquostrămoşrdquo Observăm că pentru orice X şiY din arborele de familie X este strămoş pentru Y dacă există un Z astfel icircncacirct X este părinte allui Z şi Z este strămoş al lui Y Astfel putem scrie următoarea clauzăstramos(X Y) - parinte(X Z) stramos( Z Y)Icircn această definiţie predicatul ldquostramosrdquo apare şi icircn corpul regulii şi icircn corpul ei Definiţiile de acest fel se numesc definiţii recursive iar relaţii pe care le desemnează se numesc relaţiirecursive Icircn exemplu nostru controlul relaţiei ldquostramosrdquo dintre maria şi mihai este ilustrat denivelurile diagramei următoaremaria maria maria strămoş ion ion strămoş ionnivel 0 strămoş ana ana nivel 1 mihai nivel 2

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 44: Tutorial Prolog

CuprinsBACK NEXT

Regula introdusă nu ajunge pentru definirea relaţiei ldquostrămoşrdquo Deşi sub aspect logic exprimă ceea ce vrem să definim ea nu dă următorului programului informaţia necesară pentru răspunsulla icircntrebări privind relaţia ldquostrămoşrdquodomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) parinte(ion ana) parinte(ion vasile) parinte(ana mihai) parinte(ana rodica) stramos(X Y) - parinte(X Z) stramos( Z Y)Să presupunem că se pune următoare icircntrebare-stramos(maria ana)

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 45: Tutorial Prolog

CuprinsBACK NEXT

PROLOG va icircncerca să răspundă căutacircnd icircn spaţiul stărilor descris de arbore următor stramos(maria ana) Xmaria Yana parinte(maria Z) stramos(Z ana)

parinte(maria Z) Zion stramos(ion ana) Xion Yana parinte(ion Z) stramos(Z ana)

parinte(ion Z) Zana Zvasile stramos(ana ana) stramos(vasile ana) Xana Yana Xana Yana parinte(ana Z) stramos(Z ana) parinte(vasile Z) stramos(Z ana)

parinte(ana Z) parinte(vasile _) Zmihai Zrodica no stramos(mihai ana) stramos(rodica ana) Xana Yana Xana Yanaparinte(mihai Z) stramos(Z ana) parinte(rodica Z) stramos(Z ana)

parinte(mihai_) parinte(rodica_)

no no

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 46: Tutorial Prolog

CuprinsBACK NEXT

PROLOG nu reuşeşte să termine corect căutarea icircn spaţiul stărilor problemei deoarece recurenţanu are o condiţie de oprire Oprirea programului este provocată de terminarea parcurgerii arborelui de familie sau de limitările echipamentului pe care lucrează versiunea de PROLOG icircn cauză dacă arborele este foarte adacircnc Aşadar ne trebuie o metodă care garantează terminarea execuţiei unei proceduri recursive date O astfel de metodă poate fi implementată folosind o clauză care enunţă condiţiile de margine icircn care o relaţie este validă Icircn exemplul nostru această condiţie este relaţia ldquopărinterdquo care are sensul că o relaţie de strămoşrdquo icircntre două persoane este valabilă la margine cacircnd una dintre persoane este părintele celeilalte De aceea trebuie să adăugăm icircn baza de reguli o clauză Noul program estedomains persoana = symbolpredicates parinte(persoana persoana) stramos(persoana persoana)clauses parinte(maria ion) 1 parinte(ion ana) 2 parinte(ion vasile) 3 parinte(ana mihai) 4 parinte(ana rodica) 5 stramos(X Y) - parinte(X Y) 6 stramos(X Y) - parinte(X Z) stramos( Z Y) 7Clauza 6 acţionează ca o condiţie de frontieră a relaţiei definite Icircn general pentru rezolvarea recursivă a unei probleme icircmpărţim problema icircn două subgrupe Prima subgrupă conţine instanţa ldquosimplărdquo a problemei (limita recurenţei) A doua problemă conţine instanţele ldquogeneralerdquo ale problemei ale căror soluţii se găsesc reducacircndu-le la versiuni mai simple ale problemei (recurenţă)

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 47: Tutorial Prolog

CuprinsBACK NEXT

Considerăm util să icircncheiem acest capitol cu paragraf de concluzii Toate clauzele care se referă la acelaşi nume de predicat trebuie grupate Ordinea clauzelor icircn cadrul aceluiaşi grup influenţează modul de execuţie deoarece ele sunt inspectate icircn vederea resatisfacerii icircn ordinea icircn care sunt trecute Ordinea icircn care sunt aşezate grupurile de clauze nu prezintă importanţă Procedeul prin care PROLOG realizează satisfacerea clauzelor este unificarea Icircn 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ă tehnica backtrackingului Forţarea backtrackingului se face predicatul fail Procesul de resatisfacere prin backtracking poate fi oprit cu ajutorul tăieturii Negaţia icircn PROLOG poate fi exprimată utilizacircnd o combinaţie tăietură-eşuare (fail) sau utilizacircnd predicatul not Clauza not(p(arg1 arg2hellip argn)) este satisfăcută dacă şi numai dacăclauza p(arg1 arg2hellip argn) nu se poate satisface PROLOG admite recursivitatea icircn sensul că acelaşi nume de predicat poate apare şi icircn capul unei reguli şi icircn corpul ei Icircn situaţia icircn care se utilizează definiţii recursive este necesar să se definească condiţii de margine (condiţii de oprire a apelurilor recursive)

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 48: Tutorial Prolog

CuprinsBACK NEXT

Operatii de intrareiesire

Exista doua stiluri de operare cu date de intrareiesire in Prolog stilul Edinburg este depasit dar inca suporta de unele implementari Prolog Este relativ simplu de folosit dar are limitari intrareiesire ISO este standardul suportat de toate implementarile Prolog Stilul EdinburgScrierea termenilorPredicacul predefinit write ia orice termen Prolog si il afiseaza pe ecran Predicatul nl muta ldquocursorulrdquo la o linie noua- write (Hello_ther e ) nl write(Goodbye)Hello thereGoodbyetrueDe notat ca atomii care sunt ciati sunt afisati fara ghilimele (simple) Varianta writeq a lui write va afisa si ghilimelele

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 49: Tutorial Prolog

CuprinsBACK NEXT

Citirea termenilorPredicatul read accepta orice termen Prolog scris la tastaturaPredicatul read este satisfacut daca argumentul sau poate fi unificat cu un termen dat de utilizatorExemplele anterioare ilustreaza mai multe situatii de folosireLucrul cu fisierePredicatul see ia ca argument un fisier efectul sau este sa deschida fisierul pentru citire astfel ca Prolog sa ia date de intrare din fisier nu de la consola Preducatul seen inchide toate fisierele deschise datele de intrare provin din nou de la consola- see(myfiletxt)read(X)read(Y)read(Z)seenCand un fisier este deschis Prolog va retine pozitia ldquocursoruluirdquo in acel fisierPredicatul tell deschide un fisier pentru scriere si comuta iesirea la acestaPredicatul Told inchide toate fisierele deschise pentru scriere si comuta iesirea la consolaIntrareiesire la nivel de caracterePredicatul put scrie un caracter-put(42)truePredicatul get citeste un caracter de la intrarea implicita- get(X)| X=37

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50
Page 50: Tutorial Prolog

CuprinsBACK NEXT

Standard ISOStreamuriStandardul ISO pentru intrareiesire din Prolog considera notiunea de streamSunt disponibile predicate pentrudeschiderea si inchiderea streamurilor in diferite moduriinspectarea starii unui stream precum si a altor informatii scriereacitirea se face in streamuriExista doua streamuri permanent deschise user_imput si user_output corespunzand intrarii si iesirii la consolaDeschiderea streamurilorPredicatul open(Filename Mode Stream Obtions) deschide un streamInchiderea streamurilorPredicatul close(Stream Obtions) inchide Stream cu obtiunile Obtion close(Stream) este versiunea fara obtiuniObtiunile include force(false) (implicit) si force(true) chiar daca exista o eroare fisierul se considera inchis fara sa ridice o eroareProprietati ale streamurilorPredicatul stream_property(Stream Property) poate fi folosit pentru detectarea proprietatilorCitirea termenilorread_term(Stream Term Obtions)read_term(Term Obtions)read(Stream Term)read(Term)Scrierea termenilorwrite_term(Stream Term Obtions)write_term(Term Obtions)write(Stream Term)Write(term)

  • TUTORIAL PROLOG
  • CUPRINS
  • Scurt istoric
  • Procurare Prolog
  • INTRODUCERE
  • Slide 7
  • Deosebiri intre programarea logica si clasica
  • Slide 9
  • Slide 10
  • Slide 11
  • CUM UTILIZAM PROLOG
  • Structura unui program in prolog
  • Slide 14
  • Slide 15
  • Slide 16
  • Slide 17
  • Slide 18
  • Un exemplu de program in Prolog
  • Interogarea Prologului
  • Slide 21
  • Slide 22
  • Slide 23
  • Slide 24
  • Slide 25
  • Slide 26
  • Satisfacerea clauzelor in Prolog (Backtracking)
  • Slide 28
  • Sintaxa limbajului Prolog
  • Slide 30
  • Slide 31
  • Slide 32
  • Slide 33
  • Slide 34
  • Slide 35
  • Controlul procesului de Backtracking
  • Slide 37
  • Slide 38
  • Slide 39
  • LISTE
  • Slide 41
  • Recursivitatea in Prolog
  • Slide 43
  • Slide 44
  • Slide 45
  • Slide 46
  • Slide 47
  • Operatii de intrareiesire
  • Slide 49
  • Slide 50