Professional Documents
Culture Documents
Viorel NEGRU
October 14, 2003
Cuprins
Introducere v
1 Not iuni de baza Lisp 3
1.1 Not iuni introductive . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Interpretorul Lisp . . . . . . . . . . . . . . . . . . . . . . 3
1.1.2 Elemente de baza . . . . . . . . . . . . . . . . . . . . . . 4
1.1.3 Evaluarea . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.4 Atribuirea si legarea variabilelor . . . . . . . . . . . . . . 8
1.2 Operat ii cu liste . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2.1 Funt iile car, cdr si cons . . . . . . . . . . . . . . . . . . . 10
1.2.2 Alte funct ii . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3 Probleme propuse . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2 Funct ii utilizator 17
2.1 Denirea funct iilor . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.1 Denire . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.1.2 Apel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.3 Evaluare . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.1.4 Variabile legate si variabile libere . . . . . . . . . . . . . 19
2.1.5 Modul de transmitere a parametrilor . . . . . . . . . . . 21
2.2 Expresii condit ionale . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2.1 Cond . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3 Predicate Lisp . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3 Recursivitatea 23
3.1 Denirea recursivitat ii . . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Recursivitatea n Lisp . . . . . . . . . . . . . . . . . . . . . . . 24
3.3 Corectitudinea unui algoritm recursiv . . . . . . . . . . . . . . . 25
3.4 Reguli pentru conceperea de algoritmi recursivi . . . . . . . . . 26
3.4.1 Recursivitate simpla si recursivitate dubla . . . . . . . . 28
i
ii CUPRINS
3.5 Tipuri de funct ii recursive . . . . . . . . . . . . . . . . . . . . . 29
3.5.1 Funct ii nal recursive . . . . . . . . . . . . . . . . . . . . 29
3.5.2 Recursivitate compusa . . . . . . . . . . . . . . . . . . . 32
3.5.3 Recursivitate monotona si nemonotona . . . . . . . . . . 32
3.6 Trasarea funct iilor recursive . . . . . . . . . . . . . . . . . . . . 33
3.7 Probleme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.7.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3.7.2 Operat ii asupra listelor . . . . . . . . . . . . . . . . . . . 36
3.7.3 Operat ii cu mult imi . . . . . . . . . . . . . . . . . . . . . 37
3.7.4 Operat ii cu vectori si matrice rare . . . . . . . . . . . . . 37
Lista gurilor
1.1 Structura interna a listei (a b c): (1) Descrierea arborescenta;
(2) Descrierea simplicata. . . . . . . . . . . . . . . . . . . . . . 10
1.2 Structura interna a listei ((a (b c)) d ((e f) g) h), descrierea
arborescenta. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.3 Structura interna a listei ((a (b c)) d ((e f) g) h), descrierea pe
nivele. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.4 Structura unei celule cons. . . . . . . . . . . . . . . . . . . . . . 12
1.5 Relat ia dintre car, cdr si cons. . . . . . . . . . . . . . . . . . . . 13
2.1 Legarea parametrilor. . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1 Arborele inversat pentru funct ia fact . . . . . . . . . . . . . . . 26
3.2 Arborele inversat pentru funct ia dublu-recursiva fib . . . . . . 29
3.3 Arborele inversat pentru funct ia recursiva atomizare . . . . . . 30
3.4 Arborele inversat pentru funct ia fact - varianta nal recursiva . 31
iii
iv LISTA FIGURILOR
Introducere
Prodomo
High thoughts must have high language Aristophanes - Frogs (405 B.C.)
Limbaje de programare
Rezolvarea unei probleme presupune, n general, pornind de la un enunt , (mai
mult sau mai put in formalizat), proiectarea unui algoritm, a carui implemen-
tare (codicare) va un program, scris ntr-un limbaj de programare, pro-
gram ce va executat pe un calculator n vederea obt inerii solut iei problemei.
Execut ia unui program presupune declansarea unui proces de calcul. Procesele
de calcul sunt entitat i abstracte care, n evolut ia lor, manipuleaza alte entitat i
abstracte, numite date. Evolut ia unui proces este condusa de o mult ime de
reguli, ce formeaza programul.
Un limbaj de programare este o notat ie prin care programatorii comunica cu
calculatoarele, precum si cu alt i programatori. Limbajele de programare pot
mai apropiate de limbajul cod-masina al calculatorului (limbaje de asamblare)
sau mai ndepartate (limbaje de nivel inalt).
In funct ie de scop, ntalnim
limbaje generale si limbaje speciale.
Limbajelor de programare se pot clasica n funct ie de paradigmele de
programare utilizate: programare procedurala (C, Pascal); programare logica
(Prolog); programare functionala (Lisp, Scheme, ML); programare orientata
obiect (Smalltalk, C++); programare orientata pattern-uri (OPS5, Clips); pro-
gramare orientata pe componente etc.
O clasicare mai generala este legata de modul de rezolvare a problemei.
Vorbim de programare declarativa (n care furnizam calculatorului ce sa re-
zolve) si de programare imperativa (n care furnizam calculatorului cum sa
rezolve problema).
In primul caz este vorba de limbaje din clasa PROLOG,
iar n al doilea caz de limbaje ca: Pascal, C, Lisp etc.
Majoritatea limbajelor de programare au fost create, n primul rand, pentru
v
vi Introducere
a efectua calcul numeric. Limbajele din clasa Lisp au fost create special pentru
a efectua calcul simbolic. Limbajele Lisp si Prolog se mai caracterizeaza si prin
faptul ca au fost cele mai utilizate limbaje n Inteligent a Articiala.
Limbajele de programare pot interpretative sau compilative. Limbajele
interpretative sunt conversat ionale, prin raport cu limbajele compilative n
care exista o ntarziere ntre introducerea si execut ia programului. Limba-
jele interpretative sunt mai mult utilizate pentru dezvoltarea si modicarea
programelor (permit o interact iune a programatorului usoara si rapida cu cal-
culatorul). Limbajele compilative sunt utilizate pentru end users (cerint e de
viteza si mai put in de posibilitat i de modicare).
Un limbaj de programare trebuie denit pentru a obt ine programe corecte
si eciente. Din pacate este foarte greu, daca nu imposibil, de a respecta, n
acelasi timp cele doua condit ii. Limbajele din familia Lisp au fost create si
dezvoltate avand n vedere mai ntai corectitudinea si apoi ecient a programe-
lor.
In schimb limbajele din familia C au avut n vedere mai ntai ecient a si
apoi corectitudinea.
Isoric
Limbajul Lisp (LISt Processing) este unul din cele mai vechi limbaje de pro-
gramare (al doilea limbaj ca vechime, primul ind limbajul Fortran). Lisp a
fost creat ntre anii 1956 - 1962 de catre John McCarthy la MIT. Scopul a fost
crearea unui limbaj algebric bazat pe prelucrarea listelor pentru a utilizat
n Inteligent a Articiala. Lisp a fost conceput pentru a face fat a la calcule
simbolice (nenumerice) complicate. Crearea sa a fost inuent ata de evolut ia
limbajului FORTRAN, dar mai ales de limbajul specializat IPL2, folosit de
Newell, Shaw si Simon pentru implementarea programului de demonstrare
automata de teoreme Logic Theorist (program prezentat la conferint a de
Inteligent a Articiala de la Dartmouth, n vara anului 1956).
Limbajul Lisp se bazeaza pe modele matematice formale ale calcului (teoria
funct iilor recursive). La baza limbajului sta calculul , elaborat de Alonzo
Churchn 1941. Mai exact este vorba de o apropiere de schema de reprezentare
a funct iilor part ial recursive denite peste anumite clase de expresii simbolice.
Prima versiune stabila a fost Lisp 1.5 realizata de John McCarthy n 1962.
Ulterior au aparut o mult ime de variante (dialecte) de Lisp.
Intre 1986 - 1988 are loc standardizarea limbajului obiect CLOS (Common
Lisp Oriented System) [?]. CLOS este un nucleu obiect integrat in Common
Lisp, ind bazat pe limbajele New Flavors (Symbolics) si Common Loops
(Xerox).
Dintre variantele paralele ale limbajului Lisp amintim dialectele: Multilisp,
Qlisp si Buttery PSL.
In realitate n Lisp pe l anga funct ii o sa mai int alnim forme speciale si macrouri. Unii
autori ([?]) le ncadreaza n conceptul mai general de procedura. Funct ia este o procedura
n care intrarile sunt date de argumente, iar iesirea (rezultatul) de valoarea ntoarsa. Un
exemplu este funct ia din matematica. Un program este implementarea unei proceduri ntr-un
limbaj de programare. Deoarece n Lisp nu sunt deosebiri majore ntre program, procedura
si funct ie noi o sa folosim n continuare termenul de funct ie.
3
4 CAPITOLUL 1. NOT IUNI DE BAZ
A LISP
Spre exemplu, daca introducem simbolul pi, urmat de tasta < enter >, pi
va evaluat, iar valoarea va asata:
>pi
3.14159
1.1.2 Elemente de baza
Atomi si liste
Cele mai simple entitat i n limbajul Lisp sunt atomii. Atomii pot atomi
numerici sau numere, respectiv atomi simbolici sau simboluri. Numerele se
evalueaza la ele nsele.
>16 >1.25
16 1.25
Simbolurile
2
se evalueaza la valorile la care au fost legate. Sa presupu-
nem ca simbolul suma este legat la valoarea 16 (suma 16) si simbolul
locul-nasterii ARAD):
>suma >locul-nasterii
16 arad
In cadrul fazei read din ciclul read-eval-print, are loc, implicit, transformarea, n cazul
simbolurilor, a literelor mici n litere mari (variabila globala *print-case*
3
este legata
la valoarea :upcase
4
). Daca dorim ca sa avem o transformare din litere mari n litere
mici atunci *print-case* se leaga la valoarea :downcase. Efectul acestei transformari se
observa n faza print.
In aceasta prezentare consideram ca *print-case* este leaga la
valoarea :downcase.
1.1. NOT IUNI INTRODUCTIVE 5
O lista consta din zero sau mai multe elemente (atomi sau liste), separate
prin spat ii si cuprinse ntre paranteze rotunde. Exemple de liste:
(), (a b c), (a (b (c))), (+ 1 2 3), (aceasta este o lista)
Cu ajutorul listelor putem reprezenta mult imi, arbori, grafuri, expresii ma-
tematice etc.
Ca atomi, n Lisp, avem constantele t si nil. Prima are semnicat ia de
adevarat (true), iar a doua de fals (false). Constanta nil mai reprezinta si
lista vida (nil ()), nil ind singura entitate Lisp cu dubla semnicat ie.
>t >nil >()
t nil nil
Comentarii si scrierea unui program n Lisp
Comentariile n Lisp sunt de forma:
;<text-oarecare>
Efectul ntalnirii macrocaracterului
5
;n faza read a ciclului read-eval-print
este ignorarea tuturor caracterelor de dupa ; pana la sfarsit de linie.
Comentariile pot singure pe linie sau combinate cu text sursa Lisp. Sunt
preferate comentariile la nivel de linie. Acestea pot straticate (de exemplu
cel mai general comentariu va cont ine la nceput de linie patru - cinci caractere
;, iar cel mai specic un caracter ;).
Funct iile n Lisp se scriu indentate, n general t inand cont de paranteze:
;;; Calculul factorialului
;;;
(defun fact (n)
;;conditia de oprire
(if (zerop n)
1 ; 1 <-- (fact 0)
;;apelul recursiv
(* n (fact (1- n)))
)
)
5
Un macrocaracer este un caracter caruia i se ataseaza o funct ie care este apelata n
momentul n care parser-ul read nt alneste caracterul respectiv, funct ie care potent ial poate
modica expresia simbolica prelucrata de read.
6 CAPITOLUL 1. NOT IUNI DE BAZ
A LISP
Expresii simbolice
Listele si atomii formeaza expresiile simbolice sau s-expresiile n Lisp. O
denit ie (recursiva) a expresiilor simbolice este urmatoarea:
1. Atomii sunt expresii simbolice;
2. O lista este o construct ie de forma () sau (e
1
, e
2
, . . . , e
n
), unde n 1 si
e
1
, e
2
, . . . , e
n
sunt expresii simbolice;
3. O pereche cu punct
6
este o construct ie de forma (e
1
. e
2
), unde e
1
,si e
2
sunt expresii simbolice;
4. Listele si perechile cu punct sunt expresii simbolice.
Exemple de expresii simbolice:
1, abc (), (a . b), ((a) (b c (d)) e), "ab1", ("a" 2 b)
Funct ii
Funct iile n Lisp sunt obiecte obisnuite, la fel ca simbolurile si listele.
Apelul unei funct ii este reprezentat de o lista n care primul element repre-
zinta funct ia, iar celelalte elemente argumentele funct iei. De exemplu, forma
(+ 1 2 3) este compusa din funct ia (operatorul) de adunare + si din argumen-
tele (operanzii) 1 2 si 3.
>(+ 1 2 3) >(sqrt 4)
6 2
>(* (+ 2 3) 10)
50
Evaluarea unei liste care nu este o forma va produce eroare:
>(a 1 2)
error: unbound function - a
Funct iile pot funct ii sistem sau funct ii denite de utilizator.
6
Perechea cu punct are un efect mai mult intern, pentru reprezentarea mai compacta
listelor n memorie
1.1. NOT IUNI INTRODUCTIVE 7
1.1.3 Evaluarea
O expresie simbolica ce poate evaluata se numeste forma. Daca o forma este
reprezentata printr-o lista distingem trei interpretari ale acestei forme: apel
de funct ie, apel de forma speciala, respectiv apel de macro.
Intr-un apel de
funct ie se aplica funct ia (data de primul element) asupra argumentelor (restul
elementelor) evaluate. O forma speciala evalueaza / nu evalueaza argumentele
conform unor reguli proprii.
Evaluarea implicita are loc n cadrul ciclului read-eval-print, n faza
eval. Funct ia de evaluare act ioneaza astfel:
1. daca expresia este atom, ntoarce valoarea sa;
2. daca expresia este o lista:
(a) daca primul element din lista reprezinta o funct ie, regaseste aceasta
funct ie si
i. evalueaza restul elementelor din lista aplicand aceleasi reguli la
ecare din ele;
ii. aplica funct ia de la a) la argumentele de la i) si ntoarce rezul-
tatul.
(b) daca primul element reprezinta o forma speciala, aplica un trata-
ment specic asupra argumentelor sale si asupra formei speciale;
(c) daca primul element reprezinta un macro, aplica un tratament spe-
cic macrourilor.
Stoparea evaluarii
A LISP
Funct ia eval folosita de interpretor poate apelata si explicit. Funct ia si
evalueaza argumentul, valoarea ntoarsa ind rezultatul obt inut prin evaluarea
argumentului evaluat:
Exemple de utilizare:
>(eval (+ 1 2)) >(car (+ 1 2))
3 +
Daca presupunem ca y x, iar x 10:
>(eval y) ;y (ca argument) este evaluat la x, iar x la 10
10
1.1.4 Atribuirea si legarea variabilelor
Pana acum am vazut ca datele cu care operam sunt expresii simbolice (atomi,
liste). Datele ocupa locat ii de memorie. Forma de reprezentare si cont inutul
locat iei de memorie depind de tipul datelor. Un simbol ce desemneaza valoarea
dintr-o locat ie de memorie se numeste variabila. Asocierea unei variabile la o
data se numeste legare, ind echivalentul atribuirii din alte limbaje.
Spre deosebire de alte limbaje de programare n Lisp locat ia de memorie
cont ine amprenta tipului datei, tip ce se atribuie variabilei n momentul legarii
variabilei la valoarea din locat ia de memorie. Aceasta operat ie se mai numeste
si tipare n timpul execut iei.
Pentru legarea variabilelor avem urmatoarele funct ii
7
Lisp: set, setq pen-
tru legarea secvent iala a variabilelor, respectiv pset psetq pentru legarea pa-
ralela a variabilelor.
Setq este forma speciala si are forma generala:
(setq <var
1
> <val
1
> ... <var
n
> <val
n
>)
Argumentele de ordin impar trebuie sa e simboluri si nu se evalueaza,
argumentele de ordin par se evalueaza, valoarea ntoarsa este data de ultimul
argument evaluat, iar ca efect lateral <var
i
> <val
i
> evaluate.
Exemple:
>(setq x 1 y (a b c)) >(setq x 1 y (+ x 2))
(a b c) 3
>x >x
7
Prin abuz de limbaj o sa folosim termenul de funct ie si pentru forme speciale, urmand
ca, acolo unde este cazul, sa facem distinct ia necesara
1.1. NOT IUNI INTRODUCTIVE 9
1 1
>y >y
(a b c) 3
Set este funct ie si are forma generala:
(set <var
1
> <val
1
> ... <var
n
> <val
n
>)
A LISP
1.2 Operat ii cu liste
O lista cont ine elemente care pot atomi sau liste. Listele pot prelucrate
pe nivelul supercial sau n adancime. Nivelul supercial se refera la primul
nivel de elemente. Daca toate elementele unei liste sunt atomi avem doar un
nivel (nivelul supercial).
Operat iile principale asupra listelor se refera, n principal, la selectarea
unor elemente (utilizare accesori) din lista si crearea de noi liste (utilizare
constructori).
Reprezentarea interna a unei liste este data de o structura arborestenta.
Lista (a b c) are structura interna data de Figura 1.1.
(1)
(2)
a
c
b
a b c
Figura 1.1: Structura interna a listei (a b c): (1) Descrierea arborescenta; (2)
Descrierea simplicata.
Un alt exemplu este dat de reprezentarea interna a listei ((a (b c)) d
((e f) g) h) (vezi gurile 1.2,1.3)
1.2.1 Funt iile car, cdr si cons
Funct ia car
8
primeste ca argument o lisa si ntoarce primul element al listei
sau partea stanga a unei perechi cu punct. Se poate folosi o funct ie echivalenta
si cu un nume mai semnicativ: first.
(car <lista>)
Exemple de utilizare:
8
Denumirile de car si cdr vin de la numele unor registri de la calculatorul pe care s-a
implementat prima versiune Lisp
1.2. OPERAT II CU LISTE 11
a
b
c
d
e
f
g
h
Figura 1.2: Structura interna a listei ((a (b c)) d ((e f) g) h), descrierea
arborescenta.
a
b c
d
e f
g
h
Figura 1.3: Structura interna a listei ((a (b c)) d ((e f) g) h), descrierea pe
nivele.
>(car (a b c)) >(car a)
a error: bad argument type - a
>(car (1 . 2)) >(first (a b c))
1 a
>(car ((a (b c)) d ((e f) g) h))
(a (b c))
Funct ia cdr primeste ca argument o lisa si ntoarce lista mai put in primul
element sau partea dreapta a unei perechi cu punct. Se poate folosi o funct ie
echivalenta si cu un nume mai semnicativ: rest.
(cdr <lista>)
Exemple de utilizare:
12 CAPITOLUL 1. NOT IUNI DE BAZ
A LISP
>(cdr (a b c)) >(cdr a)
(b c) error: bad argument type - a
>(cdr (1 (2 . 3))) >(rest (a b c))
((2 . 3)) (b c)
>(dar ((a (b c)) d ((e f) g) h))
(d ((e f) g) h)
Prin convent ie car si cdr din nil este nil.
Funct ia cons (denumirea vine de la CONStructor) creaza o lista (celula
cons) care are car-ul dat de primul argument si cdr-ul de al doilea argument
(Figura 1.4). Rezultatul va o lista (cand al doilea argument este o lista) sau
o pereche cu punct (cand al doilea argument este un atom).
(cond <el> <lista>)
cdr car
celula cons
Figura 1.4: Structura unei celule cons.
Exemple de utilizare:
>(cons a (b c)) >(cons nil nil)
(a b c) nil
>(cons (a) (b c)) >(cons 1 2)
((a) b c) (1 . 2)
>(cons 1 nil) >(cons (a b) c)
(1) ((a b) . c)
Funct iile car si cdr pot compuse:
>(car (car (cdr (a ( b c) d))))
b
Aplicarea funct iilor se face de la drepta spre stanga.
In funct ie de imple-
mentare, exista, pe langa car si cdr funct iile cxxr, cxxxr, cxxxr cu x egal
cu a sau d. Funct ia echivalenta cu apelul din exemplul anterior este:
1.2. OPERAT II CU LISTE 13
>(caadr (a (b c) d))
b
O combinat ie de car, cdr si cons (vezi Figura 1.5) din care rezulta relat ia
dintre acestea este data n exemplul urmator:
>(setq l (a b c))
(a b c)
>(cons (car l) (cdr l))
(a b c)
(a b c)
car a
cdr (b c)
cons (a b c)
Figura 1.5: Relat ia dintre car, cdr si cons.
1.2.2 Alte funct ii
A LISP
>(append ((a)) (b c) d)
((a) b c . d)
>(append)
nil
Funct ia list are un numar variabil de argumente, argumentele evaluate
putand orice expresie simbolica. valoarea ntoarsa este data de concatenare
argumentelor evaluate.
Forma generala este:
(list <sexpr
1
> <sexpr
2
> . . . <sexpr
n
>)
Exemple de utilizare:
>(list 1 2 3)
(1 2 3)
>(list (a b) c ((d e) f))
((a b) c ((d e) f))
>(list 1 (2 . 3))
(1 (2 . 3))
>(list nil nil)
(nil nil)
O comparat ie ntre cons, append si list este prezentata n exemplul
urmator:
>(cons (a) (b c))
((a) b c)
>(append (a) (b c))
(a b c)
>(list (a) (b c))
((a) (b c))
Funct ia last ntoarce ultima celula cons a listei primite ca argument.
Forma generala este:
(last <lista>)
Exemple de utilizare:
1.3. PROBLEME PROPUSE 15
>(last (a b c d))
(d)
>(last (a b . c))
(b . c)
>(last (a))
(a)
Funct a reverse are ca argument o lista si ntoarce ca si rezultat o lista cu
elementele de pe nivelul supercial inversate.
Forma generala este:
(reverse <lista>)
Exemple de utilizare:
>(reverse (1 2 3 4 5)
(5 4 3 2 1)
>(reverse (a (b c d) e))
(e (b c d) a)
Funct ia length ntoarce numarul de elemente de pe nivelul supercial al
listei primite ca argument.
Forma generala este:
(length <lista>)
Exemple de utilizare:
>(length (a b c))
3
>(length ((a b (c)) (d e)))
2
>(length ())
0
1.3 Probleme propuse
16 CAPITOLUL 1. NOT IUNI DE BAZ
A LISP
Capitolul 2
Funct ii utilizator
Funct iile n Lisp pot funct ii sistem sau funct ii denite de utilizator. Fuct iile
denite de utilizator permit mpreuna cu macro-urile extinderea limbajului
Lisp. Funct iile sistem sunt funct ii scrise, pentru ecient a, n cod. Funct iile
utilizator, tot din considerente de ecient a, pot compilate.
2.1 Denirea funct iilor
2.1.1 Denire
Denirea funct iilor utilizator se face cu ajutorul macro-ului
1
defun
2
.
Forma generala este:
(defun <nume-func> <lista-param>
<expr-1> <expr-2> ... <expr-n>)
unde:
<nume-func> este primul argument si reprezinta numele funct iei denite
de defun;
<lista-param> este al doilea argument al lui defun, are forma (<par-1>
<par-2> ... <par-m>) si reprezinta lista cu parametri pentru funct ia
denita;
<expr-i>, i = 1, . . . , n sunt forme ce alcatuiesc corpul funct iei denite.
1
Pentru a obt ine o ecient a mai buna, n multe implementari ale limbajului Lisp - o parte
din macro-urile sistem au fost implementate ca si forme speciale
2
In exemplul al treilea modicarea valorii lui y n cadrul funct iei f3, y ind
variabila libera, are efect si dupa parasirea funct iei.
In ultimul exemplu funct ia
symbol-value ntoarce valoarea globala a lui x si nu valoarea sa locala.
Dupa cum se observa din exemplele anterioare nu este indicat a utilizarea
variabilelor globale n cadrul unei funct ii. Funct ia depinde de modicarea va-
riabilelor globale, comportarea funct iei modicandu-se atunci cand se schimba
valoarea variabilei globale.
Un context (mediu) n Lisp este dat de o mult ime de legaturi (variabilele cu
valorile la care sunt legate, denit ii de funct ii etc.). Contextul din momentul
denirii unei funct ii se numeste context de denire, iar contextul n care se
evalueaza funct ia de numeste context de evaluare.
Funct iile pot imbricate, o funct ie ind apelata din alt a funct ie. Fiecare
funct ie va
2.2. EXPRESII CONDIT IONALE 21
2.1.5 Modul de transmitere a parametrilor
2.2 Expresii condit ionale
2.2.1 Cond
2.3 Predicate Lisp
22 CAPITOLUL 2. FUNCT II UTILIZATOR
Capitolul 3
Recursivitatea
3.1 Denirea recursivitat ii
Un obiect este recursiv daca este denit funct ie de el nsasi.
Intalnim, astfel,
termeni ca: functii recursive, proceduri recursive, denit ii recursive de date,
calcul recursiv.
Recursivitatea ne ofera posibilitatea de a deni un numar innit de obiecte
printr-o declarat ie nita, respectiv de a descrie un numar innit de operat ii
printr-un program recursiv nit.
Exemple de denit ii recursive:
1. GNU = Gnu is Not Unix
2. numerele naturale:
(a) 0 este numar natural;
(b) succesorul unui numar natural este un numar natural.
3. arborii binari:
(a) o este un arbore binar (arborele vid);
(b) daca t
1
si t
2
sunt arbori binari atunci si
o
2
t
1
t
este un arbore binar.
23
24 CAPITOLUL 3. RECURSIVITATEA
4. factorialul unui numar:
n! =
In cazul general, factorialul unui numar este egal cu produsul dintre
numar si factorialul din numar mai put in unu;
In cazul de baza, factorialul din 0 este 1.
De aici rezulta o mult ime de reguli de programare n Lisp a funct iilor re-
cursive:
se vor utiliza funct ii de control cond, if;
clauzele recursive din cond, if vor precedate de clauze de iesire;
Daca n denit ia matematica a unei funct ii recursive condit iile de ter-
minare se pun dupa apelul recursiv, n cazul unui program Lisp acestea
trebuie puse naintea apelului recursiv. Asejarea gresita, denirea inco-
recta sau lipsa acestora conduce la ciclari innite. De exemplu, funct ia
urmatoare ce determina daca un obiect apart ine la o list a, nu ia n calcul
cazul n care obiectul nu apart ine listei si conduce, n acest caz, la o
ciclare innita.
(defun our-member (el l)
(cond ((equal (carl l)) el)
(t (our-member (cdr l))) ))
Pentru a funct iona corect trebuie inserat lanceputn cond clauza ((endp
l) nil).
apelurile recursive se vor face cu argumente mai simple (mai apropiate
de satisfacerea condit iilor de iesire);
clauzele n care se utilizeaza car, cdr trebuie sa e precedate de clauze ce
sunt satisfacute cand argumentele sunt sucient de simple (de exemplu:
lista vida, atom etc).
28 CAPITOLUL 3. RECURSIVITATEA
3.4.1 Recursivitate simpla si recursivitate dubla
Funct iile recursive n Lisp pot simplu recursive (la ecare apel creaza o
copie), dublu recursive (la ecare apel creaza doua copii) sau combinat ii de cele
doua. Pentru a putea reprezenta grac cum funct ioneaza apelul unei funct ii
recursive vom folosi tehnica arborilor inversat i. Adancimea de recursivitate
a unui algoritm recursiv este data de numarul de nivele din cadrul arborelui
inversat corespunzator.
f(x
k
)
Df(x
k
)