Lucrarea nr. 9




Cuprins:

  1. Manipularea bazei de cunostinte
  2. Gasirea tuturor solutiilor la o intrebare

1. Manipularea bazei de cunostinte



Pentru a demonstra o anumita tinta, Prologul se foloseste de clauzele din baza sa de cunostinte. Baza de cunostinte este formata din predicatele predefinite, din predicatele definite de programator in mod static (cele compilate) si, in plus, din clauze care se adauga in mod dinamic in timpul executiei unei tinte.

Clauzele se adauga in baza de cunostinte cu predicatele assert_, si se sterg cu retract.
De exemplu:

    ?- crisis.
    No
    ?- assert(crisis).
    Yes
    ?- crisis.
    Yes
    ?- retract(crisis).
    Yes
    ?- crisis.
    No

Predicatele assert(Clause) si assertz(Clause) adauga clauza la sfirsit, iar asserta(Clause) la inceput. Predicatul retract(Clause) cauta prima clauza din baza de date care se potriveste cu Clause, unifica cele doua clauze, dupa clauza gasita este stearsa din baza de date.

Daca vrem sa accesam o anumita clauza, fara a o sterge, putem folosi predicatul clause(Head,Body). De exemplu, daca avem in baza de cunostinte doua clauze:

 apartine(H,[H|_]).
 apartine(H,[_|T]):-apartine(H,T).

si intrebam

 ?- clause(apartine(X,Y), Body).
 X = _G349
 Y = [_G349|_G490]
 Body = true ;

 X = _G349
 Y = [_G492|_G493]
 Body = apartine(_G349, _G493)

Pentru a elimina warning-ul dat de Prolog, cand se face un apel la un predicat dinamic care nu are inca nici o clauza, putem declara predicatul respectiv ca dinamic:

 :- dynamic(Pred/Arity).

Probleme:

  1. Pentru a salva intr-un fisier clauzele unui predicat intr-un fisier putem defini predicatul save_pred(Pred,File) sub forma:

  2.     save_pred(Pred,File) :- tell(File),
                                listing(Pred),
                                told.

    Dezavantajul acestei implementari este ca toate cele trei predicate folosite sint nestandard. Definiti predicatul save_pred cu ajutorul predicatelor I/O descrise in lucrarea anterioara si cu predicatele descrise in aceasta lucrare.
     
     

  3. Sa se scrie un 'program' care gestioneaza o baza de date formata din axiome 'parinte(Parinte,Copil)'. Se implementeaza urmatoarele functii:
    1.  + adaugare axioma
    2.  + stergere axiome pentru un Parinte sau Copil dat
    3.  + afisare (pentru Parinte sau Copil)
    4.  + salvare/incarcare
  4. Consideram un arbore SI/SAU descris prin clauze Prolog de forma:

  5.     a :- b , c.
        b :- d ; e.
        c :- e ; f ; g.
        f :- h.

    Sa se definesca un predicat care afiseaza frunzele unui nod dat ca intrare (prin frunze intelegandu-se noduri fara fii).
    De exemplu:

        ?- expand_to_leaf(a,T).
        T = (d;e),(e;h;g)
        Yes

    Daca in timpul cautarii frunzelor apare un ciclu, acesta sa fie semnalat, dupa care predicatul esuaza.
     


  2. Gasirea tuturor solutiilor la o intrebare



Cu ajutorul backtracking-ului putem genera solutiile la o anumita tinta. In momentul in care o solutie este disponibila, restul solutiilor sunt necunoscute. In unele situatii, avem nevoie de toate solutiile la tinta in cauza. Pentru aceasta Prologul pune la dispozitia programatorului predicatele findall si bagof.

findall(Term,Goal,List)
    gaseste toate solutiile la Goal; leaga variabilele in Term cu valoriile din Goal, formand o lista cu instantele lui Term

Exemplu:
    green(kermit).
    green(crabgrass).

    ?- findall(X, green(X), L).
    X = _G313, L = [kermit, crabgrass]

    ?- findall(f(X),green(X),L).
    X = _G679, L = [f(kermit), f(crabgrass)]
 

bagof(Term,Goal,List)
    ca si findall, cu diferenta in modul de tratatare a variabilelor libere din Goal ce nu apar in Term

Exemplu:
    parent( pam, bob).
    parent( tom, bob).
    parent( tom, john).
    parent( bob, pat).

    ?- bagof(X,parent(X,Y),L).
    X = _G1132, Y = bob, L = [pam, tom] ;
    X = _G1132, Y = john, L = [tom] ;
    X = _G1132, Y = pat, L = [bob]

    ?- findall(X,parent(X,Y),L).
    X = _G697, Y = _G698, L = [pam, tom, tom, bob]
 

Problema: Sa se defineasca un predicat powerset(Set,SubSet), care determina multimea tuturor submultimilor unei multimi.