Sunteți pe pagina 1din 8

Lab. 2, pag.

Structura unui program VISUAL PROLOG


Un program PROLOG conine 4 seciuni de baz: clauses predicates domains goal Seciunea clauses conine faptele i regulile cu care va opera PROLOG pentru satisfacerea interogrilor. Seciunea predicates este seciunea n care se declar predicatele i domeniile (tipurile) argumentelor. Seciunea domains cuprinde declarea domeniilor (tipurilor) utilizate n program i care nu sunt domenii standard. Seciunea goal este seciunea n care se fac interogrile. Seciunea CLAUSES Clauzele (faptele i regulile) pentru un predicat trebuie amplasate mpreun n seciunea CLAUSES. O secven de fapte i reguli care definesc un predicat poart numele de procedur. Atunci cnd rspunde la o interogare, Visual Prolog va ncepe cu nceputul seciunii, clauses cutnd o potrivire cu toate faptele i regulile din aceast seciune. Seciunea PREDICATES Atunci cnd se definete un predicat n seciunea clauses a unui program Visual Prolog, trebuie n prealabil declarat n seciunea predicates prin care se comunic programului Visual Prolog despre ce este vorba. Exist i predicate predefinite n Visual Prolog care nu trebuie redeclarate. De asemenea vor trebui precizate domeniile argumentelor predicatului. Declararea unui predicat se face dup sintaxa: nume_predicat(tip_argument1, tip_argument2, ... ) Domeniile utilizate n declararea unui argument sunt fie domenii standard, fie domenii care au fost declarate n seciunea DOMAINS. Numele predicatelor trebuie s nceap cu liter, urmat apoi de o secven de litere, cifre i eventual caracterul _ underscore. Nu are importan dac literele utilizate sunt litere mari sau mici dar este recomandabil ca prima liter s fie liter mic, deoarece alte versiuni ale limbajului Prolog nu accept literele mari ca prim liter n numele unui predicat. Numele unui predicat nu poate depi 250 de caractere. Exemple de nume de predicate: Nume corecte de predicate fact este_un are_o listaDeVerificare choose_Menu_Item predicateName Nume incorecte de predicate [fact] *este_un* are/o lista-De-Verificare choose Menu Item predicate<Name>

Exemple Se poate declara un predicat cu denumirea my_predicate(symbol, integer)n seciunea predicates: PREDICATES my_predicate(symbol, integer)

Lab. 2, pag. 2 pentru care nu este necesar declararea domeniilor argumentelor n seciunea domains deoarece symbol i integer sunt domenii standard. Dac ns se declar predicatul my_predicate(name, number) n seciunea predicates: PREDICATES my_predicate(name, number) va fi necesar o declaraie pentru cele dou domenii name i number care nu sunt domenii standard. Presupunnd c se dorete ca aceste domenii s corespund domeniilor standard symbol i integer, seciunea declarrii domeniilor va fi: DOMAINS name = symbol number = integer PREDICATES my_predicate(name, number) Urmtoarea seciune de program prezint mai multe astfel de declaraii de predicate i de domenii: DOMAINS persoana, activitate = symbol masina, marca, culoare = symbol kilometri, vechime, pret = integer PREDICATES place(persoana, activitate) parinte(persoana, persoana) poate_cumpara(persoana, masina) masina(marca, kilometri, vechime, culoare, pret) verde(symbol) clasifica(symbol, integer) Aceast seciune de program specific urmtoarele informaii despre predicate i despre argumentele lor: Predicatul place are dou argumente (persoana i activitate), ambele aparinnd domeniului symbol (ceea ce nseamn c valorile lor sunt alfanumerice) Predicatul parinte are dou argumente de tip persoana, unde domeniul persoana este de tip symbol. Predicatul poate_cumpara are dou argumente persoana i masina, care sunt ambele de tip symbol. Predicatul masina are 5 argumente marca i culoare aparin domeniului symbol, n timp ce kilometri, vechime i cost aparin domeniului integer. Predicatul clasifica, are dou argumente, ambele aparinnd domeniilor standard symbol i integer, astfel nct nu mai este necesar declararea tipului acestora n seciunea domains. Seciunea DOMAINS n Visual Prolog se declar care sunt domeniile (tipurile) argumentelor predicatelor. Seciunea domains permite utilizarea de nume distincte pentru diferitele tipuri de date care sunt de fapt de acelai tip. ntr-un program Prolog obiectele dintr-o relaie (argumentele unui predicat) aparin unor domenii. Exist domenii predefinite sau domenii definite de utilizatori. Seciunea domains este util n dou scopuri. n primul rnd se poate da un sens, un neles numelui unui domeniu, chiar dac din punct de vedere al reprezentrii interne este acelai cu un domeniu care exist deja. n al doilea rnd declararea domeniilor ne permite declararea structurilor de date care nu sunt definite de ctre domeniile standard.

Lab. 2, pag. 3
Uneori este util s se declare un domeniu atunci cnd se dorete clarificarea unei poriuni din seciunea predicates. Prin declararea unui domeniu propriu, cu un nume personalizat, mai uor i mai simplu se pot da nume sugestive ale argumentelor predicatului respectiv.

Exemple Urmtorul exemplu ilustreaz modul n care declararea unui domeniu ajut la declararea unui predicat: Paul este un brbat care are 45 de ani. Utiliznd domeniile predefinite, se poate face urmtoarea declaraie de predicat: persoana(symbol, symbol, integer) Aceast declaraie este corect i servete celor mai multor scopuri, ns argumentele sale nu au o denumire sugestiv, astfel c, dac peste o perioad de timp, se dorete o actualizare a codului respectiv, programatorul care efectueaz modificrile de cod nu mai tie ce semnificaie a dat argumentelor predicatului respectiv. n schimb, dac se face o declarare prealabil a domeniilor, folosind denumiri sugestive, acest dezavantaj este eliminat:\ DOMAINS nume, sex = symbol varsta = integer PREDICATES persoana(nume, sex, varsta) Unul dintre principalele avantaje ale acestor declaraii este acela c Visual Prolog poate intercepta erorile, cum sunt n exemplul urmtor: acelasi_sex(X, Y) :persoana(X, Sex, _), persoana(Sex, Y, _). Cu toate c domeniile nume i sex sunt definite ambele ca symbol, ele nu sunt echivalente. Prin utilizarea declaraiilor de domenii Visual Prolog detecteaz situaiile n care ele sunt utilizate greit, ca n exemplul anterior n care s-au inversat. Se pune problema dac este recomandabil s se utilizeze astfel de declaraii de domenii ntotdeauna. Rspunsul se poate deduce din urmtoarea observaie: odat ce un argument este declarat ca aparinnd unui domeniu specific, acel domeniu nu va putea fi nlocuit cu al domeniu care are alt nume, chiar dac el este de fapt acelai domeniu. Astfel, chiar dac nume i sex aparin aceluiai domeniu (symbol), ele nu pot fi inversate. Totui, domeniile standard se pot utiliza n locul domeniilor definite de utilizatori. Urmtorul exemplu produce o eroare de incompatibilitate de tip la execuie: DOMAINS produs,suma = integer PREDICATES adunare(suma,suma,suma) inmultire(produs,produs,produs) CLAUSES adunare(X,Y,Suma):Suma=X+Y. inmultire(X,Y,Produs):Produs=X*Y. Acest program face dou operaii: adun i nmulete. Dac se specific urmtorul goal (obiectiv)):

Lab. 2, pag. 4 adunare(32, 54, Suma). Visual Prolog va da soluia: Suma=86 1 Solution care este corect. De asemenea, pentru a testa operaia de nmulire, vom utiliza urmtorul goal: inmultire(31, 13, Produs). Soluia corect, dat de Visual Prolog va fi: Produs=403 1 Solution S presupunem c avem nevoie s dublm produsul dintre 31 i 17, astfel c vom utiliza urmtorul goal: inmultire(31, 17, Suma), adunare(Suma, Suma, Rezultat). Ne ateptm s obinem urmtorul rezultat: Suma=527, Rezultat=1054 1 Solution Dar, n realitate vom obine o eroare de incompatibilitate de tip. Ceea ce se ntmpl n realitate este c se ncearc pasarea rezultatului valorii inmultire(31, 17, Suma), ctre predicatul adunare, att ca prim argument, ct i ca al doilea argument. Predicatul adunare are ns domeniul suma pentru ambele argumente, fapt ce va genera o eroare deoarece domeniul produs este diferit de domeniul suma, chiar dac ambele reprezint n realitate integer. Astfel, dac o variabil va fi utilizat n mai multe predicate, n interiorul unei clauze, el trebuie declarat acelai n fiecare predicat. Pentru o mai bun nelegere privitoare la incompatibilitile de tip, considerm urmtorul exemplu de program: DOMAINS marca,culoare = symbol vechime = byte pret, kilometri = ulong PREDICATES nondeterm masina(marca,kilometri,vechime,culoare,pret) CLAUSES masina(mercedes,130000,3,rosu,12000). masina(ford,90000,4,gri,25000). masina(cielo,8000,1,negru,30000). n acest exemplu, predicatul masina declarat n seciunea predicates are 5 argumente. Un argument aparine domeniului vechime care este de tip byte. Tipul byte este reprezentat ca ntreg fr semn pe 8 bii i poate lua valori de la 0 la 255 inclusiv. La fel, domeniile kilometri i pret sunt de tipul ulong, care se reprezint intern ca ntreg fr semn pe 32 de bii. Domeniile marca i culoare sunt de tip symbol. Se poate testa predicatul maina cu urmtoarele interogri (goal): masina(renault, 13, 40000, rosu, 12000). masina(ford, 90000, gri, 4, 25000). masina(1, rosu, 30000, 80000, cielo). Toate cele 3 interogri produc erori de domeniu. n prima situaie eroarea apare deoarece argumentul vechime trebuie s fie de tip byte. In al doilea caz s-au interschimbat vechimea i culoarea, iar n al treilea caz s-au interschimbat mai multe argumente.

Lab. 2, pag. 5 Seciunea GOAL n esen, aceast seciune este identic cu corpul unei reguli. Sunt 2 diferene ntre seciunea goal i o regul: cuvntul cheie goal nu este urmat de : - Visual Prolog execut automat interogarea (goal) cnd programul ruleaz. n timp ce programul ruleaz, se ncearc satisfacerea corpului regulii din seciunea Goal. Dac toate subobiectivele (subgoal-urile) din seciunea goal sunt terminate cu success i programul se ncheie cu success. Dac, n timp ce programul ruleaz, unul dintre subobiectivele dintr-un goal se termin cu eec, ntregul program se termin cu eec. Visual Prolog are cteva domenii standard: Domenii standard: short : -32768 32767 - ntreg scurt pe 16 bii, independent de platform; ushort : 0 65535 - ntreg scurt pe 16 bii fr semn, independent de platform; long : ntreg lung pe 32 bii, independent de platform; ulong : ntreg lung pe 32 bii fr semn, independent de platform; integer: ntreg cu semn avnd dimensiunea dependent de arhitectura calculatorului (16 sau 32 bii); unsigned: ntreg fr semn pe 16 sau 32 bii; byte : octet 0 255; word : 2 octei 0 65535; dword : 4 octei : ntreg pozitiv. Din punct de vedere sintactic, o valoare aparinnd unuia dintre domeniile ntregi standard este scris ca o secven de cifre precedate opional de un semn (-), fr spaii albe. Exist i sintaxe octale sau hexazecimale pentru domeniile ntregi. Se pot utiliza cuvintele cheie signed i unsigned n conjuncie cu byte, word i dword pentru a construi noi domenii ca n exemplul urmtor: DOMAINS i8 = signed byte unde se creeaz un nou domeniu ntreg avnd valorile ntre -128 i +127. Alte domenii standard sunt prezentate n continuare: char un caracter reprezentat pe un octet; real numrul real n virgul mobil reprezentat pe 8 octei n convenia IEEE, echivalentul tipului C double; string o secven de caractere n dou formate acceptate: 1. O secven de litere, numrul care ncepe cu liter mic; 2. O secven de caractere ntre ghilimele. symbol o secven de caractere cu aceeai sintax ca i la tipul string. Domeniile string i symbol sunt la fel, ns Visual Prolog le memoreaz diferit. Pentru symbol, Visual Prolog utilizeaz o tabel n care sunt reinute adresele lor, astfel c, dac ntr-un program se utilizeaz n mod repetat, el poate fi gsit foarte repede i este memorat mai compact. Pentru domeniul string nu este posibil utilizarea unei astfel de tabele i Visual Prolog va examina un string caracter cu caracter. Exemple de obiecte de diferite domenii: &&, maria, produs program, an_1_info symbol sau string -1, 3, 42, 5, 0, 25 integer 3, 45, 0.01, -30.0, 123.4e+5 real char a , b , / , $

Lab. 2, pag. 6 Declararea argumentelor n cadrul predicatelor Presupunem c avem urmtoarea relaie ntre obiecte: pavel este un brbat n vrst de 45 de ani. Faptele Prolog care corespund acestei relaii n limbaj natural sunt: persoana(pavel, brbat, 45) Pentru a declara predicatul persoana cu acest argument, se face urmtoarea declaraie n seciunea predicates persoana(symbol, symbol, byte) n aceast declaraie s-au folosit 3 argumente de tipuri (domenii) standard. Dac programul folosete numai argumente standard, nu este necesar seciunea domains. S presupunem c dorim s declarm un predicat care va furniza poziia unei litere n alfabet. Acest predicat ar putea fi: pozitie_alfabet(Litera, Pozitia) vom avea Pozitia = 1 dac Litera = a, Pozitia = 2 dac Litera = b i aa mai departe. Clauzele pentru acest predicat vor fi asemntoare cu urmtoarea clauz: pozitie_alfabet(Un_caracter, N). Clauzele pentru acest predicat vor fi: pozitie_alfabet('a', 1). pozitie_alfabet('b', 2). pozitie_alfabet('c', 3). ... pozitie_alfabet('z', 26). Se poate declara predicatul pozitie_alfabet astfel: PREDICATES pozitie_alfabet(char, unsigned) Se poate interoga acest program cu urmtoarele interogri: pozitie_alfabet('a', 1). pozitie_alfabet (X, 3). pozitie_alfabet ('z', Care). Aritate multipl Aritatea unui predicat este dat de numrul argumentelor sale. Pot exista dou predicate cu acelai nume, dar cu ariti diferite. Aceste predicate trebuie grupate mpreun n seciunile predicates i clauses. Exemplu: DOMAINS persoana = symbol PREDICATES tata(persoana) tata(persoana, persoana) CLAUSES tata(X): tata(X, _). tata(adam, paul). tata(ion, petre).

% Aceast persoan este un tat % O persoan este tata altei persoane

Lab. 2, pag. 7 Sintaxa unei reguli n Visual Prolog n Visual Prolog o regul se folosete atunci cnd un fapt depinde de un alt fapt sau grup de fapte. O regul are un antet i un corp cu urmtoarea sintax: HEAD: - <subgoal 1>, <subgoal 2>, ..., <subgoal n> Corpul unei reguli este format din unul sau mai multe subobiective (goal = obiectiv). Subobiectivele se separ prin virgul, specificnd conjuncia (operaia I). Fiecare subobiectiv este un apel la un alt predicat Prolog care se poate ncheia cu succes sau cu eec. Dac toate subobiectivele care alctuiesc coprul unei reguli se ncheie cu succes, atunci regula se ncheie cu succes, iar dac cel puin un subobiectiv eueaz, atunci i regula eueaz. Pentru a avea succes la o regul, Prolog trebuie s satisfac toate subobiectivele sale. Cnd un subobiectiv eueaz, Prolog se ntoarce napoi la subobiectivele anterioare, apoi continu cu valori schimbate ale variabilelor. Aceast tehnic este denumit backtracking. Simbolul IF n Prolog - se utilizeaz n loc de : - i se poate citi astfel: HEAD is true if BODY is true antetul este adevrat, dac corpul este adevrat. Semnificaia simbolului IF n Prolog difer de semnificaia aceluiai simbol din alte limbaje de programare, ca de exemplu Pascal sau C. n Pascal, condiia coninut n instruciunea IF trebuie pus naintea corpului instruciunii, cu alte cuvinte: "if HEAD is true, then BODY is true (sau: then do BODY)" Conversii automate de tip Cnd Prolog ncearc satisfacerea unui goal (obiectiv), de exemplu prin potrivirea a dou variabile, este necesar ca aceste variabile s aparin aceluiai domeniu. De asemenea, variabilele pot fi uneori legate cu constante aparinnd altor domenii. Acest lucru este posibil deoarece Visual Prolog face conversii de tip n mod automat (de la un domeniu la altul) n urmtoarele situaii: ntre string i symbol. ntre toate domeniile ntregi i real. La conversia unui caracter ntr-un ntreg acesta primete ca valoare codul s ASCII. Alte seciuni PROLOG Seciunea FACTS Un program Visual Prolog este o colecie de reguli i fapte. Uneori, n timp ce programul este n execuie, se poate dori o actualizare a unor fapte. n astfel de situaii faptele constituie o baz de date intern dinamic, care se poate schimba n timp ce programul se execut. Visual Prolog include o seciune special pentru declararea faptelor care sunt parte a bazei de date dinamice. Seciunea ncepe cu cuvntul cheie facts. Cuvntul facts este sinonim cu database. Seciunea Constants Se utilizeaz pentru declararea de constante simbolice n Visual Prolog. O constant simbolic se declar astfel: <identificator> = <macro definiie> Exemple: CONSTANTS

Lab. 2, pag. 8 zero = 0 pi = 3.1415927 Exist cteva restricii n utilizarea constantelor simbolice: Definirea unei constante nu poate face o referire la ea nsi. De exemplu: x = 2*x/2 /* nu este corect */ i va genera urmtorul mesaj de eroare: Recursion in constant definition. Sistemul nu face distincie ntre literele mari i literele mici ntr-o declaraie de constante. Totui trebuie evitat utilizarea literelor mari ca prim liter ntr-o seciune clauses pentru a nu se confunda cu variabilele, ca n exemplul urmtor: CONSTANTS Doi = 2 GOAL A=doi, write(A). Pot fi declarate mai multe constante ntr-un program, ns constantele trebuie declarate nainte de utilizarea lor. Declaraiile de constante devin effective din punctul n care sunt fcute i rmn valabile n orice fiier inclus dup declarare. Un identificator constant trebuie declarat o singur dat.