Lucrarea nr. 5
Obiecte recursive. Liste





O lista poate fi vazuta ca un obiect recursiv cu doua componente: capul listei si coada (restul) listei, care la randul ei este o lista. Prologul are un functor special pentru construirea listelor si anume simbolul '.'. Astfel, o lista formata din elementele 1, 2 si 3 poate fi scrisa sub forma:

    .(1, .(2, .(3, [])))

Din exemplul de mai sus se poate observa ca lista vida se noteaza prin atomul []. Exista si o notatie mai simpla a listelor, cu ajutorul parantezelor drepte. In aceasta notatie o lista are forma:

    [E1, E2, ..., En | Tail]

Elementele listei sunt despartite prin virgula, si poate aparea optional la sfirsit simbolul '|' urmat de specificarea cozii listei. Poate fi cel mult un singur '|' in
specificarea listei, nici o virgula dupa acest simbol nefiind permisa la acest nivel.

Exemple de liste:

    [a]       == .(a, [])
    [a,b]     == .(a, .(b, []))
    [X,a|T]   == .(X, .(a, T))
    [a|[b,c]] == .(a, .(b, .(c, [])))

Atunci cand un predicat primeste ca argument o lista, de obicei el opereaza asupra capului listei, restul listei rezolvindu-se printr-un apel recursiv. De exemplu, predicatul care testeaza apartenenta unui element la o lista poate fi scris sub forma:

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

Probleme:

  1. Sa se defineasca un predicat, care testeaza daca argumentul dat este o lista.
  2. Sa se defineasca predicatul de concatenare a doua liste.
  3. Sa se defineasca predicatul de inserare intr-o lista. Predicatul trebuie sa genereze toate posibilitatile de inserare a elementului in lista. De exemplu:

  4.     ?-ins(1,[2,3],L).
        L=[1,2,3];
        L=[2,1,3];
        L=[2,3,1]
     
  5. Sa se defineasca predicatul de stergere dintr-o lista. Predicatul trebuie implementat in trei variante:

  6.         - sterge prima aparitie;
                del(1,[1,2,1],L) => L=[2,1]
            - sterge o aparitie;
                del(1,[1,2,1],L) => L=[2,1]; L=[1,2] /* toate variantele */
            - sterge toate aparitiile
                del(1,[1,2,1],L) => L=[2]
     
  7. Folosind predicatul de concatenare, sa se defineasca un predicat prin care se sterg ultimele trei elemente din lista.
  8. Folosind predicatul de concatenare, sa se defineasca predicatul care testeaza daca o lista este sublista unei altei liste (data ca argument).
  9. Sa se defineasca predicatul care inverseaza o lista.
  10. Sa se defineasca predicatul de generare a permutarilor elementelor din lista.
  11. Sa se defineasca predicatul de sortare prin insertie.