You are on page 1of 6

Structuri n LISP Arbori, Grafuri

Cuprins: Structuri in LISP (arbori) Structuri in LISP (grafuri) DFS in LISP Exemple

V-A

I. Structuri in LISP (arbori) - Unitatea de baza in LISP este lista. Arborii se pot reprezenta sub multe feluri in LISP, atata timp cat sunt modelati sub forma unei liste. Aceasta lista poate contine la randul ei alte liste s.a.m.d. respectand principiul de structurare a informatiei intr-un arbore. Exemplu: Fie arborele: O reprezentare in LISP a acestui arbore ar fi urmatoarea: (1 (2 (3 (4) (5)) (0)) (2 (0) (1)))) S-a considerat celula lista (cheie_nod succesor_stanga succesor_dreapta) unde succesor_stanga (sau succesor_dreapta) poate fi la randul lui o alta lista. Astfel pentru fiecare nod avem asociata o lista cu trei elemente. Frunzele au fost reprezentate prin (cheie_nod), adica o lista cu un singur element. Pentru exemplul de mai sus, se implementeaza in LISP urmatoarele functii: ; asociem lui l arborele din exemplu (setf l '(1 (2 (3 (4) (5)) (0)) (2 (0) (1)))) ( let( (defun arbstang (l) (a (adancime (arbstang l))) ( cond ((null l) nil) (b (adancime (arbdrept l)))) ((= 1 (length l)) nil) ( cond ((< a b)(+ b 1)) (t (cadr l)))) (t (+ a 1))) ) ; de la let (defun arbdrept (l) ) ; de la if ( cond ((null l) nil) ) ; de la defun ((= 1 (length l)) nil) (t (caddr l)))) (defun headarb (l) ( car l)) ;functie care calculeaza adancimea maxima ;a unui arbore dat (defun cauta_key (key l) (defun adancime (l) (cond ((search_key key l) (if (= 1 (length l)) (princ '|gasit|)) 1 (t (princ '|negasit|))))

(defun search_key (key l) ( cond (( null l) nil ) ( (= key (headarb l)) t ) ( (search_key key (arbstang l)) t) ( (search_key key (arbdrept l)) t) ( t nil))) ;parcurgere in preordine (defun preordine(a) (cond ((not (null a)) (print (car a)) (preordine (cadr a)) (preordine (caddr a)) )))

;parcurgere in postordine (defun postordine(a) (cond ((not (null a)) (postordine (cadr a)) (postordine (caddr a)) (print (car a)) ();conditia de default ))) ;parcurgere in inordine (defun inordine(a) (cond ((not (null a)) (inordine (cadr a)) (print (car a)) (inordine (caddr a)) )))

II. Structuri in LISP (grafuri) - In LISP grafurile se reprezinta sub forma unor liste. Avem mai multe modalitati de a reprezenta un graf, toate folosind structura de lista. Fie graful: Reprezentarea acestuia in LISP folosind liste Pentru a memora informatii referitoare la fiecare ar fi urmatoarea: nod putem ori sa folosim o lista ajutatoare: ((nod (lista noduri_succesoare))*) Astfel: ( (1 (2 3)) (2 (1 3)) (3 (1 2 4 5 6)) (4 (3 6)) (5 (3 6)) (6 (3 4 5)) ) ( (nod1 (lista succesori nod1)) (nod2 (lista succesori nod2)) ............................................. (nodn (lista succesori nodn)) )

( (nod1 (lista atribute nod1)) (nod2 (lista atribute nod2)) ............................................. (nodn (lista atribute nodn)) ) sau putem folosi o singura lista pentru reprezentarea grafului respectiv: ( (nod1 ((lista atribute nod1) (lista succesori nod1))) (nod2 ((lista atribute nod2) (lista succesori nod2))) ................................................................................. (nodn ((lista atribute nodn) (lista succesori nodn))) ) sau perechi de cate trei (cheie nod, lista atribute nod, lista succesori nod: ( (nod1 (lista atribute nod1) (lista succesori nod1)) (nod2 (lista atribute nod2) (lista succesori nod2)) .............................................................................. (nodn (lista atribute nodn) (lista succesori nodn)) )

Vom reprezenta in LISP graful din imaginea de mai sus, folosind a doua modalitate prezentata:

In lista de atribute asociata fiecarui nod am considerat urmatoarele atribute (in ordine):
(timp_de_start, timp_de_terminare, culoare, parinte)

Astfel initial vom avea:

( (1 ((atribute_nod_1) (2 3))) (2 ((atribute_nod_2) (1 3))) (3 ((atribute_nod_3) (1 2 4 5 6))) (4 ((atribute_nod_4) (3 6))) (5 ((atribute_nod_5) (3 6))) (6 ((atribute_nod_6) (3 4 5))) )

( (1 ((0 0 0 0) (2 3))) (2 ((0 0 0 0) (1 3))) (3 ((0 0 0 0) (1 2 4 5 6))) (4 ((0 0 0 0) (3 6))) (5 ((0 0 0 0) (3 6))) (6 ((0 0 0 0) (3 4 5))) ) )

Vom considera o variabila ajutatoare, numarul de noduri pe care il are graful, care va fi retinut in prima locatie a grafului. Astfel graful nostru va fi reprezentat in LISP astfel: Varianta in LISP pentru graful nostru: ( numar_de_noduri_din_graf (6 ( ( (nod1 ((lista atribute nod1) (lista succesori nod1))) (1 ((0 0 0 0) (2 3))) (nod2 ((lista atribute nod2) (lista succesori nod2))) (2 ((0 0 0 0) (1 3))) ................................................................................. (3 ((0 0 0 0) (1 2 4 5 6))) (nodn ((lista atribute nodn) (lista succesori nodn))) (4 ((0 0 0 0) (3 6))) ) (5 ((0 0 0 0) (3 6))) ) (6 ((0 0 0 0) (3 4 5))) ) ) In cele ce urmeaza se vor prezentaimplementarea in LISP a grafului, a unor functii ajutatoare pentru prelucrare graf, precum si a metodei de parcurgere graf DFS. (setq timp 0) (defun get_NrNod(nod) (car nod) ) (defun set_NrNod(nod x) (setf (car nod) x) ) (defun get_Informatie(nod) (caadr nod) ) (defun set_Informatie(nod x) (setf (caadr nod) x) ) (defun get_debut(nod) (car (get_Informatie nod)) ) (defun set_debut(nod x) (setf (car (get_Informatie nod)) x) ) (defun get_iesire(nod) (cadr (get_Informatie nod)) ) (defun set_iesire(nod x) (setf (cadr (get_Informatie nod)) x) ) (defun get_culoare(nod) (caddr (get_informatie nod)) ) (defun set_culoare(nod x) (setf (caddr (get_Informatie nod)) x) ) (defun get_parinte(nod) (cadddr (get_Informatie nod)) ) (defun set_parinte(nod x) (setf (cadddr (get_Informatie nod)) x) ) (defun get_succesori(nod) (cadadr nod) ) (defun get_noduri(G) (cadr G) ) (defun Coloreaza_Alb(Lista_Noduri) (cond ((null Lista_Noduri) nil) (t (setq nod (car Lista_Noduri) ) (set_culoare nod 'alb)

(Coloreaza_Alb (cdr Lista_Noduri)) ) ) ) (defun Apeluri_DfsNod(Lista_Noduri G) (cond ((null Lista_Noduri) nil) (t (setq urm (car Lista_Noduri)) (cond ((eq (get_culoare urm) 'alb) (set_parinte urm nil) (Dfs_Nod urm G) ) ) (Apeluri_DfsNod (cdr Lista_Noduri) G) ) ) ) (defun Dfs_Alg(G) (setq timp timp) (setq Temp (cadr G)) ;setam Temp = lista de noduri a grafului (Coloreaza_Alb Temp);coloram in alb toate nodurile (Apeluri_DfsNod Temp G) ) (defun noduri_adiacente(nod G) (setq succesori (get_succesori nod)) (dolist (xnr succesori) (dolist (xnod (get_noduri G)) (cond ((= (get_NrNod xnod) xnr) (cond ( (eq (get_culoare xnod) 'alb) (set_parinte xnod (get_NrNod nod)) (Dfs_Nod xnod G) ) )

) ) ) ) )

(defun Dfs_Nod(Nod G) (set_culoare nod 'gri) (set_debut nod timp) (setq timp (+ timp 1)) (noduri_adiacente Nod G) (set_culoare Nod 'negru) (set_iesire Nod timp) (setq timp (+ timp 1)) ) Pentru a testa functionarea acestui program: (setq G '(6 ( (1 ((0 0 0 0) (2 3))) (2 ((0 0 0 0) ())) (3 ((0 0 0 0) (4 5 6))) (4 ((0 0 0 0) (5))) (5 ((0 0 0 0) ())) (6 ((0 0 0 0) ())) ) ) ) (setq Temp (cadr G)) (print Temp) (setq radacina (car Temp)) (print radacina) (print (get_Informatie radacina)) (print (get_debut radacina)) (print (get_iesire radacina)) (print (get_culoare radacina)) (print (get_parinte radacina)) (set_debut radacina 8) (print radacina) (print (get_succesori radacina)) (Dfs_Alg G) (print G)

Tema de laborator: Implementarea in LISP a BSF1-ului folosind metodelel rpezentate mai sus.

Breadth First Search

Simboluri i generarea automat de simboluri

V-B

1. Simboluri i proprieti Fiecare atom simbolic LISP poate fi legat la o valoare (fie global, printr-o funcie de tip SETQ, fie local n cadrul unei funcii sau a unui bloc LET). Pe lng aceast valoare, care este pstrat n ALIST, se mai pot asocia proprieti. Fiecare proprietate asociat unui atom poate avea o valoare ataat. Dac proprietatea nu a fost setat, atunci valoarea ei implicit este nil. Se pot asocia oricte proprieti unui atom simbolic. Acest lucru se realizeaz cu ajutorul funciilor setf i get. 1. (get <atom> <nume_propr>) Aceast funcie ntoarce valoarea proprietii cu numele <nume_propr> asociat simbolului <atom>. ATENIE!!! Aceast funcie i evalueaz ambii parametri, ca n exemplul de mai jos: Exemplu: > (get a 'color) ; atomul A nu este legat la nici o valoare error: unbound variable A > (get 'a 'color) ; apel corect, dac A nu e legat nil ; dac a nu este setat la nici o culoare 2. (setf <atom>|<apel_get> <valoare>) Dac este folosit cu un <atom> drept prim argument, atunci acioneaz exact ca funcia set. Dac drept prim argument este un apel al funciei get, avnd ca argumente un simbol i un nume de proprietate, acest apel are ca efect nlocuirea vechii valori a proprietii cu <valoare>. Exemplu: > (get 'a 'color) ; initial proprietatea n-a fost setat nil > (setf (get 'a 'color) 'verde) ; apelul funciei setf verde > (get 'a 'color) ; noua valoare va fi regsit verde 3. (symbol-plist <atom>) Aceast funcie afieaz lista de proprieti asociate lui <atom>, mpreun cu valorile acestora. Exemplu: > (setf (get a color) rosu) rosu > (setf (get a forma) cub) cub > (symbol-plist a) (forma cub color rosu) 5

2. Generare automat de simboluri

(gentemp {<sir>}) Genereaz un nou simbol cu numele implicit Tx. La primul apel, va genera simbolul T0. Opional, i se poate preciza un alt prefix <sir> pentru simbolul generat. La fiecare apel se incrementeaz numrul x. Exemplu: > (setq x (gentemp)) T0 > (setq x (gentemp a)) A1 3. Problem S se creeze o ierarhie de clase de animale, plecnd de la o list dat. Se d o list de animale, fiecare animal este caracterizat prin anumite trsturi. Pentru fiecare animal, se vor preciza: clasa din care face parte i o list de proprieti (care se vor preciza n forma (proprietate valoare)). S se scrie o funcie LISP care parcurge lista de animale i le introduce n ierarhie. Exemplu. Clasele ierarhiei: Animal Vertebrat cu_singe_rece reptile pesti Nevertebrat cu_singe_cald mamifer pasari

Lista de animale ((cal mamifer (ierbivor da are_copite da)) (pisica mamifer (carnivor da are_coada da)) (calcan peste (traieste_n mare))).