ϵ">]>
5. CVIČENIE Z PREDMETU ÚVOD DO DEKLARATÍVNEHO PROGRAMOVANIA LS 2013/2014
ČASŤ A
http://dai.fmph.uniba.sk/courses/udp/ex/ex05.zip
Dátum: 18. a 19. 3. 2014
Odporúčaná verzia CL: 5.81.20
WWW stránka predmetu: http://dai.fmph.uniba.sk/courses/udp/
Kontakt: udp(zavináč)lists.dai.fmph.uniba.sk
Úvodná poznámka. Toto cvičenie je venované funkciám operujúcim na zoznamoch (ex05a), chvostovej rekurzii na zoznamoch (ex05b) a tuplingu zoznamových operácií (ex05c).
Literatúra.
[1] J. Kľuka. Prednášky z Úvodu do deklaratívneho programovania LS 2013/2014.
http://dai.fmph.uniba.sk/courses/udp/udp-prednasky-2014.pdf
[2] D. Guller. Poznámky k prednáškam z CL.
[3] J. Komara and P. J. Voda. Metamathematics of Computer Programming. 2001.
Kódovanie konečných postupností párovaním. Pomocou párovacej funkcie môžeme zakódovať konečné postupnosti čísel ľubovoľnej dĺžky nasledovne:
kóduje prázdnu postupnosť,
kóduje postupnosť, ktorej prvým prvkom je číslo a zvyšok postupnosti je zakódovaný číslom .
Inak povedané, postupnosť čísel , , …, zakódujeme ako
Koncová nie je prvkom postupnosti. Jej význam je podobný hodnote None v Pythone.
Kód konečnej postupnosti nazývame zoznam.
Napríklad šesťprvkovú postupnosť 2, 3, 5, 7, 11, 13 zakódujeme zoznamom
Konvencia. Na označenie zoznamov budeme používať premenné s príponou -s (množné číslo v angličtine), napríklad , , .
Úloha. Zadefinujte funkciu , ktorej hodnotou je dĺžka zoznamu :
Napr. .
Testovanie.
L_test = r:Results
Úloha. Zistite, koľko prvkov má zoznam
Čo je piatym prvkom tohto zoznamu (ak poradie počítame od 1)?
Úloha. Zadefinujte funkciu , ktorá zreťazí zoznamy a , teda
Napr. .
Testovanie.
Conc_test = r:Results
[CL] Zabudované zreťazenie. Zreťazenie je zabudované ako binárny infixový operátor. Zapisuje sa ++ a zobrazuje sa .
Zreťazenie je asociatívne, teda
Automaticky sa zátvorkuje vľavo, teda
Zreťazenie má vyššiu prioritu ako párovanie, preto
[CL] Upozornenie. Aby ste spojili zoznam , prvok a zoznam v tomto poradí, musíte napísať
Ak napíšete bez zátvoriek, znamená to !
Úloha. Aj keď sú hodnoty výrazov a rovnaké, výpočty prebiehajú rôzne.
Na ktorý z týchto výpočtov je potrebný menší počet krokov?
Úloha. Zadefinujte funkciu , ktorej hodnotou je práve vtedy, keď sa prvok nachádza v zozname . V opačnom prípade je jej hodnotou .
Napr. , ale .
Špecifikácia:
Testovanie.
Member_test = r:Results
[CL] Zabudovaný predikát príslušnosti do zoznamu. V CL je zabudovaný predikát (vlastnosť prirodzených čísel, „booleovská funkcia“) , ktorý sa zobrazuje ako a platí práve vtedy, keď je prvkom zoznamu . Jeho negácia sa zapisuje a zobrazuje sa ako .
Tento predikát nebudeme používať pri programovaní, slúži iba na špecifikáciu (napríklad nasledujúcej funkcie).
Úloha. Zadefinujte funkciu , ktorá odstráni všetky výskyty prvku zo zoznamu . Presnejšie: Hodnotou je nový zoznam, ktorý obsahuje všetky prvky zoznamu , ktoré sú rôzne od , v pôvodnom vzájomnom poradí.
Napr. .
Uvedomte si, že musíte vytvoriť celý výstupný zoznam. Funkcia nemôže meniť vstupný zoznam.
Testovanie.
Delall_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je posledný prvok zoznamu , ak existuje, alebo , ak je prázdny.
Napr. .
Nájdite verziu bez pomocných funkcií. Ak má zoznam aspoň jeden prvok, ako zistíte, či má práve jeden prvok?
Testovanie.
Last_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je -ý prvok zoznamu :
Napr. .
Špecifikácia
Nepoužite žiadne pomocné funkcie.
Testovanie.
Sub_test = r:Results
Indexovanie v zoznamoch. Všimnite si, že (na rozdiel od polí) na zoznamoch je indexovanie pomerne výpočtovo náročné: Na prístup k prvku na -tom mieste zoznamu potrebujeme krokov.
Indexovaniu sa preto budeme pri programovaní vyhýbať. Budeme ho však používať na špecifikáciu.
Úloha. Zadefinujte funkciu , ktorej hodnotou je zoznam pozostávajúci z prvých prvkov zoznamu , teda
Napr. .
Špecifikácia
Nepoužite žiadne pomocné funkcie.
Testovanie.
Take_test = r:Results
Úloha. Zadefinujte funkciu , ktorá odstráni prvých prvkov zo zoznamu , teda
Napr. .
Špecifikácia
Nepoužite žiadne pomocné funkcie.
Testovanie.
Drop_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je najmenší prvok zoznamu . Napr. .
Pre prázdny zoznam funkcia vráti 0.
Nepoužite žiadne konštanty ako horné ohraničenia (99999 a podobne). Počas výpočtu nevytvárajte nové zoznamy.
Návod. Zistite, či má neprázdny zoznam práve jeden prvok (podobne ako pri ). Ak nie, použite vhodnú kombináciu rekurzívneho volania a funkcie definovanej na začiatku tohto súboru.
Iná možnosť: Použite pomocnú funkciu, ktorá si pamätá priebežné minimum v ďalšom argumente. Argument pri spustení správne inicializujte (nie konštantou!).
Testovanie.
Minl_test = r:Results_n
Odporúčanie. Na cvičeniach pokračujte riešením úloh z častí ex05b a ex05c. K nasledujúcim úlohám sa vráťte, ak Vám ostane čas, alebo v rámci domácej prípravy.
Úloha. Zadefinujte funkciu , ktorá zmení hodnotu -ého prvku zoznamu na , ak :
Ak , funkcia vráti nezmenený zoznam.
Napr. .
Špecifikácia
Nepoužite žiadne pomocné funkcie.
Testovanie.
Msub_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je zoznam párnych čísel zo zoznamu v pôvodnom vzájomnom poradí.
Napr. .
Testovanie.
Filter_even_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou pre zoznamy a rovnakej dĺžky je zoznam dvojíc prvkov zoznamov a :
Napr. .
Testovanie.
Zip_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je zoznam prirodzených v polouzavretom intervale .
Napr. .
Špecifikácia
Nepoužite zreťazenie.
Testovanie.
Range_test = r:Results
Úloha. Zadefinujte funkciu , ktorá aplikuje Fibonacciho funkciu na všetky prvky zoznamu a vráti zoznam výsledkov:
Špecifikácia
Použite funkciu , ktorá je zadefinovaná na začiatku tohto súboru.
Funkciu naprogramujte tak, aby sa dala použiť s akoukoľvek funkciou namiesto .
Testovanie.
Map_fib_test = r:Results
Úloha. Zadefinujte funkciu , ktorá vypočíta zoznam prvých prvkov Fibonacciho postupnosti, teda
Funkciu naprogramujte tak, aby sa dala použiť s akoukoľvek funkciou namiesto .
Nájdite explicitnú (t.j., nie rekurzívnu) definíciu využívajúcu predchádzajúce funkcie. Nepoužite zreťazenie.
Testovanie.
Table_fib_test = r:Results
Úloha. Zadefinujte funkciu , ktorej hodnotou je najväčší prvok zoznamu . Pre prázdny zoznam funkcia vráti 0.
Postupujte podobne ako pri funkcii a využite funkciu definovanú na začiatku tohto súboru.
Napr. .
Maxl_test = r:Results_n
Úloha. Zadefinujte funkciu , ktorej hodnotou je súčet všetkých prvkov zoznamu :
Napr. .
Testovanie.
Suml_test = r:Results
Úloha. Zadefinujte funkciu , ktorá zrotuje neprázdny zoznam doľava:
Napr. . Môžete použiť akékoľvek pomocné funkcie.
Testovanie.
Rotl_test = r:Results
Úloha. Zadefinujte funkciu , ktorá zrotuje neprázdny zoznam doprava:
Napr. . Môžete použiť akékoľvek pomocné funkcie.
Testovanie.
Rotr_test = r:Results
Prémiová domáca úloha du05. (1 + 1 + 2 + 1 bod)
Pravidlá pre prémiové domáce úlohy nájdete na http://dai.fmph.uniba.sk/courses/udp/#pdu
Časť d) sa nachádza v ex05c.
a) (1 bod) Naprogramujte funkciu podľa vyššie uvedeného zadania bez použitia pomocných funkcií a bez zreťazenia.
b) (1 bod) Naprogramujte funkciu podľa vyššie uvedeného zadania bez použitia pomocných funkcií a bez zreťazenia.
c) Asociatívne zoznamy. (2 body)
Definícia. Asociatívny zoznam je zoznam dvojíc kľúč-hodnota.
Naprogramujte funkcie a na prácu s asociatívnymi zoznamami.
Hodnotou funkcie je jednoprvkový zoznam , ak je prvá hodnota, ktorá je v asociatívnom zozname priradená kľúču . Ak taká hodnota neexistuje, hodnotou je prázdny zoznam.
Napríklad a .
Funkcia v asociatívnom zozname zmení prvú hodnotu priradenú kľúču na . Ak sa kľúč v zozname doteraz nenachádzal, pridá dvojicu na koniec .
Napríklad a .
Testovanie.
Lookup_test = r:Results Update_test = r:Results