Sunteți pe pagina 1din 7

Lucrarea de laborator nr.

3
Scopul: Prelucrarea listelor n Prolog
PARTEA I: SUPORT TEORETIC
1. Despre liste
Lista reprezint unul dintre tipurile cele mai utilizate de structuri de date, att n Prolog, ct i n alte
limbaje simbolice. O list este o secven ordonat de obiecte de acelai tip. n PROLOG elementele
unei liste se separ ntre ele prin virgul i ntreaga secven este nchis ntre paranteze drepte.
Exemple:
[] lista vid
[X, Y, Y] list ale crei elemente sunt variabilele X, Y i Z
[[0, 2, 4], [1, 3]] list de liste de numere ntregi
Tipurile de liste utilizate ntr-un program PROLOG trebuie declarate n seciunea domains sub
forma:
tip_lista = tip*
unde tip este un tip standard sau definit de utilizator. O list este compus conceptul din dou pri:
cap (head), care desemneaz primul element din list;
rest (tail), care desemneaz lista elementelor rmase dup eliminarea primului element.
Restul unei liste se mai numete corpul sau coada unei liste, i este ntotdeauna o list. Exemplele
urmtoare ilustreaz modul n care se structureaz o list:

Lista
['a','b','c']
['a']
[]
[[1,2,3],[2,3,4],[]]

Cap
'a'
'a'
nedefinit
[1,2,3]

Coada
['b','c']
[]
nedefinit
[[2,3,4],[]]

Acest tip de mprire este utilizat n predicatele care prelucreaz liste folosindu-se de avantajul
regulii de unificare (identificare, substituire):
singurul termen care se identific cu [] este []

o lista de forma [H1|T1] se va identifica numai cu o lista de forma [H2|T2] daca H1 se


poate identifica cu H2 si T1 se poate identifica cu T2

Urmtorul tabel ilustreaz n cteva exemple aceast regul de unificare:


Lista1
[X,Y,Z]
[7]
[1,2,3,4]
[1,2]

Lista2
[Ion, Maria, Vasile]
[X,Y]
[X,Y|Z]
[3|X]

Legarea variabilelor
X=Ion, Y=Maria, Z=Vasile
X=7, Y=[]
X=1, Y=2, Z=[3,4]
esec

2. Exemple de utilizare
Aproape toate predicatele care utilizeaz liste sunt recursive i sunt definite pentru:
cazul de baz: lista vid []
cazul recursiv: pentru o lista de forma [H|T], efectueaz anumite aciuni
asupra capului H, apoi apeleaz predicatul recursiv cu coada T.
Folosind liste, putem acumula o serie de informaii ntr-un singur obiect
PROLOG. De exemplu faptele:
luna (1, ianuarie).
luna(2, februarie).
luna(3, martie).
luna(4, aprilie).
luna(5, mai).
luna(6, iunie).

pot fi redate folosind o singur list sub forma faptului:


luni_prima_jumatate_an([ianuarie, februarie, martie, aprilie, mai, iunie]).

Pentru comparaie considerm urmtoarele dou programe i cteva interogri asupra lor:
/* program_1 */
predicates
luna(integer,symbol)
afis
afis_p(integer)
afis_n(integer)
clauses
luna(1,ianuarie). luna(2, februarie). luna(3, martie).
luna(4, aprilie). luna(5, mai). luna(6, iunie).
afis:-luna(_,X),write(X),nl,fail.
afis.
afis_p(1):-luna(1,X), write(X),nl.
afis_p(N):-N1=N-1,afis_p(N1),N2=N1+1,luna(N2,X),write(X),nl.
afis_n(N):-luna(N, X), write(X),nl.

Goal: afis
ianuarie februarie martie aprilie mai iunie
yes
Goal: afis_p(1)
ianuarie
yes
Goal: afis_p(3)
ianuarie februarie martie
yes
Goal: afis_n(3)
Martie
yes
/* program_2 */
Domains
luni=symbol*
predicates
prima_jumat_an(luni)
clauses
prima_jumat_an([ianuarie,februarie,martie,aprilie,mai,iunie]).
Goal: prima_jumat_an(X)
X = [ianuarie, februarie, martie, aprilie, mai,iunie]
1 Solution
Goal: prima_jumat_an([X1, X2, X3, X4, X5, X6])
X1 = ianuarie, X2 = februarie, X3 = martie, X4 = aprilie, X5 = mai, X6 =
iunie
1 Solution
Goal: prima_jumat_an([X|Y])
X = ianuarie, Y = [ februarie, martie, aprilie, mai, iunie]
1 Solution
Goal: prima_jumatate_an([X|_])
X = ianuarie
1 Solution

Goal: prima_jumat_an([X,Y,Z| R])


X = ianuarie, Y = februarie, Z = martie, R = [aprilie,
mai, iunie]
1
Solution
Goal: prima_jumat_an([X,Y,Z |_])
X = ianuarie, Y = februarie, Z
=martie
1
Solution
Goal: prima umat_an([_,_,X|_])
X = martie
1
Solution

Dup cum se vede din exemplul de mai sus limbajul Prolog permite s se aleag nu doar primul
element al unei liste, ci mai multe. De asemenea, este permis s se lucreze cu liste n care
elementele nu au acelai tip.
n exemplul de mai jos obiectele de tip lista sunt liste ale cror elemente pot fi numere ntregi,
reale sau complexe.
domains
complex=z(real,real)
numar=r(real);i(integer);c(complex)
lista=numar*
predicates
p(lista)
clauses.
p([r(2.8),i(9),r(0.89),i(77),c(z(2,6))]).
Goal: p([X|Y])
X = r(2.8), Y = [i(9),r(0.89),i(77),c(z(2,6))]
1 Solution
Goal: p([X|_]) X = r(2.8)
1 Solution
Goal: p([X, i(9) |Y])
X = r(2.8), Y = [r(0.89),i(77),c(z(2,6))]
1 Solution
Goal: p([X, r(0.89) |Y])
No Solution

Partea II: Probleme propuse.


1. a) Liniarizarea listelor. Scrie predicatul liniar(ListaListe, Lista), unde ListaListe este o lista de
elemente care pot fi rndul lor liste, iar n Lista se construieste liniarizarea listei ListaListe.
Astfel,liniar([1, 2, [3, 4], [5, [6, 7], [[8], 9]]], L) va returna in L lista [1, 2, 3, 4, 5, 6, 7, 8, 9].
b) S se elimine primele N elemente de la nceputul unei liste. Numarul elementelor pentru
eliminare se va ntroduce utiliznd predicatul readln limbajului Prolog.

2. a) Scrieti un predicat descomp(N, Lista) care primeste un numar ntreg N si ntoarce o lista a
factorilor primi ai numarului N; de exemplu: descomp(12, [2, 2, 3]) este adevarat.
b) S se elimine ultimii N elemente a unei liste. Numarul elementelor pentru eliminare se va
ntroduce utiliznd predicatul readln limbajului Prolog.

3. a) Scrieti un predicat invers(Lista, ListaInversata) care inverseaza elementele unei liste; sa se


scrie doua variante ale predicatului de inversare a unei liste: o varianta n care lista inversata este
calculata pe ramura de revenire din recursivitate i o varianta n care lista inversata este calculata pe
ramura de avans n recursivitate.
b) Scriei un program care utilizeaz predicatul listaPara, care are dou argumente. Primul
argument este o list de numere ntregi, iar al doilea argument returneaz o list cu toate numerele
pare din prima list.

4. a) Scrieti un predicat palindrom(Lista) care verifica daca o lista este palindrom(Un palindrom este
o secventa care, daca este parcursa de la stnga la dreapta sau de la dreapta la stnga, este identica; de
exemplu: [a, b, c, b, a] sau [a, b, c, c, b, a].) Sa se modifice predicatul anterior astfel incit sa genereze
liste palindrom cu elemente 0 si 1.
b) S se scrie un program Prolog care s sorteze descresctor numerele unei liste.

5. a) Scrieti un predicat rotire(Lista, Directie, Nr, ListaRez) care roteste Lista cu un num_r de
Nr elemente la stnga (dac_ Directie = stg) sau la dreapta (dac_ Directie = dr), depunnd rezultatul n
ListaRez.
b) S se scrie un program Prolog care calculeaz i afieaz cel mai mare divizor comun al
tuturor numerelor dintr-o list.

6. a) Sa se scrie predicatul substitutie(X, Y, L1, L2), unde L2 este rezultatul substituirii tuturor
aparitiilor lui X din lista L1 cu Y. Ex: substitutie(a, x, [a, [b,a,] c], L2) va produce: L2 = [x, [b, x], c].
b) Liniarizarea listelor. Scrie predicatul liniar(ListaListe, Lista), unde ListaListe este o lista de
elemente care pot fi rndul lor liste, iar n Lista se construieste liniarizarea listei ListaListe.
Astfel,liniar([1, 2, [3, 4], [5, [6, 7], [[8], 9]]], L) va returna in L lista [1, 2, 3, 4, 5, 6, 7, 8, 9].

7. a) Sa se scrie predicatul imparte(L, L1, L2) care mparte lista L n doua subliste L1 si L2, care a
un numar de elemente aproximativ egal, fara a calcula lungimea listei L. Ex: imparte([a, b, c, d, e],
L1, L2) va produce: L2 = [a, b, c] si L3 = [d, e].
b) Scriei un predicat descomp(N, Lista) care primete un numr ntreg N i ntoarce o lista a
factorilor primi ai numarului N; de exemplu: descomp(12, [2, 2, 3]) este adevarat.

8. a) Sa se scrie un predicat evenmember(Elem,Lista) care spune daca Elem se afla in Lista pe


pozitie para. De exemplu, apelul evenmember(X,[1,5,3,4]) va returna pe rind solutiile X = 5; X = 4.
b) Scrieti un predicat invers(Lista, ListaInversata) care inverseaza elementele unei liste; sa se
scrie doua variante ale predicatului de inversare a unei liste: o varianta n care lista inversata este
calculata pe ramura de revenire din recursivitate i o varianta n care lista inversata este calculata pe
ramura de avans n recursivitate.

9. a) Sa se scrie un predicat imparte(L1,L2,L3) care imparte lista L1 in doua liste L2 si L3,


continnd elementele de pe pozitii impare iar L3 pe cele de pe pozitii pare.Ex:
imparte([a,b,c,d,e],L2,L3) va produce L2=[a,c,e] si L3=[b,d].
b) Scrieti un predicat palindrom(Lista) care verifica daca o lista este palindrom(Un palindrom
este o secventa care, daca este parcursa de la stnga la dreapta sau de la dreapta la stnga, este
identica; de exemplu: [a, b, c, b, a] sau [a, b, c, c, b, a].) Sa se modifice predicatul anterior astfel incit
sa genereze liste palindrom cu elemente 0 si 1.

10. a) S se scrie un program Prolog care s calculeze media numerelor unei liste.
b) Scrieti un predicat rotire(Lista, Directie, Nr, ListaRez) care roteste Lista cu un num_r de
Nr elemente la stnga (dac_ Directie = stg) sau la dreapta (dac_ Directie = dr), depunnd rezultatul n
ListaRez.

11. a) S se scrie un program Prolog care calculeaz i afieaz cel mai mare divizor comun al
tuturor numerelor dintr-o list.
b) Sa se scrie predicatul imparte(L, L1, L2) care mparte lista L n doua subliste L1 si L2, care a
un numar de elemente aproximativ egal, fara a calcula lungimea listei L. Ex: imparte([a, b, c, d,
e], L1, L2) va produce: L2 = [a, b, c] si L3 = [d, e].

12. a) S se scrie un program Prolog care s sorteze descresctor numerele unei liste.
b) Sa se scrie predicatul substitutie(X, Y, L1, L2), unde L2 este rezultatul substituirii tuturor
apariiilor lui X din lista L1 cu Y. Ex: substitutie(a, x, [a, [b,a,] c], L2) va produce: L2 = [x, [b, x], c].

13. a) Scriei un program care utilizeaz predicatul listaPara, care are dou argumente. Primul
argument este o list de numere ntregi, iar al doilea argument returneaz o list cu toate numerele
pare din prima list.
b) Scrieti un predicat rotire(Lista, Directie, Nr, ListaRez) care roteste Lista cu un num_r de
Nr elemente la stnga (dac_ Directie = stg) sau la dreapta (dac_ Directie = dr), depunnd rezultatul n
ListaRez.

14. a) S se elimine primele N elemente de la nceputul unei liste. Numarul elementelor pentru
eliminare se va ntroduce utiliznd predicatul readln limbajului Prolog.
b) Sa se scrie predicatul imparte(L, L1, L2) care mparte lista L n doua subliste L1 si L2, care a
un numar de elemente aproximativ egal, fara a calcula lungimea listei L. Ex: imparte([a, b, c, d, e],
L1, L2) va produce: L2 = [a, b, c] si L3 = [d, e].

15. a) S se elimine ultimii N elemente a unei liste. Numarul elementelor pentru eliminare se va
ntroduce utiliznd predicatul read limbajului Prolog.
b) Scriei un program care utilizeaz predicatul listaPara, care are dou argumente. Primul
argument este o list de numere ntregi, iar al doilea argument returneaz o list cu toate numerele
pare din prima list.

S-ar putea să vă placă și