Sisteme Expert

Model test recapitulativ Prolog

Pentru a va pregati puteti incerca sa faceti din exercitiile de mai jos si apoi sa mi le trimiteti pe mail sa le corectez. Sunt 5 exercitii: primul e cu parcurgere/generare de liste si matrici, al doilea cu predicatele bagof/setof/findall, al treilea e cu operatori sau predicate dinamice (sau ambele), al patrulea este cu citire/scriere in fisier (eventual si ceva cu un predicat dinamic), al cincilea e cu biblioteci.

  1. Exercitii de completat (inlocuiti toate comentariile cu secventa de cod corespunzatoare):
    • Sa se construiasca un predicat care genereaza pe rand ca solutii literele mici dintre alte doua litere mici date. Se vor testa datele de intrare. Forma predicatului va fi: interval_litere(+Lit1,+Lit2,-Lit) | ?- interval_litere(2,f,X).
      no
      | ?- interval_litere(z,f,X).
      no
      | ?- interval_litere(a,f,X).
      X = a ? ;
      X = b ? ;
      X = c ? ;
      X = d ? ;
      X = e ? ;
      X = f ? ;
      no
      | ?-
      interval_litere(Lit1,Lit2,Lit):-test_date(Lit1,Lit2), name(Lit1,[N1]), name(Lit2,[N2]), interval_l(N1,N2,N),name(/* ? */,[N]).

      test_date(Lit1,Lit2):-e_litera_mica(Lit1),e_litera_mica(Lit2), Lit1 /* ? */Lit2.

      e_litera_mica(Lit):- atom(Lit),atom_length(Lit,/* ? */), 'a' @=< Lit, Lit @=< /* ? */.

      interval_l(A,B,A):- A=<B.
      interval_l(A,B,X):- A<B, /* ? */, interval_l(A1,B,X).

    • Se parcurge o lista de structuri de tip student. De exemplu: [student(doru, popescu), student(tache, ionescu), student(gogu, popescu), student(bogdan, georgescu), student(liliana, ionescu), student(vasile, popescu)] Sa se scrie un predicat care primeste un nume de familie si returneaza lista prenumelor studentilor cu acel nume de familie. | ?- lista_prenume(popescu,[student(doru, popescu), student(tache, ionescu), student(gogu, popescu), student(bogdan, georgescu), student(liliana, ionescu), student(vasile, popescu)],L).
      L = [doru,gogu,vasile] ?
      yes
      | ?-
      lista_prenume(Nume, [student(P,N)|T],Lrez):- lista_prenume(Nume, T,Trez) , (Nume==N -> /* ? */; /* ? */).
      /*pas de oprire*/
    • Sa se calculeze suma numerelor cu modul mai mic decat N dintr-o matrice de numere data. | ?- sum_mat_nume(m4,10,Sum).
      Sum = 41 ?
      yes
      | ?-
      matrice(m4,
          [[12,10,7,3],
          [-8,100,1,4],
          [9,9,10,11]]
      ).

      sum_mat_nume(Nume,N,Sum):-/*preiau matricea asociata numelui*/,sum_mat(Mat,N,Sum).
      sum_mat([Linie|T],N,Sum):-sum_linie(Linie,N,SumLin),sum_mat(T,N,SumT), Sum is /* ? */.
      /*pas oprire sum_mat */ sum_linie([H|T],N,Sum):- sum_linie(T,N,SumT), ( /* ? */ < /* ? */ -> Sum is /* ? */; Sum is /* ? */).
      /*pas oprire sum_linie */
    • Sa se ordoneze folosind setof o lista de sume dupa rezultatul lor. De exemplu [2+7,7+1,6+2,1+10,3+2]. | ?- ordoneaza_sume([2+7,7+1,6+2,1+10,3+2],L).
      L = [3+2,6+2,7+1,2+7,1+10] ?
      yes
      | ?-
      ordoneaza_sume(L,Lord):-setof(st(R,Sum), L^(member(Sum,L), /* ? */), Laux), findall(Sum, member(/* ? */,Laux),Lord).

  2. Exercitiu cu liste:
    • (parcurgere lista)Sa se scrie un predicat care parcurge o lista de numere si afiseaza fiecare set de numere vecine in lista intre paranteze drepte si pe linii diferite. De exemplu, pentru lista [1,a,b,7,4,5,2,3,z,z,7,1] va afisa:
      [1]
      [7,4,5,2,3]
      [7,1]
    • (parcurgere + generare lista)Sa se scrie un predicat care parcurge o lista de numere si pentru fiecare numar intalnit pune intr-o lista-rezultat cifrele reprezentarii lui in baza doi. De exemplu pentru lista [1,4,3] lista rezultat va fi: [1,1,0,0,1,1] (1 - 1 ; 4 - 1,0,0 ; 3 - 1,1):
    • (lista de liste)Sa se scrie un predicat care primeste un numar natural N si un numar natural K si genereaza lista tuturor listelor de lungime K de numere naturale cu proprietatea ca suma elementelor lor este N. Atentie, fara grupuri duplicate (adica grupuri cu aceleasi numere dar eventual puse in alta ordine): daca avem o lista [M,N,P] nu avem si lista [N,P,M] de exemplu.
    • (matrice)Sa se scrie un predicat care primeste un numar de linie si un numar de coloana si interschimba linia cu coloana respectiva (elementul de intersectie va avea forma elem_coloana/elem_linie). Exemplu:
      a b c d
      e f g h
      i j k l
      m n o p

      Interschimbam linia 2 cu coloana 1.

      a i c d
      e j g h
      b f/k j n
      m l o p
  3. Exercitiu cu bagof/setof/findall:
    %dans(nume_dans, lista_perechi)
    %lista perechi: [ [nume_baiat, nume_fata], .....]
    dans(tango,[[ion, andreea],[marin, ana],[doru, elena]]).
    dans(vals,[[mihai, elena],[ion, oana],[daniel, carmen], [doru, andreea], [marin, ana]]).
    dans(quickstep, [[ion, andreea],[marin,carmen]]).
    dans(jive,[[marin, ana], [doru, elena],[daniel, oana],[ion, andreea]]).
    dans(pasodoble,[[marin, elena]]).
    dans(vals_vienez,[[daniel, carmen],[doru,oana]]).
    Se considera ca un dansator e identificat unic prin nume.
    1. Sa se adauge inca un dans la baza de cunostinte, respectand formatul (se va scrie direct in fisier, nu se va adauga dinamic). Fara a folosi unul din predicatele predefinite care construiesc liste, afisati dansurile pe ecran, cate unul pe linie, in ordinea in care apar in baza de cunostinte.
    2. Sa se returneze lista dansurilor in ordinea numarului de perechi inscrise la proba respectiva.
    3. Sa se scrie un predicat care returneaza numele dansatorului (baiat sau fata) care a participat la numarul cel mai mare de dansuri.
    4. Sa se scrie un predicat cu 2 parametri de iesire (un nume de baiat si o lista de nume de fete), care returneaza pe rand (solutii multiple) fiecare baiat cu lista numelor fetelor cu care a dansat (indiferent de dans)
    5. Se se scrie un predicat care calculeaza lista numelor baietilor din baza de cunostinte, lista numelor fetelor din baza de cunostinte, si genereaza si o matrice dupa cum urmeaza. Fiecare linie a matricei va corespunde unui baiat (in ordinea in care apar baietii in lista corespunzatoare lor), si fiecare coloana unei fete (de asemenea coloanele vor corespunde fetelor in ordinea in care apar acestea in lista lor). Un element al matricii va reprezenta de cate ori au dansat impreuna un baiat si o fata conform datelor din baza de cunostinte.
      pred(-ListaBaieti,-ListaFete,-Matrice)
  4. Exercitiu cu operatori. Sa se defineasca operatorii necesari pentru ca toate combinatiile de interogari (precum cele de mai jos) cu sume intre litri (l) si mililitri (ml) (nu si alte unitati de masura) sa fie posibile. Rezultatele trebuie sa fie date astfel incat numarul de ml sa fie mai mic decat 1000. In caz ca e mai mare, trebuie transformat in litri si restul ramas va reprezenta numarul de ml. Atentie, nu e obligatoriu ca operanzii dati ca intrare sa aiba numarul de ml mai mic decat 1000 (de exemplu puteti avea 5 l si 2402 ml) dar rezultatul trebuie intotdeauna sa respecte regula.
    | ?- Z este 1 l si 504 ml + 2 l si 600 ml.
    Z = 4 l si 104 ml ?
    | ?- Z este 3 l si 27 ml + 10 ml.
    Z = 3 l si 37 ml ?
    | ?- Z este 3 l + 5 l.
    Z = 8 l ?
    | ?- Z este 2 l + 8 ml.
    Z = 2 l si 8 ml ?
    | ?- Z este 502 ml + 1503 ml.
    Z = 2 l si 5 ml ?
    Atentie, trebuie sa mearga orice combinatie de operanzi de forma X l, X ml, X l si Y ml. In cazul in care in rezultat avem un caz de forma 0 unitati de masura, aceasta nu se mai specifica decat daca e singur in expresie. De exemplu 5 l si 0 ml va fi afisat doar ca 5 l. Insa daca avem doar 0 l ramane 0 l.
  5. Exercitiu cu fisiere. Se considera un fisier cu cateva cuvinte cu punct la sfarsit, ca in exemplul:
    abc.
    bau.
    ana.
    bobo.
    cip.
    cip.
    ham.
    miau.
    arici.
    copil.
    Sa se scrie un predicat cu 4 parametri. Primul parametru e numele unui fisier de intrare (care va fi un fisier conform exemplului dat). Al doilea parametru e o litera. Datele de intrare se considera corecte. Predicatul va calcula in al 3-lea parametru lista cuvintelor din fisier care incep cu litera respectiva . In al 4 le-a parametru se va calcula numarul total al cuvintelor care contin acea litera (deci nu doar numarul celor care incep cu acea litera).
    pred(+FisIn,+Litera,-ListCuv,-NrCuvLitera)
  6. Exercitiu cu biblioteci. Sa se scrie un predicat care primeste ca paramteru un nume de director si redenumeste toate fisierele din acel director cu numele lor anterior concatenat cu data curenta (deci cu un sir de forma: an_luna_zi_ora_minut_secunde). Predicatul va avea forma pred(+Director)