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

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

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

1. Od Scheme k Lispu

Funkcionální programování úvod

Paradigmata programování 1

LISP Definice funkcí

Paradigmata programování 2

Paradigmata programování 1

Paradigmata programování 1

Jazyky pro umělou inteligenci

Paradigmata programování II Přednáška 2: 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

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

Algoritmizace a programování

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

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]

Pointery II. Jan Hnilica Počítačové modelování 17

KAPITOLA 9 - POKROČILÁ PRÁCE S TABULKOVÝM PROCESOREM

Programování v jazyce JavaScript

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

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

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

DUM 06 téma: Tvorba makra pomocí VBA

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

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

PARADIGMATA PROGRAMOVÁNÍ 2A MUTACE

2 Datové typy v jazyce C

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

Paměť počítače. alg2 1

Programování v C++, 2. cvičení

Logické programování I

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

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

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Programovací jazyk Pascal

6. blok část C Množinové operátory

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Algoritmizace a programování

Úvod do programovacích jazyků (Java)

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Sada 1 - Základy programování

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

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

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

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

PARADIGMATA PROGRAMOVÁNÍ 2A VEDLEJŠÍ EFEKT

ALGORITMIZACE PRAKTICKÉ

Lokální definice (1) plocha-kruhu

KIV/ZIS cvičení 5. Tomáš Potužák

Základy programování (IZP)

Algoritmy I. Číselné soustavy přečíst!!! ALGI 2018/19

přetížení operátorů (o)

Tabulkový procesor. Základní rysy

Algoritmizace prostorových úloh

Algoritmizace prostorových úloh

Hlavní užitečné funkce Visual LISPu jsou:

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

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

PARADIGMATA OBJEKTOVÉHO PROGRAMOVÁNÍ I

Skripta ke školení. Základy VBA. vypracoval: Tomáš Herout. tel:

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_25 09

Negativní informace. Petr Štěpánek. S použitím materiálu M.Gelfonda a V. Lifschitze. Logické programování 15 1

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

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

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

Programování v Pythonu

Reprezentace dat v informačních systémech. Jaroslav Šmarda

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Datové struktury 2: Rozptylovací tabulky

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

Tematický celek Proměnné. Proměnné slouží k dočasnému uchovávání hodnot během provádění aplikace Deklarace proměnných

Databázové systémy Cvičení 5.2

Grafy. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 13.

Datové typy v Javě. Tomáš Pitner, upravil Marek Šabo

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

8 Třídy, objekty, metody, předávání argumentů metod

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Logika a logické programování

Paradigmata programování 1

DUM 01 téma: Obecné vlastnosti tabulkového editoru, rozsah, zápis do buňky, klávesové zkratky

Dotazy tvorba nových polí (vypočítané pole)

Úvod do Matlabu. Praha & EU: Investujeme do vaší budoucnosti. 1 / 24 Úvod do Matlabu

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

VY_32_INOVACE_In 6.,7.13 Vzorce vložení funkce

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

Systém je citlivý na velikost písmen CASE SENSITIVE rozeznává malá velká písmena, např. PROM=1; PROm=1; PRom=1; Prom=1; prom=1; - 5 různých proměnných

Příklad : String txt1 = new String( Ahoj vsichni! ); //vytvoří instanci třídy String a přiřadí ji vnitřní hodnotu Ahoj vsichni!

Př. další použití pointerů

Čtvrtek 3. listopadu. Makra v Excelu. Obecná definice makra: Spouštění makra: Druhy maker, způsoby tvorby a jejich ukládání

Odvozené a strukturované typy dat

Datové typy strana 29

Textové popisky. Typ dat

Konstruktory a destruktory

Algoritmizace a programování

2. cvičení z ZI1 - Excel

typová konverze typová inference

MQL4 COURSE. By Coders guru -8- Proměnné

ALGORITMIZACE A PROGRAMOVÁNÍ

Transkript:

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 3. CVIČENÍ 2011 Jan Janoušek MI-FLP Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti

Page 1 of 6 Cviceni 3 Obsah seznamy, cons-buňka, car, cdr, first, rest, caar,..., cddddr, nth, nthcdr, list, last, append, length, butlast, copy-list, copy-tree, listp, consp, atom, symbolp, numberp, ukazatele, porovnávání (eql, eq, =, equal), function, #', apply, funcall, lambda-výraz, mapovací funkcionály (mapcar, mapcan, mapc, maplist, mapcon, map) Seznamy Seznamy jsou jednou ze základních datových struktur v Lispu. V Common Lispu (CL) je možné použít i specializované datové struktury (hash-tabulky, vektory a vícerozměrná pole, streamy,...). Při psaní programu však většinou v první fázi použijeme seznamy a až později můžeme zvážit, zda je účelné přejít ke specializovaným (efektivnějším) datovým strukturám. Seznam můžeme definovat takto: 1) Seznamem je prázdný seznam ( v Lispu zapsán jako nil nebo () ) 2) Seznam vznikne přidáním libovolného prvku k seznamu (zleva), přitom prvkem může být libovolný atom nebo opět seznam. V Lispu se pro vytváření seznamů pomocí přidávání prvků používá funkce cons. Tato funkce očekává dva parametry. Výsledkem volání je vytvoření dvousložkového objektu nazývaného consbuňka (angl. cons-cell), první složka tohoto objektu je ukazatel na objekt zadaný funkci cons jako první argument, druhá složka je ukazatel předaný funkci cons jako druhý argument. Pro přístup k těmto prvkům se používají funkce car (první složka) cons-buňky a cdr (druhá složka). CL-USER 13 > (setf x (cons 'b nil)) (B) CL-USER 14 > (setf y (cons 'a (cons 'b (cons 'c nil)))) (A B C) (Obrázky reprezentace). Se symbolem X je nyní asociován jednoprvkový seznam (B), se symbolem Y tříprvkový seznam (A B C). Jak je vidět z předchozích příkladů, seznam se v Lispu zapisuje jako skupina prvků oddělených mezerami, která ohraničena kulatými závorkami. CL-USER 16 > (car y) A CL-USER 17 > (cdr y) (B C) První složka prvního cons objektu je ukazatel na A druhý prvek je ukazatel na zbytek seznamu. Mimo funkce car a cdr (pojmenování vzniklo podle registru počítače na kterém běžel jeden z prvních dialektů Lispu - ekvivalentně můžeme použít first a rest) existují jejich různé variace. Např. CL-USER 18 > (cddr y) (C) je ekvivalentní zápisu (cdr (cdr y)). Podobně pracují funkce caar, caaar, cdddr,... CL-USER 19 > (cadr y) B

Page 2 of 6 Funkce cadr vrátí (car (cdr...)) Pro přístup na prvek seznamu, jehož pořadí je zadáno indexem, můžeme použít funkce: CL-USER 28 > (nth '1 y) B CL-USER 29 > (nthcdr '1 y) (B C) Indexování začíná v Lispu vždy od nuly. Pro vytvoření seznamu z více prvků v jednom kroku slouží funkce list, funkce last vrátí poslední cons objekt seznamu: CL-USER 31 > (list 'a 'b 'c 1 2 '(2 3) t) (A B C 1 2 (2 3) T) CL-USER 34 > (last (list 'a 'b 'c 1 2 '(2 3) t)) (T) Funkce append spojí více seznamů do jednoho: CL-USER 35 > (append '(1 2) '(a (b c))) (1 2 A (B C)) Další užitečné funkce: length - vrátí délku seznamu butlast - seznam bez posledního prvku Jestliže potřebujeme vytvořit kopii seznamu, použijeme funkci copy-list. Výsledkem je tzv. mělká kopie seznamu, tedy kopírují se pouze cons-buňky z nejvyšší úrovně zadaného seznamu. Nový seznam má tedy tytéž prvky - ukazatele na ně jsou ale umístěny v nových cons buňkách. Pro vytvoření hluboké kopie (včetně vnořených seznamů), slouží funkce copy-tree. Některé predikáty (listp x) - testuje, zda x je seznam (nil nebo cons buňka - vrací tedy t i pro seznam, který není řádně ukončen) (consp x) - testuje, zda x je cons buňka (atom x) - testuje, zda x je atom (symbolp x) - vrací t, jestliže x je symbolický atom (numberp x) - vrací t, jestliže x je číslo Tečková notace Seznamy popsané v předchozí části se někdy označují jako tzv. řádné (proper) seznamy. Takový seznam je buď prázdný seznam (nil nebo ()), nebo cons buňka, jejíž cdr je opět řádný seznam. Funkce testující, zda je seznam řádný, by mohla vypadat třeba takto:

Page 3 of 6 (defun prop-sez (lst) (or (null lst) (and (consp lst) (prop-sez (cdr lst))))) Standardní Lispovský predikát na testování seznamů listp, vrací T i pro seznamy, které nejsou řádné. Přepis této funkce v Lisp kódu by mohl vypadat takto: (defun my-listp (lst) (or (null lst) (consp lst))) Všechno co není cons buňka, se v Lispu považuje za atom. Predikát atom můžeme tedy přepsat jako: (defun my-atom (a) (not (consp a))) Funkcí cons se však v Lispu nevytváří pouze seznamy. Je ji možno použít, kdykoliv je potřeba vytvořit dvouprvkovou strukturu. Ta je pak zobrazena v tečkové notaci. CL-USER 20 > (cons 'a 'b) (A. B) Tečkovou notaci lze použít i při zápisu seznamů, ale zpravidla to neděláme. Jestliže však pomocí tečkové notace vytvoříme řádný seznam, je zobrazen obvyklým způsobem. CL-USER 21 > '(1. (2. (3. nil))) (1 2 3) Následující struktury nejsou řádným seznamem (poslední cons buňka neobsahuje v cdr složce nil). Zobrazeny jsou v tzv. smíšené notaci. CL-USER 22 > '(1. (2. (3. 4))) (1 2 3. 4) CL-USER 23 > (cons 1 (cons 2 (cons 3 4))) (1 2 3. 4) Ukazatele Lisp nepracuje explicitně s ukazateli. Je to zbytečné. Jestliže navážeme na symbol nějaký objekt (číslo, strukturu, seznam,...), obsahuje symbol pouze ukazatel na tento objekt a ne objekt samotný. Jestliže například zadáme: CL-USER 54 > (setf A '(1 2)) (1 2) CL-USER 55 > (setf B A) (1 2) nekopíroval se do B celý seznam z A, pouze se do B přiřadil ukazatel na stejný seznam, na jaký ukazuje proměnná A. Kvůli efektivnosti občas Lisp nevytváří ukazatele - například malé číslo (integer) zabere stejnou paměť jako pointer, a tak se může uložit (včetně příslušné typové informace!) přímo do dané proměnné nebo do složky v cons-buňce, ale to už jsou implementační detaily. Jednoduše si můžeme představit, že proměnná vždy obsahuje ukazatel na objekt, který je do ní přiřazen. Mimo jiné to znamená, že je možno přiřadit objekt jakéhokoliv typu kamkoliv (jestliže

Page 4 of 6 toto implicitní chování nezměníme explicitní deklarací). Porovnávání K porovnávání dvou objektů můžeme v Lispu použít několik funkcí. Funkce eql porovnává, jestli jsou dva objekty identické. Čísla jsou identická, jestliže mají stejnou hodnotu (a typ), ostatní objekty jsou identické, jestliže jsou na stejném místě v paměti (ukazatele se rovnají). CL-USER 78 > (eql 1 1) T CL-USER 79 > (eql 121212121212121212121212121212 121212121212121212121212121212) T CL-USER 80 > (eql (cons 1 nil) (cons 1 nil)) NIL CL-USER 81 > (eql 0 0.0) NIL Funkce eq je přísnější obdoba eql. Vrací T pouze v případě, že oba argumenty jsou na stejném místě v paměti. CL-USER 82 > (eq 121212121212121212121212121212 121212121212121212121212121212) NIL Pro porovnávání čísel můžeme použít funkci =. Dvě čísla jsou stejná, jestliže mají stejnou hodnotu (mohou se lišit typem). CL-USER 89 > (= 0 0.0) T Jestliže chceme otestovat, jestli složitější datové struktury obsahují stejné elementy (např. jestli dva seznamy obsahují stejné prvky), můžeme použít funkci equal. CL-USER 90 > (equal (list 1 (list 2 3)) (list 1 (list 2 3))) T Funkce V Lispu jsou funkce objekty - podobně jako symboly, seznamy nebo řetězce. Speciální operátor function vrací zobrazitelnou reprezentaci funkce. Podobně jako můžeme použít ' (apostrof) místo quote, můžeme operátor function nahradit pomocí zkratky #'. CL-USER 4 > (function +) #<function + 20113F9A> CL-USER 6 > #'+ #<function + 20113F9A> Porovnat rozdíly při vyhodnocování symbolů můžeme následovně:

Page 5 of 6 CL-USER > (setf list ) CL-USER 11 > list Symbol list se vyhodnotil na hodnotu, která je na něj navázaná. CL-USER 12 > 'list LIST Speciální operátor quote vrátil textovou reprezentaci zadaného symbolu. CL-USER 13 > #'list #<function LIST 200DCA7A> Výsledkem dotazu po funkční hodnotě je objekt reprezentující funkci navázanou na symbol list. Jako ostatní objekty v Lispu, můžeme i funkci předat jako parametr. Jednou z mnoha funkcí očekávajících jako parametr jinou funkci, je funkce apply. Jako první argument očekává funkci, zbytek pak tvoří argumenty, na které se má tato funkce aplikovat. Posledním argumentem musí být seznam. CL-USER 16 > (apply #'+ '(1 2 3 4)) CL-USER 17 > (apply #'+ 1 2 '(3 4)) Funkce funcall pracuje stejně jako apply, nepotřebuje však argumenty zabalené do seznamu. CL-USER 18 > (funcall #'+ 1 2 3 4) K vytvoření nepojmenované (anonymní) funkce můžeme v Lispu použít tzv. lambda-výraz. CL-USER 21 > (lambda (x y) (+ x y)) #'(LAMBDA (X Y) (+ X Y)) Nepojmenovaná funkce je výhodná při jednorázovém použití jako parametr jiné funkce. CL-USER 22 > (funcall #'(lambda (x y) (- x y)) 2) 8 Mapovací funkcionály Velmi často se v Lispu vyskytuje požadavek na postupné zpracování seznamu pomocí nějaké funkce. Pro tyto případy poskytuje Common Lisp tzv. mapovací funkcionály (někdy označované jako funkce vyšších řádů). Jako první argument očekávají funkci a zbylé argumenty představují seznam nebo několik seznamů. Počet těchto seznamů musí odpovídat počtu parametrů funkce, zadané jako první parametr. Tato funkce je pak postupně aplikována na určitou podmnožinu prvků vybraných ze seznamu: Funkcionál mapcar pracuje na jednotlivých prvcích. Napřed se použije car z každého seznamu, potom cadr a tak dále. Počet opakování je dán počtem prvků nejkratšího seznamu. Výsledkem je seznam vytvořený z výsledných hodnot aplikované funkce.

Page 6 of 6 CL-USER 1 > (mapcar #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) ((1 4 9) (2 5 8) (3 6 1)) Funkcionál mapcan pracuje podobně jako mapcar, výsledky (předpokládá se, že to jsou seznamy) jsou však do seznamu přidávány pomocí (destruktivního) postupného propojení za sebou. CL-USER 2 > (mapcan #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) (1 4 9 2 5 8 3 6 1) Funkcionál mapc je opět obdoba mapcar, jako výsledek se vrací druhý argument. Používá se kvůli vedlejším efektům, kdy nás nezajímá návratová hodnota. CL-USER 3 > (mapc #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) (1 2 3) Funkcionál maplist - zadaná funkce je postupně aplikována na celý seznam, cdr seznamu, cddr seznamu... CL-USER 4 > (maplist #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) (((1 2 3) (4 5 6 7) (9 8 1 2 3 4)) ((2 3) (5 6 7) (8 1 2 3 4)) ((3) (6 7) (1 2 3 4))) Funkcionál mapcon funguje jako maplist, s tím rozdílem, že výsledek je vytvořen pomocí (destruktivního) postupného propojení dílčích hodnot (předpokládá se, že to jsou seznamy) za sebou. CL-USER 5 > (mapcon #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) ((1 2 3) (4 5 6 7) (9 8 1 2 3 4) (2 3) (5 6 7) (8 1 2 3 4) (3) (6 7) (1 2 3 4)) Funkcionál mapl je obdobou mapc pro maplist. CL-USER 6 > (mapl #'list '(1 2 3) '(4 5 6 7) '(9 8 1 2 3 4)) (1 2 3) Funkcionál map funguje jako mapcar, jako první parametr je však možno zadat typ výsledku. CL-USER 12 > (map 'cons #'list '(1 2 3) '(4 5 6 7)) ((1 4) (2 5) (3 6)) CL-USER 14 > (map 'vector #'list '(1 2 3) '(4 5 6 7)) #((1 4) (2 5) (3 6))

Cvičení 2 - priklady file:///c:/pracovni/vyuka/jui/web/w03test.html Page 1 of 1 Cvičení 3 1) Pomocí car a cdr definujte funkci my-fourth, která vrátí čtvrtý prvek seznamu. 2) Zapište tři různé cons výrazy, které vrátí (a b c). 3) Ukažte, jak jsou následující symbolické výrazy reprezentovány v paměti a kolik cons-buněk je k jejich reprezentaci zapotřebí: a) (A B (C D) E) b) (A (B (C (D. E)))) c) (A (B. C) (D. E)) d) (A B (C. (D E))) 4) Definujte funkci my-length, která spočítá délku seznamu (bez podseznamů). (my-length '(1 2 (3 4))) --> 3 5) Definujte funkci at-cnt, která určí počet atomů ve výrazu. (at-cnt '(1 2 (3 4))) --> 4 (at-cnt 1) --> 1 (at-cnt '(1 2 (3 4. 5) 6. 7)) --> 7 6) Definujte rekurzivně funkci revall, která otočí pořadí prvků v seznamu včetně podseznamů. (revall '(1 2 3 (4 5))) --> ((5 4) 3 2 1) 7) Definujte funkci, která dostane zadanou počáteční celočíselnou hodnotu X a počet opakování N. Výsledkem bude seznam obsahující N čísel, od X do X+N-1. (counter 12 5) --> (12 13 14 15 16) 8) Pomocí mapovacích funkcionálů definujte funkci, která vypočte ze seznamu čísel seznam jejich druhých odmocnin. Záporná čísla bude vynechávat (pomocí mapcan). (odm '(11-5 4 8-7)) --> (3.3166247903554 2.0 2.8284271247461903) 9) Pomocí mapovacích funkcionálů definujte funkci, která obdrží dva seznamy. Výsledkem je seznam aritmetických průměrů odpovídajících si prvků. (prum '(1 2 3 4) '(7 8 9 )) --> (4 5 6 7)