rv01 vi lisp

84
Veštačka inteligencija Osnove Lisp-a Vladan Mihajlović Aleksandar Milosavljević

Upload: -

Post on 26-Oct-2015

40 views

Category:

Documents


2 download

DESCRIPTION

Lisp programiranje kome treba

TRANSCRIPT

Veštačka inteligencijaOsnove Lisp-a

Vladan MihajlovićAleksandar Milosavljević

2

Jezici VI

FunkcionalniLisp

LogičkiProlog

3

Zašto naučiti Lisp?

Eric Raymond “Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot.”

4

Osnovne osobine Lisp-a

Programi i podaci se tretiraju na istovetan način. Lispkoristi liste kao osnovne strukture podataka, a i poziv funkcije je lista čiji je prvi element ime funkcije (koristi se prefix notacija).Automatsko i dinamičko upravljanje memorijom. Sistem sam rezerviše i oslobađa memoriju prema potrebama. Jezik sa funkcionalnim načinom programiranja. Funkcionalno programiranje zasniva se na ideji da se rezultat svake funkcije može iskoristiti kao argument druge funkcije. Lisp omogućava komponovanje (kombinovanje) funkcija. Rekurzija je prirodni način programiranja.

5

Osnovne osobine Lisp-a

Interpretiran jezik. Primenjuje se ciklus read-eval-execute, Danas postoje i prevodioci za Lisp, a razvojna okruženja često nude i prevodioce i interpretatore. Obično postoji inkrementalno prevođenje.Ne postoje tipovi podataka. Lisp je programski jezik bez javne definicije tipa. Mnogi dijalekti nude mogućnost korišćenja tipova podataka, ali to nije neophodno. U tom slučaju provera i vezivanje tipa je dinamičko, tj. samo u procesu izvršenja.Jednostavna sintaksa. Lisp ima jednostavnu sintaksu, i može se primeniti kako za matematička izračunavanja, tako i za simboličku obradu.

6

Lisp - ukratko

Sve u Lisp-u je ili atom ili lista (izraz)Lista predstavlja podatak ili funkcijuNema deklarisanja tipova podataka, već se podaci dinamički vezuju za tipoveNema sekvencijalnog niza naredbi, već se rezultat postiže ugnježdavanjem i komponovanjem poziva funkcijaRekurzivni pozivi funkcija su suština programiranja u Lisp-uOmogućava definisanje izvršnih struktura jer su podaci i funkcije predstavljaju na isti način – listama

7

Osnovni elementi jezika Lisp

Simbolički izraz (S-izraz)Atom (simbol, broj, string, t, nil, …)

Nema razlike između malih i velikih slova (osim u stringovima)

Lista: elementi liste su atomi ili listePrvi element liste se tretira kao ime funkcije, ako ispred liste nije quote (')Ako je ako ispred liste quote (') onda se i prvi element liste tretira kao podatak

8

Atomi

Predefinisani literalni atomi (logičke konstante)T, t – TAČNO (True) Nil, nil, '() – NETAČNO (False) ili prazna lista

Numerički atomiNpr. 12 , -135.28

Tekstualni atomiNpr. ”A”, ”tekst”

LiteraliPočinju slovomNpr. a, vestacka, neki-atom_sa_dugackim-imenom, tema1

9

Liste

Lista atoma (elementi liste su atomi)(a b c)(1 b a 3 c)(1 2 3 4 a b)

Prava lista (elementi liste su atomi i druge liste)

((a b) (c d) (e f))(1 (2 3) (c d (e) f) 4 5)

10

Elementi jezika Lisp

KonstantePromenljiveFunkcije PredikatiProgram = Forme + FunkcijeForme

Samo-evaluirajućeLiteraliListe

Komentar – deo linije iza znaka ;Npr: ; prva linija komentara

11

Konstante i promenljive

KonstanteT, Nil, '()“string”1, 0, 5 – numeričke vrednosti'simbol#\a – karakter#( 1 2 3 ) – vektor

PromenljivePočinju slovomMogu biti različite dužineNema razlike između mali i velikih slova

12

Funkcije

Zadaju u prefiks notacijiPredstavljaju se listom, tako da je prvi element liste ime funkcije, a ostali elementi argumenti:

(ime-funkcije {argumenti})(ime-funkcije arg1, arg2, ... , argn)

Argumenti funkcija mogu biti konstante, literali, atomi, liste i pozivi drugih funkcija.Primeri poziva funkcije:

(+ 2 3 5 7 100)(car '(a b c))

13

Primeri funkcija

+5

49 +

3

917

(+ 5 4) (+ 3 5 9)

5

car(a b c d) a

(car ’(a b c d))

list3

9(3 5 9)

(list ’3 ’5 ’9)

5

14

Razlika između podataka i funkcija

Podaci i funkcije se predstavljaju kao listeLista kao podatak ima ispred oznaku ' (quote)

'(obj1 obj2 obj3 ... objn)quote(obj1 obj2 obj3 ... objn)'(+ 9 3) => (+ 9 3)(quote (+ 9 3)) => (+ 9 3)

Lista kao funkcija je obična lista(proc arg1 arg2 ... argn)(+ 9 3) => 12

15

Predikati

Posebna vrsta funkcijaVraćaju vrednost tačno (t) ili netačno ('())Obično se imena predikata označavaju sufiksom na različite načine<ime>-plistp, zerop

16

Sistemske funkcije

Numericke: +, -, *, /, log…Logicke: and, or, not, everyFunkcije za rad sa listama: cons, list, append, car, cdr, first, rest, nth, length…Predikati: atom, consp, listp, <, =, equal, member…

17

Numeričke funkcije

(+ 1 2 3 4 5) => 15(- 1 2 3 4 5) => -13(* 5 4 3) => 60(/ 12 3 2) => 2(1+ 3) => 4(mod 5 3) => 2(random 100) => 55(sqrt 2) => 1.4142135(exp 1) => 2.7182817(square 5) => 25

18

Logičke funkcije

(not obj) - negacija objekta obj(and obj1 obj2 … objn) - logičko I(or obj1 obj2 … objn) - logičko ILI(and '() '(1 2 3)) => ( )(or '() '(1 2 3)) => (1 2 3)(not '()) => t(or '(1 2 3) '(2 4 5)) => (1 2 3)

19

Funkcije za rad sa listama

conslist appendcar cdrfirstrestlength, itd.

20

Funkcija car

a b c da

car(a b c d) a

(car ’(a b c d)) => a

21

Funkcija cdr

a b c d

cdr(a b c d) (b c d)

(cdr ’(a b c d)) => (b c d)

a b c d

22

Funkcije car i cdr

Funkcija car vraća prvi element liste list kao rezultatOblik: (car list)(car '(1 2 3 4)) => 1(car 'a) => ()(car nil) => ()(car '((1 2) 3 4)) => (1 2)

Funkcija cdr vraća ostatak liste list, tj. svi elementi kao lista, osim prvogOblik: (cdr list)(cdr '(1 2 3 4)) => (2 3 4) (cdr 'a) => Error!(cdr nil) => ()(cdr '((1 2) 3 4)) => (3 4)

23

Funkcije car, cdr, first i rest

(cadr '(a b c)) => b ekvivalentno sa: (car (cdr '(a b c)))(caddr '(1 2 3 4 5)) => 3 ekvivalentno sa:

(car (cdr (cdr '(1 2 3 4 5))))(cdar '((1 2 3) 4 5)) => (2 3) ekvivalentno sa:

(cdr (car '((1 2 3) 4 5)))Funkcija first vraća prvi element liste kao rezultatOblik: (first list)(first '(1 2 3 4)) => 1Funkcija rest vraća ostatak liste, tj. svi elementi kao lista, osim prvogOblik: (rest list)(rest '(1 2 3 4)) => (2 3 4)car = first i cdr = rest

24

Funkcija cons

a b c db c d

cons(b c d)

(a b c d)

(cons ’a ’(b c d)) => (a b c d)

a

a

25

Funkcija cons

Funkcija cons dodaje element na početak liste (kao prvi element)Oblik: (cons elem list)Umeće elem na početak liste listDrugi argument funkcije mora biti lista(cons 'a '(b c d)) => (A B C D)(cons '(a b) (1 2 3 4 5)) => ((A B) 1 2 3 4 5)(cons '(a b c) '()) => ((A B C))Ako je drugi argument funkcije atom formira se lista s tačkom ispred drugog argumenta funkcije(cons 'a 'b) => (A . B)(cons '(a b c) 'd) => ((A B C) . D)

26

Funkcija list

a b c d

list (a b c d)

(list ’a ’b ’c ’d) => (a b c d)

a

a b c d

bcd

27

Funkcija list

Formira listu čiji su elementi argumenti funkcije (broj elemenata nove lista jednak je broju argumenata)Oblik: (list list1 list2 ... listn)Formira listu u kojoj svaki od argumenate predstavlja pojedinačnielement(list 'a 2 'b) => (A 2 B)(list '(a b) '(c d)) => ((A B) (C D))(list 'a) => (A)(list '()) => ('())(list 'a 'b 'c 'd) => (A B C D)(cons 'a (cons 'b (cons 'c (d)))) => (A B C D)Funkcija list* formira lista s tačkom ispred poslednjeg argumenta funkcije(list* 'a 'b 'c 'd) => (A B C . D)

28

Funkcija append

a b c d

append (a b c d)

(append ’(a b) ’(c d)) => (a b c d)

(c d)

(a b)

c d

a b

29

Funkcija append

Formira novu listu koja sadrži elemente iz liste prvog argumenta i elemente liste drugog argumenta funkcijeOblik: (append arg1 arg2 ... argn)Spaja prvi argument, drugi, treći i ostale u jedinstvenu listu, tj. vrši nadovezivanje listiArgumenti ove funkcije moraju biti liste(append '(1 2 3 4) '(a b c d)) => (1 2 3 4 A B C D)(append '(a b c) '(d (e f (g h i) j k l)) => (A B C D (E F (G H I) J K L)(append '() '(a)) => (A)Razlike između cons, list i append(cons '(a b) '(c d)) => ((A B) C D)(list '(a b) '(c d)) => ((A B) (C D))(append '(a b) '(c d)) => (A B C D)

30

Funkcija lenght

Funkcija vraća broj elemenata listeOblik: (lenght list)(length '(1 2 3 4 5)) => 5(length '()) => 0(lenght '(a (b c) d))) => 3(lenght '(a b c d (e f (g h i) j k l)) => 5

31

Funkcije nth i last

Ove funkcije vraćaju jedan element iz listeElementi liste imaju indekse koji počinju od 0.Funkcija nth vraća n-ti element liste ili praznu listu ako taj element liste ne postojiOblik: (nth list)(nth 2 '(1 2 3 4)) => 3(nth 4 '(1 2 3 4)) => '()(nth 1 '(a (b c) d))) => (B C)Funkcija last vraća poslednji element liste.Oblik: (last list)(last '(1 2 3 4)) => (4)(last '(a b c d (e f (g h i) j k l))) => ((e f (g h i) j k l))

32

Funkcije reverse

Funkcija reverse vraća listu sa svim elementima ulazne liste ali uređenim u obrnutom redosleduPri izmeni redosleda ne ulazi u podlisteOblik: (reverse list)(reverse '(a b c d)) => (D C B A)(reverse '((a b) (c d))) => ((C D) (A B))

33

Predikati atom i listp

Predikat atom vraća logičku vrednost tačno (t) ako je argument atom u suprotnom netačno.Oblik: (atom arg)(atom '(1 2 3 4 5)) => '()(atom '()) => T(atom 'a) => TPredikat listp vraća logičku vrednost tačno (t) ako je argument lista u suprotnom netačno.Oblik: (listp arg)(listp '(1 2 3 4 5)) => T(listp '()) => '()(listp 'a) => '()

34

Predikati null, zerop i functionp

Predikat null vraća logičku vrednost tačno (t) ako je argument prazna lista.Oblik: (null arg)(null '(1 2 3 4 5)) => '()(null 'a) => '()(null '()) => TPredikat zerop vraća logičku vrednost tačno (t) ako je argument lista jednak 0.Oblik: (zerop arg)(zerop '(1 2 3 4 5)) => '()(zerop '0) => TPredikat functionp vraća logičku vrednost tačno (t) ako je argument predikata funkcija.Oblik: (functionp arg)(functionp #’zerop) => T(functionp ’zerop) => '()

35

Predikati poređenja

Predikati poređenja ispituju da li su dva objekta jednaka (razlikuju se po načinu poređenja, tj da li su fizički identični u memoriji, operaciono identični, ili identični po vrednosti):(eq obj1 obj2) – ispituje da li su adrese objekata jednake(eql obj1 obj2) – ispituje da li su objekti logički jednaki(eqv obj1 obj2) – ispituje da li su objekti operaciono jednaki(equal obj1 obj2) – ispituje da li su objekti jednaki po strukturi i vrednosti(equalp obj1 obj2) – ispituje da li su objekti jednaki po vrednosti(equal 'a 'b) => '() (equalp 'a 'b) => '()(equal 'a 'a) => T (equalp 'a 'a) => T(equal 3 3) => T (equalp 3 3) => T(equal 3 3.0) => '() (equalp 3 3.0) => T(equal 3.0 3.0) => T (equalp 3.0 3.0) => T

36

Funkcije klase member

Funkcija member ispituje da li element postoji u listi i vraća listu koja sadrži elemente liste počevši od prvog pojavljivanja prvog argumenta (uključujući i njega) do krajaOblik: (member elem list)(member '2 lista) => (2 3 4 5) (member 2 '(1 2 3)) => (2 3)(member 'e '(a b c d)) => '()(member 'a '((a b) c d)) => '()(member '(d e) '((a b) c (d e) f)) => ‘()Funkcije member-if i member-if-not ispituju da li predikat koji je prvi argument vraća tačno primenjen na elemente liste drugog argumentaOblik: (member-if pred list) i (member-if-not pred list)(member-if #'atom '((a b) c d)) => (C D)(member-if #'numberp '(a #\Space 5 rec)) => (5 rec) (member-if-not #listp '((a b) c d)) => (C D)

37

Postavljanje globalnih promenljivih

Funkcije setq i setf vraća naziv promenljive čiji se sadržaj postaje lista navedena kao drugi argument funkcijeOblik: (setq var list) i (setf var list)(setq lista '(1 2 3 4 5)) => lista(lista) => (1 2 3 4 5)(setq alista ((A (1 5)) (B (2 6)))) => alista(alista) => ((A (1 5)) (B (2 6)))Napomena: Za definisanje promenljivih dovoljno je pozvati jednu od ovih funkcija.

38

Uslovna funkcija if

Funkcija if ako je uslov ispunjen vraća rezultat then izraza, u suprotnom rezultat else izraza ako postoji ili praznu listuOblik: (if test then_form else_form)Uslov (test) je predikatThen izraz i else izraz mogu biti promenljive, atomi, liste ili pozivi funkcije(setq lista '(1 2 3 4 5)) => (1 2 3 4 5)(if (listp lista) (car lista) (cdr lista)) => 1(if (equal (car lista) (cadr lista)) (car lista)) => '()

39

Uslovna funkcija cond

Funkcija cond omogućava postavljanje višestrukih uslova i grananja. Oblik: (cond (test1 exp1) (test2 exp2) ... (testN expN))Uslov (test) koji se ispituje je relacioni operator ili predikatIzraz je promenljiva, atom, lista ili poziv funkcijeUslovi (test) se ispituju sekvencijalno po redu navođenja i funkcija cond vraća rezultat izraza (exp) za uslov koji je zadovoljen(cond ((equal op 'zbir) (+ x y))

((equal op 'proizvod) (* x y))(t '(nedefinisano)))

40

Definisanje funkcija

Za definisanje se koristi makro defun.Oblik: (defun name (arg...) exp)Ime je naziv funkcije i mora se razlikovati od većpostojećih funkcija,Argumenti su navedeni kao lista i prenose se po vrednostiTelo funkcije čine ugnježdeni i komponovani pozivi funkcijaIzlaz iz funkcije je rezultat poslednje izvršene funkcije iz tela(defun kvadrat (n) (* n n)) => KVADRAT(kvadrat 3) => 9

41

Funkcije za rotiranje

(defun rotate-left (l)(append (cdr l)

(list (car l))))(rotate-left '(a b c d e f)) => (B C D E F A)(defun rotate-right (l)

(cons (car (reverse l))(reverse (cdr (reverse l)))))

(rotate-right '(a b c d e f)) => (F A B C D E)

42

Izračunavanje faktorijela

Napisati funkciju na lispu koja određuje faktorijel broja4! = 4 * 3!3! = 3 * 2!2! = 2 * 1!1! = 1 * 0!0! = 11! = 1 * 12! = 2 * 13! = 3 * 24! = 4 * 6Rekurzivna formula:n! = n * (n-1)!Završetak rekurzije:0! = 1

43

Izračunavanje faktorijela

(defun fact (n)(if (= n 0) '1

(* n (fact (1- n)))))(fact 5) => 120(fact 5) => (* 5 (fact 4)) => (* 5 (* 4 (fact 3)))=> (* 5 (* 4 (* 3 (fact 2))))=> (* 5 (* 4 (* 3 (* 2 (fact 1)))))=> (* 5 (* 4 (* 3 (* 2 (* 1 (fact 0))))))=> (* 5 (* 4 (* 3 (* 2 (* 1 1))))) => (* 5 (* 4 (* 3 (* 2 1))))=> (* 5 (* 4 (* 3 2))) => (* 5 (* 4 6)) => (* 5 24) =>120

44

Logika programiranja u Lisp-u

Koraci obrade listeUslov za kraj – ako je lista prazna vratiti odgovarajuću vrednost (obično praznu listu)Ispitivanje i obrada prvog elementa liste –ispitati da li prvi element liste zadovoljava zadati uslov i izvršiti njegovu obradu na odgovarajući načinNastaviti sa obradom ostatka liste –ukomponovati rekurzivni poziv funkcije, uz promenu argumenta, sa pozivom funkcija za rad sa listama prema zahtevu zadatka obrade

45

Određivanjebroja elemenata liste

Napisati funkciju na lispu koja određuje broj elemenata liste(broj '(a b c d)) = 1 + (broj '(b c d))(broj '(b c d)) = 1 + (broj '(c d))(broj '(c d)) = 1 + (broj '(d)) (broj '(d)) = 1 + (broj '()) (broj '()) = 0(broj '(a b c d)) = 1 + 1 + 1 + 1 + 0Obrada: povećati broj elemenata liste za 1 i nastaviti sa obradom ostatka listeZavršetak: prazna lista nema nijedan element

46

Određivanjebroja elemenata liste

(defun broj (l)(cond ((null l) '0)

(t (1+ (broj (cdr l))))))(broj '(a b c d e f)) => 6(broj '(a b (c d e) f) => 4

47

Određivanjebroja elemenata liste

(defun clanp (el l)(cond ((null l) '())

((equal el (car l)) t)(t (clanp el (cdr l)))))

(clanp 'a '(a b c)) => t(clanp '(1 2) '((1 2 3) 4 (1 2) 5 6)) => t(clanp '(1 2) '((1 2 3) (4 (1 2) 5) 6)) => '()

48

Određivanje pozicijemaksimalnog elementa liste

(defun maxpoz (l)(if (null l) '() (maxpoz1 0 1 l)))

(defun maxpoz1 (maxp ind lp)(cond ((null (cdr lp)) maxp)

((> (car lp) (cadr lp))(maxpoz1 maxp (1+ ind)

(cons (car lp) (cddrlp))))

(t (maxpoz1 ind (1+ ind) (cdrl )))))

49

Rotiranje elemenata liste

(defun rotate-right (l)(cond ((null l) '())

(t (rotright (list (car l)) l))))(defun rotright (l1 l2)

(cond ((null l2) '())((null (cdr l2)) (cons (car l2) l1))(t (rotright (append l1 (car l2)) (cdr l2)))))

(rotate-right '(a b c d e f)) => (F A B C D E)(rotate-right '(a (b c (d e)) f (g h)))

=> ((G H) A (B C (D E)) F)

50

Funkcije remove

Funkcija remove briše sva pojavljivanja zadatog elementa iz listeOblik: (remove elem list)(remove '1 '(1 2 3 4 5)) => (2 3 4 5)(remove 'a '(1 2 3 4 5)) => (1 2 3 4 5)(remove '1 '(a 1 2 3 1 5) :test 'equal :from-end t) => (A 2 3 5)(remove '1 '((a 1) (2 3) (1) (5)) :test 'member :from-end t) =>((2 3) (5))(remove '1 '((a 1) (2 3) (1) (5)) :test 'equal :key 'car) =>((A 1) (2 3) (5))(remove '1 '((a 1) (2 3) (1) (5)) :test-not 'equal :key 'car) =>((1))Funkcija remove-duplicates vraća listu koja nema duplikataOblik: (remove-duplicates list)(remove-duplicates '((a 2)(b 3)(c 5)(d 3)) :test 'equal :key 'cadr:from-end t) => ((A 2) (B 3) (C 5))

51

Asocijativne liste

Asocijativna lista je lista kod koje je svaki element lista sa dva elementa. Prvi element podliste je ključ, a drugi odgovarajuća vrednost. ((A 1) (B 3) (C 10))((A (1 5)) (B (2 6)) (C (3 7)))Funkcija za pristup vrednostima asocijativne liste na osnovu ključa je assocFunkcija assoc vraća podlistu argumenta alist (mora biti asocijativna lista) čiji je ključ jednak argumentu keyOblik: (assoc key alist)(assoc 'B ((A 1) (B 3) (C 10))) => (B 3)(assoc 'C ((A (1 5)) (B (2 6)) (C (3 7)))) => (C (3 7))

52

Liste osobina

Liste osobina su osobine koje se pridružuju navedenom simbolu.Jednom simbolu se može pridružiti više osobina, i svakoj osobini se mogu dodeljivati i menjati vrednosti. Funkcija gensym generiše novi simbol.Oblik: (gensym)Poziv iste funkcije sa argumentom “s” omogućava formiranje simbola koji počinju slovom “s”:Oblik: (gensym 's)Funkcija get čita vrednosti osobine key simbola sym.Oblik: (get sym key) Funkcija set postavlja vrednost osobine key simbola sym.Oblik:(set (get sym key) val)

53

Postavljanje globalnih promenljivih

Funkcije setq i setf vraća naziv promenljive čiji se sadržaj postaje lista navedena kao drugi argument funkcijeOblik: (setq var list) i (setf var list)(setq lista '(1 2 3 4 5)) => lista(lista) => (1 2 3 4 5)(setq alista ((A (1 5)) (B (2 6)))) => alista(alista) => ((A (1 5)) (B (2 6)))Napomena: Za definisanje promenljivih dovoljno je pozvati jednu od ovih funkcija.

54

Postavljanje lokalnih promenljivih

Funkcije let i let* dodeljuje promenljivoj (id) listu (val) i vraća vrednost izraza (exp) Oblik: (let ((id val)...) exp)Oblik: (let* ((id val)...) exp)Moguće je definisanje više promenljivih jednom naredbomBitno: domen važenja promenljive je let izraz (exp) (let ((x 3)) (+ x 3)) => 6(let ((a 5) (b 6)) (* a b)) => 30(let ((x 1)) (let ((x (+ x 1))) (+ x 2))) => 4(let ((x 9)) (* x (let ((x (/ x 3))) (+ x x)))) => 54(let ((x 9)) (* x (let ((x (/ x 3))) x) (+ x x))) => 486

55

Razlike let i let*

Funkcije let i let* se razlikuju po redosledu dodele vrednosti.Funkcija let dodeljuje vrednosti paralelno svim promenljivamaFunkcija let* dodeljuje vrednosti sekvencijalnopromenljivama(let ((x 0) (y 1))

(let ((x y) (y x))(list x y))) => (1 0)

(let ((x 0) (y 1))(let* ((x y) (y x))

(list x y))) => (1 1)

56

Definisanjeparametara, konstanti i promenljivih

Definisanje parametara: (defparameter *p* 1) => *P* - definisan parametar *p*, dodeljena mu je vrednost 1Vrednost parametra se može jednostavno prikazati: *p* => 1Definisanje konstanti: (constantp '*p*) => false -definisanje konstante *p* (može se definisati iako je pre toga definisan parametar sa istim imenom)(setq *p* 2) => 2 - postavljanje vrednosti za *p* na 2(defparameter *p* 3) => *P* *p* => 3(defvar *v* 1) => *V* - definisanje promenljive *v* sa početnom vrednošću 1*v* => 1 - pristupanje vrednosti promenljive *v*(constantp *v*) => '() - definisanje konstante *v* (setq *v* 2) => 2 - postavljanje vrednosti za *v* na 2(defvar *v* 3) => *V* - ponovo definisanje promenljive *v* sa početnom vrednošću 3

57

Funkcije za evaluaciju izraza

U Lisp-u se podaci i funkcije tretiraju na isti način. Zbog toga postoje funkcije koje omogućavaju evaluaciju izraza, tj. listi koje su pre toga tretirane kao podaci.Funkcija eval izvršava funkciju koja je prvi element u argumentuOblik: (eval arg)(eval '(+ 2 3)) => 5Funkcija apply primenjuje funkciju na listuOblik: (apply fun list)(apply 'car '(a b c d)) => A

58

Iteracije

Iteracija: do, do*, dolist, dotimes, dolist, loop, loop-finishNajčešće korišćena funkcija je do, koja odgovara standardnoj DO petlji u drugim programskim jezicima, s tim da se u Lisp-u mogu definisati i više “paralelnih”petlji:(do ({var | (var [ init-form [step-form ]])}*)

(end-test-form {result-form}*){declaration}* {tag | statement}* )

(do ( (temp-one 1 (1+ temp-one))(temp-two 0 (1- temp-two)) )

((> (- temp-one temp-two) 5) temp-one)) => 4

59

Funkcije do, do* i dolist

(do ( (temp1 1 (1+ temp1))(temp2 0 (1+ temp1)) )

((= 3 temp2) temp1)) => 3(do* ( (temp1 1 (1+ temp1))

(temp2 0 (1+ temp1)) )((= 3 temp2) temp1)) => 2

Funkcija dolist omogućava iterativnu obradu elemenata liste.(setq temp2 '()) => '()(dolist (temp1 '(1 2 3 4) temp2)

(append temp1 temp2)) => (4 3 2 1)

60

Funkcije za definisanje niza naredbi

Funkcije prog1 i progn omogućavaju definisanje niza naredbi kao u standardnim programskim jezicimaFunkcija prog1 vraća rezultat poziva prve funkcije u nizu (func1).Oblik: (prog1 func1 func2 ... funcn)Funkcija prog1 vraća rezultat poziva poslednje funkcije u nizu (funcn).Oblik: (progn func1 func2 ... funcn)(prog1 (setq x 'mis) (setq x 'slon) (setq x 'tigar) 'dobro)=> mis(progn (setq x 'mis) (setq x 'slon) (setq x 'tigar) 'dobro)=> dobro

61

Klasa map funkcija

Funkcija mapfun sekvencijalno poziva funkciju definisanu u mapfun (fun) za svaki element liste i nad rezultatom izvršava funkciju (func) i rezultat vraća na mesto elementa stare liste.Oblik: (mapfun func list)(setq words '((one jedan) (two dva) (three tri)))(mapcar 'car words) => (one two three)(mapcar 'cadr words) => (jedan dva tri)(mapcar 'reverse words) => ((jedan one) (dva two) (tri three))(mapcon 'reverse words) => ((three tri) (two dva) (one jedan) (three tri) (two dva) (three tri))

62

Funkcija mapcar

(one jedan) (three tri)(two dva)mapcar

car

(one jedan) (three tri)(two dva)

car car

63

Funkcija lambda

Ova funkcija omogućuje izvršavanje poziva više funkcija pri korišćenju map funkcijaFunkcija lambda povezuje promenljivu (var) sa elementom liste koju izdvaja map funkcija i poziva funkcije argumente lambda nad ovim elementom. Rezultat se prosleđuje map funkciji.Oblik: (mapfun (lambda (var) func...) list)(mapcar (lambda (x) (* x x)) '(1 2 3 4 5))=> (1 4 9 16 25)(mapcar (lambda (x) (car x) (cadr x)) words)=> (jedan dva tri)

64

Strukture

Strukture u Lisp-u odgovaraju strukturama u drugim programskim jezicimaStruktura se definiše funkcijom defstruct(defstruct struct_name slot1 … slotn)Slotovi su elementi strukture kojima se može dodeliti vrednost.Funkcija za pravljenje strukture: make-struct_nameFunkcije za pristup slotovima: struct-name_slot1, struct_name-slotnPredikat ispitivanja pripadnosti strukture: struct_name-pFunkcija kopiranja strukture: copy-struct_name

65

Kreiranje i korišćenje struktura

(defstruct predmet naziv godina semestar)

(setq vestacka(make-predmet

:naziv "vestacka“:godina '4 :semestar 8))

(defstruct rectangleheightwidth)

(defstruct circleradius)

(defun area (x)(cond ((rectangle-p x)

(* (rectangle-height x)(rectangle-width x)))

((circle-p x)(* pi (expt (circle-radius x)

2))))) (let ((r (make-rectangle)))

(setf (rectangle-height r) 2(rectangle-width r) 3)

(area r)) => 6(let ((c (make-circle)))

(setf (circle-radius c) 5)(area c)) => 6

66

Ulaz i izlaz u Lisp-u

Funkcija read je ekvivalent funkciji cin u jeziku C++. Čita se ce red unet sa tastature.Primer: (setq A (read))Funkcije princ i print služe za ispis na ekranu. Razlika je u izlazu iz funkcije, dok je ispis isti.(princ "sam") => "sam" sam(print "sam") => "sam" "sam"(defun out ()

(print "sam") (princ "sam"))(out) => "sam" "sam" sam "sam"

67

Funkcija format

Za formiranje preglednijeg izlaza koristi se funkcija format.Konverzija ~a se upotrebljava jer radi za sve tipove podataka(defun zdravo1 () (format t “zdravo"))(zdravo1) => “zdravo"(defun zdravo2 (N) (format t "~%zdravo ~a" N))(zdravo2 MIlane) => “zdravo Milane“(setq lista '(M I L A N)) => lista(defun stampaj_listu (l) (format t "~% Lista: ~a" l))(stampaj_listu lista) => “(M I L A N)“

68

Pravljenje liste atoma

(defun flatten (l)(cond ((null l) '())

((atom l) (list l))((atom (car l))

(cons (car l) (flatten (cdr l))))(t (append (flatten (car l))

(flatten (cdr l))))))(flatten '(1 2 3)) => (1 2 3)(flatten '(1 2 (3 4) 5)) => (1 2 3 4 5) (flatten '(1 2 ((3 4) 5 (6)) 7)) => (1 2 3 4 5 6 7)

69

Izvršenje funkcije flatten

(flatten '(1 2 (3 4) 5)) =>(cons '1 (flatten '( 2 (3 4) 5)) =>(cons '1 (cons '2 (flatten '( (3 4) 5)) =>(cons '1 (cons '2 (append (flatten (3 4)) (flatten (5))))) =>(cons '1 (cons '2 (append (cons '3 (flatten (4))) (flatten (5))))) =>(cons '1 (cons '2 (append (cons '3 (cons 4 (flatten '()) (flatten (5))))) =>(cons '1 (cons '2 (append (cons '3 (cons 4 '()) (flatten (5))))) =>(cons '1 (cons '2 (append (cons '3 '(4)) (flatten (5))))) =>(cons '1 (cons '2 (append '(3 4) (flatten (5))))) =>(cons '1 (cons '2 (append '(3 4) (cons '5 (flatten '())))) =>(cons '1 (cons '2 (append '(3 4) (cons '5 '()))) =>(cons '1 (cons '2 (append '(3 4) '(5))) =>(cons '1 (cons '2 '(3 4 5))) =>(cons '1 '(2 3 4 5)) =>(1 2 3 4 5)

70

Brisanje zadatog elementa liste

(defun obrisi (el l)(cond ((null l) '())

((equal el (car l)) (obrisi el (cdr l)))(t (cons (car l) (obrisi el (cdr l))))))

(obrisi 'a '(a b (a f) j a k)) => (B (A F) J K)(obrisi '(1 2) '(1 2 (1 2 3) 6 (1 2) 8 3

(5 (1 2) 4)))=> (1 2 (1 2 3) 6 8 3 (5 (1 2) 4)))

71

Brisanje zadatog elementa liste

(defun obrisi-sve (el l)(cond ((null l) '())

((equal el (car l)) (obrisi-sve el (cdr l)))((atom (car l)) (cons (car l) (obrisi-sve el (cdr l))))(t (cons (obrisi-sve el (car l))

(obrisi-sve el (cdr l))))))

(obrisi-sve 'a '(a b (a f) j a k)) => (B (F) J K)(obrisi-sve '(1 2) '(1 2 (1 2 3) 6 (1 2) 8 3 (5 (1 2) 4)))

=> (1 2 (1 2 3) 6 8 3 (5 4)))

72

Okretanje redosleda elemenata liste

Šta uraditi s prvim elementom liste?Prvi element liste treba postaviti na poslednju poziciju, a ostale ispred njega.

Šta uraditi sa ostalim članovima liste?Ostatku liste treba okrenuti redosled.

Kako povezati prvi obrađeni član liste sa ostatkom liste nakon obrade?

Izlaz funkcije je lista, pa se povezivanje obavlja nekom od funkcija za pravljenje liste.

Kada se obrada završava i koji je povratna vrednost za kraj?

Kada je ulazna lista prazna. Povratna vrednost je neutralni element za pravljenje liste – prazna lista.

73

Okretanje redosleda elemenata liste

(defun okreni (l)(cond ((null l) '())

(t (append (okreni (cdr l)) (list (car l))))))

(okreni '(a b c)) => (C B A)(okreni '(a (b c) d e f)) => (F E D (B C) A)(okreni '(a (b c (d e) f) g (h i))) => ((H I) G (B C(D E) F) A)

74

Okretanje redosleda elemenata liste

(defun okreni-sve (l)(cond ((null l) '())

((atom (car l))(append (okreni-sve (cdr l)) (list (car l))))

(t (append (okreni-sve (cdr l))(list (okreni-sve (car l)))))))

(okreni-sve '(a b c)) => (C B A)(okreni-sve '(a (b c) d e f)) => (F E D (C B) A)(okreni-sve '(a (b c (d e) f) g (h i)))

=> ((I H) G (F (E D) C B) A)

75

Presek skupova

Rešenje: Uporediti sve elemente prve liste se poredi sa elementima druge liste.Element prve liste upoređuje se sa svim elementima druge liste.Ako je element prve liste jednak bilo kom elementu druge dodati ga u izlaznu listu.Ako je element prve liste ne nalazi u drugoj preći na sledeći element prve liste.

Postoje dve rekurzije, za elemente prve liste i druge liste, koje treba realizovati jednom funkcijom.

Definisati uslov koji će da razdvoji prvu rekurziju od druge.

76

Presek skupova

(defun presek (l1 l2)(cond ((null l1) '())

((null l2) '())((atom l1) (if (equal l1 (car l2)) (list l1)

(presek l1 (cdr l2))))(t (append (presek (car l1) l2)

(presek (cdr l1) l2)))))

(presek '(a b d) '(g)) => () (presek '(1 3 4) '(5 1 2)) => (1)(presek '(a b d e f j k m) '(a c d e j l m))

=> (A D E J M)

77

Predstavljanje stabla i grafa

((cvor1 (pot11 pot12 ...))

(cvor2(pot21 pot22 ...))...)

(setq graf'((A (B C)) (B (D E))(C (F G)) (D (H))(E (I)) (F (J)) (G (J))(H) (I (J)) (J)))

B

FD

H

C

A

J

I

E

G

78

Stablo i graf – jednostavne funkcije

Izdvajanje liste svih čvorova u grafu(defun izdvoji (graf)

(if (null graf) '()(cons (caar graf) (izdvoji (cdr graf))))))

(izdvoji graf) => (A B C D E F G H I J)Izdvajanje listova u grafu(defun izdvojiL (graf)

(cond ((null graf) '())((null (cdar graf))

(cons (caar graf) (izdvojiL (cdr graf))))(t (izdvojiL (cdr graf)))))

(izdvojiL graf) => (H J)

79

Stablo – izdvajanje sledbenika

(defun sledS (cvor stablo)(cond ((null stablo) '())

((equal (caar stablo) cvor)(if (null (cdar stablo))

'() (cadar stablo)))(t (sledS cvor (cdr stablo)))))

(sledS 'B graf) => (D E)(sledS 'D graf) => (H)(sledS 'H graf) => ()

80

Graf – izdvajanje sledbenika

(defun sledG (cvor graf obradjeni)(cond ((null graf) '())

((equal (caar graf) cvor)(dodaj (cadar graf) obradjeni))

(t (sledG cvor (cdr graf) obradjeni))))(defun dodaj (potomci obradjeni)

(cond ((null potomci) '())((member (car potomci) obradjeni)

(dodaj (cdr potomci) obradjeni))(t (cons (car potomci)

(dodaj (cdr potomci) obradjeni)))))(sledG 'B graf ‘(A D G)) => (E)

81

Dodavanje elementa u graf

(defun dodavanje (graf cvor potomci roditelji)(dodaj_veze (dodaj_cvor graf cvor potomci) cvor roditelji))

(defun dodaj_cvor (graf cvor potomci)(cond ((null graf) (list (cons cvor (list potomci))))

((equal cvor (caar graf)) (cons (cons (caar graf)(list (dodaj potomci (cadar graf)))) (cdr graf)))

(t (cons (car graf) (dodaj_cvor (cdr graf) cvor potomci)))))(defun dodaj_veze (graf cvor roditelji)

(cond ((null roditelji) graf)(t (dodaj_veze (dodaj_pot graf (car roditelji) cvor)

cvor (cdr roditelji)))))(defun dodaj_pot (graf cvor pot)

(cond ((null graf) graf)((equal cvor (caar graf)) (cons (cons (caar graf)

(list (append (cadar graf) (list pot)))) (cdr graf)))(t (cons (car graf) (dodaj_pot (cdr graf) cvor pot)))))

82

Sortiranje liste atoma

(defun sort (l op)(cond ((null l) '())

(t (umetni (car l) (sort (cdr l) op) op))))(defun umetni (el l op)

(cond ((null l) (list el))((apply op (list el (car l))) (cons el l))(t (cons (car l) (umetni el (cdr l) op)))))

(sort '(4 6 2 8 1) '<) => (1 2 4 6 8)(sort '(4 6 2 8 1) '>) => (8 6 4 2 1)

83

Sortiranje liste atoma

(defun sort (l op)(cond ((null l) '())

(t (dodaj (car l) (sort (cdr l) op) op))))(sort '(4 6 2 8 1) '<)=> (dodaj '4 (sort '(6 2 8 1) '<) '<)=> (dodaj '4 (dodaj '6 (sort '(2 8 1) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 (sort '(8 1) '<) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 (dodaj '8 (sort '(1) '<) '<) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 (dodaj '8 (dodaj '1 (sort '() '<) '<) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 (dodaj '8 (dodaj '1 '() '<) '<) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 (dodaj '8 '1 '<) '<) '<) '<)=> (dodaj '4 (dodaj '6 (dodaj '2 '(1 8) '<) '<) '<)=> (dodaj '4 (dodaj '6 '(1 2 8) '<) '<)=> (dodaj '4 '(1 2 6 8) '<)=> (1 2 4 6 8)

84

Sortiranje liste atoma

(defun dodaj (el l op)(cond ((null l) (list el))

((apply op (list el (car l))) (cons el l))(t (cons (car l) (dodaj el (cdr l) op)))))

(dodaj '8 '1 '<) => (cons '1 (dodaj '8 '() '<))=> (cons '1 '(8)) => (1 8)(dodaj '2 '(1 8) '<)=> (cons '1 (dodaj '2 '(8) '<))=> (cons '1 '(2 8)) => (1 2 8)(dodaj '6 '(1 2 8) '<)=> (cons '1 (dodaj '6 '(2 8) '<))=> (cons '1 (cons '2 (dodaj '6 '(8) '<)))=> (cons '1 (cons '2 '(6 8)))=> (cons '1 '(2 6 8)) => (1 2 6 8)