Sunteți pe pagina 1din 34

Prelegerea 4.

Liste în Prolog

Întrebari

1. Sintaxă a listelor
2. Prelucrarea listelor
Exemple de liste

[monday, tuesday, wednesday, thursday, friday,


saturday, sunday]

[1, 2, 3, 4, 5, 6, 7]

[1.2, 2.5, 0.3, 4.7, 5.0, 6.2, 7.9]

['п', 'в', 'с', 'ч', 'п', 'с', 'в']

[ ]- o lista vida
Exemple de liste

[A, sosit, [ ziua, de, mine]]

[ a, X, b, [ Y, c] ]

[cartea (cujetari, autor(blaise, pascal)),


cartea(moby_dick , autor(herman,mellvile))]
Reprezentarea arborescentă a unei liste cu un
singur element
Reprezentarea arborescentă a listei
[ana, tenis, toma, facultate]
Liste cu variabile şi semnificaţiile lor
Exemple de unificare a listelor
Definiţia unei liste

În funcţie de numărul de elemente, o listă poate fi


definită în Prolog, în două feluri:

(1) lista vidă (lista cu 0 elemente) este o listă


reprezentată în Prolog prin atomul special [ ].

(2) o listă nevidă este o structură cu două


componente:
[Head | Tail]
În general, listele sunt definite recursiv.
[Head | Tail]

Primul element din listă - capul listei (head). Capul


unei liste poate fi orice termen, constantă, variabilă
sau funcţie Prolog.

Al doilea element - corpul sau coada listei (tail)


(format din următoarele elemente din listă). Coada
unei liste trebuie să fie o listă.

Sfârşitul unei liste este, de obicei,


reprezentat ca lista vidă.
Declararea listelor

domains
<nume listei>= <tipul elementelor listei>*

Exemple:

listI = integer* /* o listă din numeri întregi */


listR = real* /* o listă din numeri reale */
listC = char* /* o listă de simboluri */
lists = string* /* o listă din propoziţii */
listL = listI* /* o listă cu elemente- liste din
numeri întregi */
Obiecte de tip diferit intr-o lista

Exemplu: declararile din sectia


domains
element = i(integer); c(char); s(string)
liste = element*

permit formarea si prelucrarea unor liste compuse


din elemente, ce apartin diferitor tipuri de date

[i(15), s("Мама"), c('A'), s(“soseste") ,c('+'),


s(“miine"), i(48), c('!')]
Prelucrarea listelor

Unul din motivelle utilizării listelor rezidă în


capacitatea lor de a exprima situaţii dinamice.
Majoritatea predicatelor asupra listei utilizează
divizarea listei în cap şi coadă. Asupra capului se
aplică o operaţie, apoi însăşi, coada se împarte în cap
şi coadă şi operaţia se aplică din nou.
Procesul continuă pană cand nu se întîlneşte o
condiţie de terminare. Cea mai evidentă condiţie este
o lisă vidă. Astfel dacă avem lista [unu,doi, trei] ,ea
poate fi redusă în patru paşi:
Prelucrarea listei
[1, 2, 3] => [ 1| [2, 3] ] => [1 | [2| [3] ]] =>
[1 | [2 | [3] ] ] => [ 1 | [ 2 | [ 3 | [ ] ]]]
1. Cap=unu,
Coada=[doi,trei]

2. Cap=doi,
Coada=[trei]

3. Cap=trei, Coada=[ ]

4. Lista vida
Un program simplu de utilizare a listelor

domains
town=symbol
town_list = town*

predicates
town(town_list)
clauses
town([“Chisinau”,”Orhei”,”Balti”,
”Tiraspol”, “Tigina”]).
Afisarea elementelor listei
DOMAINS
SL= STRING*
PREDICATES
show_list(SL)
CLAUSES
show_list( [] ).
show_list( [H|T] ):-write(H), nl, show_list(T).
GOAL
show_list([“bmw”,”volvo”,”ford”,”citroen”,”renault”,
”ford”,”fiat”,”opel”,”mazda”]).
Verifcarea apartinerii unui element listei
( scop intern)
DOMAINS
IL = integer*
PREDICATES
member( INTEGER, IL)
CLAUSES
member(X, [ X| _ ] ).
member(X, [ _|Xs] ):-member(X, Xs).
GOAL
member( 2, [1,2,3]), write(“Adevarat elementu
2 apartine listei date”).
Verifcarea apartinerii unui element listei
( scop extern)

member (X, [X|_] ).


member(X, [_|T] ) :– member (X,T).
?- member ( с, [a, b, c, d] )
Yes
?- member ( e, [a, b, c, d] )
No
?- member ( X, [a, b, c, d] )
X=a , X=b, X=c, X=d
Acest predicat este inclus în bibliotecile multor versiuni al
limb.Prolog. În aceste biblioteci pot fi descoperite şi alte
predicate care pot fi utilizate pentru rezolvarea problemelor
diferite.
Verifcarea apartinerii unui element listei

O reguila universala pentru prelucrarea listelor:


member( X, [ X | R ] ).
member( X, [ Y | R ] ) :- member( X, R ).
Cea ce confirma ca:
•X este membru unei liste daca capul listei este X .
• sau ca X este membru unei liste – coada R
Testarea predicatelui-regula member
goal
member(2, [1,2,3] ).
 yes
goal
member(X, [1,2,3] ). % generam componentele listei
 X=1
X=2
X=3

goal
member( [3,Y] , [[1,a],[2,m],[3,z],[4,v],[3,p]] ).
Y=z
Y=p
% sunt cautate elemente -perechi
Testarea predicatelui-regula member
…sunt cautate elementele care satisfac unor conditii -
constringeri

goal
member( X, [23, 45, 67, 12, 222, 19, 9, 6] ) ,
Y = X*X,
Y < 100.
 X = 9 Y = 81
X = 6 Y = 36

% simbolul ‘=‘ poate fi folosit aici deoarece se utilizeaza ca


semn de comparare (op.logica)
Lungimea unei liste

Sunt declarate:
length([ ], 0). /* in lista vida nu sunt elemente */
length([ _ | T ], L) :– length(T, L_T), L = L_T + 1.

/* L – numar de elemente in lista data


L_T - numarul elementelor in coada listei*/

Exemplu de scop :
?- length( [1,2,3] , L ).
Lungimea unei liste
Lungimea unei liste
Lungimea unei liste
Lungimea unei liste
Lungimea unei liste
Lungimea unei liste
Testarea predicatului –regula length
Programul urmator descrie relatiile dintre o lista
si ultimul sau element:
mylast(X, [X]).
mylast(X, [_|T]) :- mylast(X, T).
Enumeram cateva scopuri si raspunsurile sistemului:
?- mylast(2, [2]).
true.
?- mylast(2, [1, 2, 3]).
false.
?- mylast(X, [1, 2, 3]). X = 3 ;
false.
?- mylast(3, [1, 2, X]). X = 3 ;
false.
Regula takeout
Regula takeout serveste pentru extragere unui element
din lista data.
takeout(X, [X|R], R).
takeout(X, [F|R], [F|S]) :- takeout(X,R,S).

Explicare:
•Cind X coincide cu capul listei(se extrage din lista
prin [X|R]), lista-rezultat va fi R .

•Cind X se extrage din sublista - coada prin


[X|R], [X|S], resultatul va fi S.
Eliminarea unui element din lista:

DOMAINS
ILIST = integer*
PREDICATES
takeout(INTEGER, ILIST, ILIST)
CLAUSES
takeout(X, [X|Xs], Xs).
takeout(X,[Cap|Xs],[Cap|Ys]):- takeout(X,Xs,Ys).
GOAL
takeout( 2, [1,2,3], X) , write(X).
Utilizam scopuri externe
goal
takeout;(X,[1,2,3],L).
 X=1 L=[2,3]
X=2 L=[1,3] takeout(X, [X|R], R).
X=3 L=[1,2] takeout(X, [F|R], [F|S]) :-
takeout(X,R,S).
takeout(X,Z,W)
poate fi interpretat si ca ‘include X in W pentru a obtine Z’

goal
takeout(3,W,[a,b,c]).
 W = [3,a,b,c]
W = [a,3,b,c]
W = [a,b,3,c]
W = [a,b,c,3]
Calculam suma elementelor listei

sum([ ], 0). /* suma elementelor liste vide = 0*/


sum([H|T], S) :– sum(T, S_T), S = S_T + H.

S_T – suma elementelor coadei ,


S – suma elementelor listei
Exemple

Multimile pot fi reprezentate în Prolog ca liste.


Predicatul multime(L, M) transforma lista L in
multimea M.
multime( [] , [] ).
multime( [ X | Rest ], Rez) :-
apartine(X, Rest), multime(Rest,Rez).
multime([X | Rest], [X | Rez]) :-
not(apartine(X,Rest)), multime(Rest, Rez).