Paradigmata programování 1

Podobné dokumenty
Paradigmata programování 1

PARADIGMATA PROGRAMOVÁNÍ 2 PŘÍSLIBY A LÍNÉ VYHODNOCOVÁNÍ

PARADIGMATA PROGRAMOVÁNÍ 2A INTERPRET S VEDLEJŠÍMI EFEKTY A MAKRY

Paradigmata programování 1

Paradigmata programování 1

1. Od Scheme k Lispu

Paradigmata programování II Přednáška 2: Mutace

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA III

PARADIGMATA PROGRAMOVÁNÍ 2A MAKRA I

Funkcionální programování úvod

Paradigmata programování 1

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 3. CVIČENÍ

Reprezentace aritmetického výrazu - binární strom reprezentující aritmetický výraz

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

PARADIGMATA PROGRAMOVÁNÍ 2A MUTACE

Slepé prohledávání do šířky Algoritmus prohledávání do šířky Při tomto způsobu prohledávání máme jistotu, že vždy nalezneme koncový stav, musíme ale p

LISP Definice funkcí

Přednáška 3. Rekurze 1

Paradigmata programování II Přednáška 1: Vedlejší efekt

Algoritmizace a programování

Paradigmata programování II Korutiny a nedeterminismus

PARADIGMATA PROGRAMOVÁNÍ 2A VEDLEJŠÍ EFEKT

Hanojská věž. T2: prohledávání stavového prostoru. zadání [1 1 1] řešení [3 3 3] dva možné první tahy: [1 1 2] [1 1 3]

Virtuální počítač. Uživatelský program Překladač programovacího jazyka Operační systém Interpret makroinstrukcí Procesor. PGS K.

Dokumentace programu sdc

Paradigmata programování II Přednáška 6: Líné vyhodnocování, proudy a kešované vyhodnocování

PARADIGMATA PROGRAMOVÁNÍ 2 KORUTINY, NEDETERMINISMUS

PARADIGMATA PROGRAMOVÁNÍ 2 AKTUÁLNÍ POKRAƒOVÁNÍ

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 5. CVIČENÍ

Operátory. Základy programování 1 Tomáš Kühr

Prolog PROgramming in LOGic část predikátové logiky prvního řádu rozvoj začíná po roce 1970 Robert Kowalski teoretické základy Alain Colmerauer, David

Automaty a gramatiky(bi-aag) Formální překlady. 5. Překladové konečné automaty. h(ε) = ε, h(xa) = h(x)h(a), x, x T, a T.

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

5 Přehled operátorů, příkazy, přetypování

(pracovní verze textu určená pro studenty)

Základní datové struktury

Přednáška 7. Celočíselná aritmetika. Návratový kód. Příkazy pro větvení výpočtu. Cykly. Předčasné ukončení cyklu.

Úvod do programovacích jazyků (Java)

Operátory. Základy programování 1 Martin Kauer (Tomáš Kühr)

Algoritmizace a programování

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Anotace. zpět k rekurzi: teorie her. Martin Pergel,

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Jazyk Scheme: jeho syntax a sémantika

Definice uživatelského typu. Uživatelem definované typy. Součinové datové typy. Součtové datové typy. FLP - Uživatelem definované typy

NPRG030 Programování I, 2018/19 1 / :25:37

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

Lokální definice (1) plocha-kruhu

Da D to t v o é v ty t py IB111: Datové typy

CZ.1.07/1.5.00/

Prohledávání do šířky = algoritmus vlny

ALGORITMIZACE PRAKTICKÉ

X36UNX 16. Numerické výpočty v sh příkazy expr, bc, dc. Zdeněk Sojka

Programování v jazyce JavaScript

Stefan Ratschan. Fakulta informačních technologíı. Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Stromy. Příklady. Rekurzivní datové struktury. Základní pojmy

Implementace LL(1) překladů

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Programovací jazyk Pascal

Logické programování I

1. Převeďte dané číslo do dvojkové, osmičkové a šestnáctkové soustavy: a) b)

Tvorba výrazu: speciální znaky shellu se uvádějí do apostrofů jednotlivé části výrazu se oddělují mezerou

Paradigmata programování 2

LEKCE 6. Operátory. V této lekci najdete:

VZORCE A VÝPOČTY. Autor: Mgr. Dana Kaprálová. Datum (období) tvorby: září, říjen Ročník: sedmý

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

C# konzole Podíl dvou čísel, podmínka IF

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

MQL4 COURSE. By Coders guru -4 Operace & Výrazy

Paradigmata programování 1 poznámky k přednášce. 3. Rekurze 1

Racionální čísla, operátory, výrazy, knihovní funkce

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Anotace. Dámy na šachovnici dominance a nezávislost. Aritmetické výrazy, notace a převody mezi nimi, nejdelší rostoucí podposloupnost.

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 2. CVIČENÍ

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

IB015 Neimperativní programování. Organizace a motivace kurzu, programovací jazyk Haskell. Jiří Barnat

Programovací jazyk Haskell

Stream API. Petr Krajča. Základy programovaní 4 (Java) Katedra informatiky Univerzita Palackého v Olomouci

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

GENEROVÁNÍ KÓDU 9. SHRNUTÍ - PŘÍKLAD POSTUPU PŘEKLADU VSTUPNÍHO PROGRAMU (ZA POUŽITÍ DOSUD ZNÁMÝCH TECHNIK)

Implementace aritmetického stromu pomocí směrníků

Lisp 7-1. opakování destruktivních změn seznamů

Funkcionální programování. Kristýna Kaslová

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Programovací í jazyk Haskell

Racionální čísla, operátory, výrazy, knihovní funkce

Generování vnitřní reprezentace programu

ZÁPOČTOVÁ PRÁCE z UIR

Pokročilá algoritmizace amortizovaná složitost, Fibonacciho halda, počítačová aritmetika

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Syntaktická analýza. Implementace LL(1) překladů. Šárka Vavrečková. Ústav informatiky, FPF SU Opava

IB015 Neimperativní programování. Časová složitost, Typové třídy, Moduly. Jiří Barnat Libor Škarvada

Pracovní listy - programování (algoritmy v jazyce Visual Basic) Algoritmus

Booleovská algebra. Booleovské binární a unární funkce. Základní zákony.

Zápis programu v jazyce C#

Základy algoritmizace a programování

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

VI. Derivace složené funkce.

Transkript:

Paradigmata programování 1 Kvazikvotování a manipulace se symbolickými výrazy Vilém Vychodil Katedra informatiky, PřF, UP Olomouc Přednáška 11 V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 1 / 38

Přednáška 11: Přehled 1 Kvazikvotování rozdíl mezi speciálními formami quote a quasiquote vkládání hodnot pomocí unquote a unquote-splicing syntaktický cukr pro kvazikvotování 2 Práce se symbolickými výrazy zjednodušování aritmetických výrazů dvou argumentů zjednodušovací tabulky zjednodušování operací více argumentů symbolické derivace převod symbolických výrazů mezi různými notacemi 3 Vyhodnocování symbolických výrazů postfixové vyhodnocování zásobníkový model vyhodnocování bezzávorkových výrazů V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 2 / 38

Kvazikvotování Speciální formy quote a quasiquote quote vrací svůj argument bez vyhodnocení (známe), quasiquote jako quote, ale u některých podvýrazů lze vynutit vyhodnocení Příklad (identické chování quote a quasiquote) (quasiquote 15) = 15 (quasiquote symbol) = symbol (quasiquote (x. 3)) = (x. 3) (quasiquote (1 2 (3 4) 5)) = (1 2 (3 4) 5) Syntaktický cukr: (quote expr ) ' expr (quasiquote expr ) ` expr V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 3 / 38

Použití unquote a unquote-splicing V kvazikvotovaných výrazech lze použít: (unquote expr ) vyhodnotí expr a vloží hodnotu na dané místo (unquote expr ), expr (unquote-splicing expr ) vyhodnotí expr a vloží prvky výsledného seznamu na dané místo, jeden po druhém ( expr se musí vyhodnotit na seznam) (unquote-splicing expr ),@ expr Příklad (rozdíl mezi unquote a unquote-splicing) `(1 2,(build-list 3 +) #f) = (1 2 (0 1 2) #f) `(1 2,@(build-list 3 +) #f) = (1 2 0 1 2 #f) `(1 2,(+ 2 3) #f) = (1 2 5 #f) `(1 2,@(+ 2 3) #f) = chyba V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 4 / 38

Příklad (kvazikvotované seznamy a jejich vyhodnocení) `(1 2 3 4) = (1 2 3 4) `(1 (+ 10 20) 3 4) = (1 (+ 10 20) 3 4) `(1,(+ 10 20) 3 4) = (1 30 3 4) `'(1,(+ 10 20) 3 4) = (quote (1 30 3 4)) `(1,(append '(a b) '(c d) '(10 20)) 3 4) = (1 (a b c d 10 20) 3 4) `(1,@(append '(a b) '(c d) '(10 20)) 3 4) = (1 a b c d 10 20 3 4) `(1 2 3 4 5) = (1 2 3 4 5) `(1 (+ 2 3) 4 5) = (1 (+ 2 3) 4 5) `(1,(+ 2 3) 4 5) = (1 5 4 5) `(1 ((,(+ 2 3))) 4 5) = (1 ((5)) 4 5) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 5 / 38

Příklad (kvazikvotování na co dát pozor) (define s '(a b c)) `(1,s 2) = (1 (a b c) 2) `(1,@s 2) = (1 a b c 2) `(1 '2 3) = (1 (quote 2) 3) `'(1 2 3) = (quote (1 2 3)) '`(1 2 3) = (quasiquote (1 2 3)) `(1 `(2 3)) = (1 (quasiquote (2 3))) `(1 `(,(+ 1 2) 3)) = (1 (quasiquote ((unquote (+ 1 2)) 3))) `(1,`(,(+ 1 2) 3)) = (1 (3 3)) kvazikvotování lze vnořovat unquote a unquote-splicing má význam pouze na stejné úrovni vnoření V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 6 / 38

Intermezzo: Asociační seznamy Seznam je asociační seznam pokud je ve tvaru: (( klíč 1. hodnota 1 ) ( klíč 2. hodnota 2 ) ( klíč n. hodnota n )) Základní selektor assoc pro práci s asociačním seznamem: (define s (list (cons 'a 10) (cons 'b 20) (cons 'c 30))) (assoc 'b s) = (b. 20) (assoc 'a s) = (a. 10) (assoc 'c s) = (c. 30) (assoc 'd s) = #f (define assoc (lambda (elem l) (cond ((null? l) #f) ((equal? (caar l) elem) (car l)) (else (assoc elem (cdr l)))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 7 / 38

Práce se symbolickými výrazy Motivační příklad co dělá každý pořádný překladač Uvažujeme symbolické výrazy kódující aritmetické výrazy s proměnnými. Úkolem je napsat proceduru na zjednodušování výrazů, např.: (+ y (/ (+ 2 x) (+ 1 x (* 2 0.5)))) se zjednoduší na (+ 1 y) Jak naučit počítač symbolicky upravovat výraz? procedura simplify použitelná ve tvaru (simplify výraz ) rekurzivní charakter problému: pokud je výraz atom, nezjednodušujeme pokud je výraz seznam (op a b c x), pak: pak nejprve zjednodušíme argumenty (vede na rekurzivní aplikaci simplify) potom využijeme známé zákony a pokusíme se zkrátit výsledek (x 0 = 0, x 1 = x, x + x = 2x,... ) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 8 / 38

Jednoduchá verze simplify Zjednodušuje výrazy s omezením: aritmetické výrazy mohou mít nejvýš dva argumenty zjednodušuje pevně zabudovanou množinu operací: +,,, (define simplify (lambda (expr) ;; zjisti, jestli jsou oba argumenty stejná čísla (define == (lambda (x y) (and (number? x) (number? y) (= x y)))) ;; ošetření dělení nulou (define div-by-zero (lambda () 'division-by-zero)). V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 9 / 38

;; zjednodušení pro sčítání (define simplify-add (lambda (op x y) (cond ((== x 0) y) ; 0 + y = y ((== y 0) x) ; x + 0 = x ((equal? x y) `(* 2,x)) ; x + x = 2 x (else (list op x y))))) ;; zjednodušení pro násobení (define simplify-mul (lambda (op x y) (cond ((== x 0) 0) ; 0 y = 0 ((== y 0) 0) ; x 0 = 0 ((== x 1) y) ; 1 y = y ((== y 1) x) ; x 1 = x (else (list op x y))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 10 / 38

;; zjednodušení pro odčítání (define simplify-min (lambda (op x y) (cond ((== x 0) (list op y)) ; 0 x = x ((== y 0) x) ; x 0 = x ((equal? x y) 0) ; x x = 0 (else (list op x y))))) ;; zjednodušení pro dělení (define simplify-div (lambda (op x y) (cond ((== x 0) 0) ; 0 x = 0 ((== y 0) (div-by-zero)) ; x 0 nelze ((== x 1) (list op y)) ; 1 x = 1 x ((== y 1) x) ; x 1 = x ((equal? x y) 1) ; x x = 1 (else (list op x y))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 11 / 38

. (cond ((number? expr) expr) ((symbol? expr) expr) ((and (list? expr) (member (car expr) '(+ * - /))) (let ((op (car expr)) (expr (map simplify expr))) (if (null? (cddr expr)) případ jednoho argumentu (if (number? (cadr expr)) (eval expr) expr) (let ((x (cadr expr)) (y (caddr expr))) (cond ((and (number? x) (number? y)) (eval expr)) ((equal? op '+) (simplify-add op x y)) ((equal? op '*) (simplify-mul op x y)) ((equal? op '-) (simplify-min op x y)) (else (simplify-div op x y)))))))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 12 / 38

Příklad (použití jednoduché verze simplify) Kde funguje uspokojivě: (simplify '(+ 10)) = 10 (simplify '(+ 1 2)) = 3 (simplify '(- x 0)) = x (simplify '(- 0 x)) = (- x) (simplify '(/ 0 x)) = 0 (simplify '(/ x 0)) = division-by-zero (simplify '(/ x 1)) = x (simplify '(/ 1 x)) = (/ x) (simplify '(/ (+ 2 x) (* 2 0.5))) = (+ 2 x) Kde lze ještě vylepšit: (simplify '(+ (* 2 3) (+ y (+ 2 x)))) = (+ 6 (+ y (+ 2 x))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 13 / 38

Tabulka zjednodušování elegantní řešení (define simplification-tbl ;; pomocné procedury == a div-by-zero (let ((== (lambda (x y) (and (number? x) (number? y) (= x y)))) (div-by-zero (lambda () 'division-by-zero))) ;; asociační tabulka symbol zjednodušovací procedura `((+.,(lambda (op x y) (cond ((== x 0) y) ((== y 0) x) ((equal? x y) `(* 2,x)) (else (list op x y))))) (*.,(lambda (op x y) (cond ((== x 0) 0). V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 14 / 38

Zjednodušovací procedura s tabulkou jako parametrem (define simplify (lambda (expr table) (let simplify ((expr expr)) (cond ((number? expr) expr) ((symbol? expr) expr) ((and (list? expr) (assoc (car expr) table)) (let ((expr (map simplify expr))) (if (null? (cddr expr)) (if (number? (cadr expr)) (eval expr) expr) (if (forall number? (cdr expr)) (eval expr) (apply (cdr (assoc (car expr) table)) expr))))))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 15 / 38

Verze pro + a s libovolně mnoha argumenty Myšlenka dalšího zjednodušování: všechna čísla ze seznamu posčítáme/vynásobíme (argument value) ostatní (složené) hodnoty ze seznamu dáme do seznamu (argument compound) (define simplify-addmul (lambda (op compound value) (cond ((and (equal? op '*) (= value 0)) 0) ((null? compound) value) ((= value (eval `(,op))) případ neutrálního prvku (if (null? (cdr compound)) (car compound) (cons op compound))) (else `(,op,value,@compound))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 16 / 38

(define simplification-tbl (let ((== (lambda (x y) (and (number? x) (number? y) (= x y)))) (div-by-zero (lambda () 'division-by-zero)) (simplify+* (lambda (op. rest) (let ((value (apply (eval op) (filter number? rest))) (compound (remove number? rest))) (simplify-addmul op compound value))))) `((+.,simplify+*) (*.,simplify+*) (-.,(lambda (op x y) (cond ((== x 0) (list op y)) ((== y 0) x). V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 17 / 38

Příklad (použití rozšířené verze simplify) Nové možnosti zjednodušování: (simplify '(+ 1 2 x 3 y 5 6)) = (+ 17 x y) (simplify '(+ (* 2 3) y (+ 2 x))) = (+ 6 y (+ 2 x)) (simplify '(- (* 1 x) (+ 2-3 x 1))) = 0 (simplify '(/ (+ 2 x) (+ 1 x (* 2 1/2)))) = 1. Pořád není ideální: (simplify '(+ x (- x))) = (+ x (- x)) (simplify '(* x (/ 1 x))) = (* x (/ x)) (simplify '(+ 1 (+ 1 (+ 1 x)))) = (+ 1 (+ 1 (+ 1 x) (simplify '(+ x x x x)) = (+ x x x x). V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 18 / 38

Práce se symbolickými výrazy Motivační příklad symbolické derivace Uvažujeme symbolické výrazy kódující aritmetické výrazy s proměnnými. Úkolem je napsat proceduru, která pro daný výraz vrací jeho derivaci, např.: na základě výrazu (* x x) a proměnné x vracíme (* 2 x) Jak naučit počítač symbolicky derivovat? naimplementujeme tabulku pravidel pro derivování c = 0, rekurzivně aplikujeme pravidla x = 1, (f ± g) = f ± g, (f g) = f g + g f,... na výsledek použijeme zjednodušování čitelnější výstup V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 19 / 38

Implementace symbolické derivace Vytvoříme proceduru diff: dva formální argumenty: expr (vstupní výraz), var (proměnná) procedura diff používá lokálně definované vazby: variable? predikát (je daný výraz proměnná?) constant? predikát (je daný výraz konstanta?) table tabulka pravidel pro derivování derive rekurzivní procedura pro vlastní výpočet Schématicky: (define diff (lambda (expr var). (derive expr)) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 20 / 38

Interní predikáty variable? a constant? ;; testuj, jestli je daný výraz proměnná (define variable? (lambda (expr) (equal? expr var))) ;; testuj, jestli je daný výraz konstanta (define constant? (lambda (expr) (or (number? expr) (and (symbol? expr) (not (variable? expr)))))) Poznámka: vazba symbolu var se bere z prostředí vzniku procedur (argument diff) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 21 / 38

Interní tabulka pravidel pro derivování ;; asociační seznam symbol pravidlo (define table `((+.,(lambda (x y) `(+,(derive x),(derive y)))) (-.,(lambda (x y) `(-,(derive x),(derive y)))) (*.,(lambda (x y) `(+ (*,x,(derive y)) (*,(derive x),y)))) (/.,(lambda (x y) `(/ (- (*,(derive x),y) (*,x,(derive y))) (*,y,y)))))) Poznámka: procedura navázaná na derive zatím není definována (!!) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 22 / 38

Interní tabulka pravidel pro derivování ;; derivuj vstupní výraz (define derive (lambda (expr) (cond ((variable? expr) 1) ((constant? expr) 0) (else (apply (cdr (assoc (car expr) table)) (cdr expr)))))) Poznámky: vazba symbolu var se bere z prostředí vzniku procedur (argument diff) spuštění (derive expr) s výchozím vstupním výrazem výstup lze zjednodušovat pomocí simplify V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 23 / 38

Příklad (použití diff a simplify) (diff '(+ x x) 'x) = (+ 1 1) (diff '(* x y) 'x) = (+ (* x 0) (* 1 y)) (diff '(+ (* x 2) (* x x)) 'x) = (+ (+ (* x 0) (* 1 2)) (+ (* x 1) (* 1 x))) (diff '(* x (* x x)) 'x) = (+ (* x (+ (* x 1) (* 1 x))) (* 1 (* x x))) (simplify (diff '(+ x x) 'x)) = 2 (simplify (diff '(* x y) 'x)) = y (simplify (diff '(+ (* x 2) (* x x)) 'x)) = (+ (+ x x) 2) (simplify (diff '(* x (* x x)) 'x)) = (+ (* x (+ x x)) (* x x)) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 24 / 38

Příklad (vytvoření funkce derivace pomocí symbolického předpisu) (define diff-proc (lambda (expr var) (eval `(lambda (,var),(simplify (diff expr var)))))) (define diff-proc (lambda (expr var) (eval `(lambda (,var),(simplify (diff expr var))) (environment-parent (the-environment))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 25 / 38

Příklad (Notace zápisu aritmetických výrazů) infixová symbol pro operace je mezi operandy ( běžná notace ) plusy: snadno se čte minusy: asociativita, priorita, operace pouze dva argumenty Příklad: 2 * (3 + 5) prefixová symbol pro operace před operandy plusy: libovolný počet operandů, odpadají problémy s asociativitou / prioritou minusy: nezvyk, velké množství závorek Příklad: (* 2 (+ 3 5)) (vynásob dvojku se součtem trojky a pětky) postfixová symbol pro operace za operandy Příklad: (2 (3 5 +) *) postfixová bezzávorková (polská) plusy: strojově snadno analyzovatelná minusy: nejméně čitelná, operace mají fixní počet operandů Příklad: 2 3 5 + * V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 26 / 38

Příklad (struktura výrazu (+ (* 2 x) (- (/ (+ x 2) z)) 5)) *. 2. x (). +..... 5 () -.. () /... +. x. 2 () z () V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 27 / 38

Příklad (struktura výrazu (+ (* 2 x) (- (/ (+ x 2) z)) 5)) + * - 5 2 x / + z x 2 V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 27 / 38

Příklad (prefixová notace převedená na postfixovou) (define prefix->postfix (lambda (S-expr) (cond ((number? S-expr) S-expr) ((symbol? S-expr) S-expr) ((null? S-expr) S-expr) ((list? S-expr) `(,@(map prefix->postfix (cdr S-expr)),(car S-expr))) (else "Incorrect expression.")))) (prefix->postfix '(* 2 3)) = (2 3 *) (prefix->postfix '(* (+ 2 3) 4)) = ((2 3 +) 4 *) (prefix->postfix '(cons (+ 2 3) 4)) = ((2 3 +) 4 cons) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 28 / 38

Příklad (prefixová notace převedená na bezzávorkovou) (define prefix->polish (lambda (S-expr) (cond ((number? S-expr) (list S-expr)) ((symbol? S-expr) (list S-expr)) ((null? S-expr) (list S-expr)) ((list? S-expr) `(,@(apply append (map prefix->polish (cdr S-expr))),(car S-expr))) (else "Incorrect expression.")))) (prefix->polish '(* 3 5)) = (3 5 *) (prefix->polish '(+ 2 (* 3 5))) = (2 3 5 * +) (prefix->polish '(+ (* 2 3) 5)) = (2 3 * 5 +) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 29 / 38

Příklad (prefixová notace převedená na infixovou) (define prefix->infix (lambda (S-expr) (if (pair? S-expr) (let ((op (car S-expr)) (tail (cdr S-expr))) (cond ((null? tail) (eval S-expr)) ((null? (cdr tail)) `(,op,(prefix->infix (car tail)))) (else (foldl (lambda (expr collected) (list collected op expr)) (prefix->infix (car tail)) (map prefix->infix (cdr tail)))))) S-expr))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 30 / 38

Příklad (příklady převodu do infixové notace) (prefix->infix '(*)) = 1 (prefix->infix '(- 2)) = (- 2) (prefix->infix '(- 2 3)) = (2-3) (prefix->infix '(- 2 3 4)) = ((2-3) - 4) (prefix->infix '(- (/ (+ x 2) z))) = (- ((x + 2) / z)) Poznámky: převod infix->prefix je komplikovanější, musíme řešit: priority operací: 2 3 + 4 = (2 3) + 4 a nikoliv 2 (3 + 4), asociativitu operací: 2 3 4 = (2 3) 4 a nikoliv 2 (3 4). více: kursy Formální jazyky a automaty, Překladače I, II V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 31 / 38

Vyhodnocování postfixových výrazů Princip jako u vyhodnocování ve Scheme operace je na konci seznamu nelze (bez dalších koncepčních úprav) zavést speciální formy Algoritmus vyhodnocení: číslo se vyhodnotí na číslo symbol se vyhodnotí na svou vazbu je-li výraz seznam, potom: 1 vyhodnotí se jeho prvky jeden po druhém, 2 až se vyhodnotí poslední z nich, pak se ověří, jestli se vyhodnotil na proceduru, 3 pokud ano, dojde k aplikaci procedury,... V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 32 / 38

Příklad (průběh vyhodnocení výrazu v postfixové notaci) (postfix-eval '((10 20 cons) (30 40 cons) list)) aktuální výraz ((10 20 cons) (30 40 cons) list) () seznam argumentů (10 20 cons) () (20 cons) (10) (cons) (10 20) ((30 40 cons) list) ((10. 20)) (30 40 cons) () (40 cons) (30) (cons) (30 40) (list) ((10. 20) (30. 40)) = ((10. 20) (30. 40)) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 33 / 38

Příklad (evaluátor postfixových výrazů) (define postfix-eval (lambda (expr) (cond ((number? expr) expr) ((symbol? expr) (eval expr)) (else (let proc ((expr expr) (args '())) (cond ((null? expr) '()) ((null? (cdr expr)) (apply (postfix-eval (car expr)) (reverse args))) (else (proc (cdr expr) (cons (postfix-eval (car expr)) args))))))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 34 / 38

Vyhodnocování výrazů v bezzávorkové notaci Princip vyhodnocování: vyhodnocuje se pomocí dodatečného zásobníku (odložiště výsledků operací) nutná podmínka: operace mají pevně danou aritu (počet operandů) Prostředí (vazby symbolů a arita procedur): (define environment `((+ 2,+) (- 2,-) (/ 2,/) (* 2,*) (n 1,-) (^ 2,expt))) Kde má uplatnění: embedded zařízení, malé systémy, tiskárny (PostScript), FORTH,... V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 35 / 38

Algoritmus vyhodnocování pomocí zásobníku Tři základní pravidla: 1 atom na začátku (dosud nezpracovaná část výrazu) přesuň na zásobník 2 je-li na začátku (jméno) operace s aritou n, pak: vyzvedni n argumentů ze zásobníku, proveď operaci s vyzvednutými argumenty, ulož výsledek operace na vrchol zásobníku. 3 pokud je vstup prázdný, stav zásobníku je výsledek výpočtu (polish-eval '(10 20 +) environment) vstup zásobník (10 20 +) () (20 +) (10) (+) (20 10) () (30) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 36 / 38

Příklad (rozdíly ve vyhodnocování) vstup zásobník (10 20 30 + *) () (20 30 + *) (10) (30 + *) (20 10) (+ *) (30 20 10) (*) (50 10) () (500) vstup zásobník (10 20 + 30 *) () (20 + 30 *) (10) (+ 30 *) (20 10) (30 *) (30) (*) (30 30) () (900) (10 20 30 + *) (20 + 30) 10 (10 20 + 30 *) (10 + 20) 30 V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 37 / 38

(define polish-eval (lambda (expr env) (let iter ((input expr) (stack '())) (if (null? input) stack (let ((word (car input)) (tail (cdr input))) (if (not (symbol? word)) (iter tail (cons word stack)) (let ((func (assoc word env))) (if (not func) (error "Symbol not bound") (let ((arity (cadr func)) (proc (caddr func))) (iter tail (cons (apply proc (reverse (list-pref arity stack))) (list-tail stack arity)))))))))))) V. Vychodil (KI, UP Olomouc) Kvazikvotování, manipulace se symbolickými výrazy Přednáška 11 38 / 38