ϵ">]>
13. CVIČENIE Z PREDMETU ÚVOD DO DEKLARATÍVNEHO PROGRAMOVANIA LS 2012/2013
http://dai.fmph.uniba.sk/courses/udp/ex/ex13.zip
Dátum: 6. 5. 2013
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
Literatúra.
[1] J. Kľuka. Prednášky z Úvodu do deklaratívneho programovania LS 2012/2013.
http://dai.fmph.uniba.sk/courses/udp/udp-prednasky-2013.pdf
[2] D. Guller. Poznámky k prednáškam z CL.
[3] J. Komara and P. J. Voda. Metamathematics of Computer Programming. 2001.
Na prednáške sme opísali postfixový stroj, ktorý vykonáva program (postupnosť inštrukcií) modifikáciou zásobníka čísel.
Inštrukcie postfixového stroja. Nasledujúce konštruktory kódujú inštrukcie postfixového stroja. Predikát platí pre kódy inštrukcií.
Všimnite si skutočné mená konštruktorov (, , , ).
Úloha. Zadefinujte predikát , ktorý platí, ak je kódom programu, teda zoznamom kódov inštrukcií.
Zásobník postfixového stroja. Postfixový stroj má zásobník čísel, ktorý sa mení počas behu programu. Inštrukcie pridávajú čísla na vrch zásobníka, alebo čísla z vrchu zásobníka odoberajú.
Zásobník zakódujeme zoznamom prirodzených čísel, pričom hodnota na vrchu zásobníka je prvým prvkom zoznamu.
Beh postfixového stroja. Postfixový stroj postupne vykonáva inštrukcie v programe. Inštrukcie menia zásobník nasledovným spôsobom (viď tiež ilustráciu v prednáškach [1, §18.1, str. 122]):
pridá číslo na vrch zásobníka.
pridá na vrch zásobníka kópiu čísla, ktoré sa nachádza v zásobníku na -tom mieste (počítajúc od 0).
odoberie zo zásobníka vrchnú hodnotu a hodnotu pod ňou a namiesto nich pridá na vrch zásobníka hodnotu .
odoberie zo zásobníka vrchnú hodnotu a hodnotu pod ňou a namiesto nich pridá na vrch zásobníka hodnotu .
Úloha. Odkrokujte na papieri beh nasledovných dvoch programov, ak začiatočný stav zásobníka je .
Úloha. Zjednodušte program na 3 inštrukcie, teda napíšte program , ktorý vypočíta na vrch zásobníka rovnaký výsledok ako , ale .
Úloha. Zadefinujte funkciu , ktorá simuluje beh postfixového stroja s programom na zásobníku .
Po skončení programu vráti funkcia hodnotu z vrchu zásobníka.
Použite funkciu () z modulu .
Úloha. Spustite programy a funkciou a overte, či ste ich správne odkrokovali.
Otestujte tiež svoje programy a na rôznych začiatočných stavoch zásobníkov:
3,5,7,0 = vs & Run(Prog1,vs) = rp1 & Run(Prog11,vs) = rp11
7 = n & Run(Prog3,n,0) = rp3 & n*(n+1) = x
Pomocou funkcie môžeme presne vyjadriť vlastnosti programov a :
Numerické výrazy s premennými. Numerické výrazy s premennými sú tvorené:
číselnými konštantami , , , …, , …,
premennými , , , …, , …,
aplikáciou sčítania na dva numerické výrazy a ,
aplikáciou násobenia na dva numerické výrazy a .
Kódovanie numerických výrazov s premennými. Numerické výrazy majú stromovú štruktúru. Môžeme ich zakódovať podobne ako binárne stromy. Použijeme nasledujúce konštruktory:
kóduje číselnú konštantu ,
kóduje premennú ,
kóduje súčet výrazov, ktoré sú zakódované číslami a ,
kóduje súčin výrazov, ktoré sú zakódované číslami a .
Predikát platí, ak je kód numerického výrazu.
Úloha. Vypočítajte hodnotu výrazov s kódmi a , ak premenná má hodnotu , premenná má hodnotu a premenná má hodnotu .
Úloha. Zjednodušte výraz tak, že súčet konštánt nahradíte jedinou konštantou. Zapíšte kód zjednodušeného výrazu:
Úloha. Zadefinujte denotačnú funkciu , ktorá vypočíta hodnotu numerického výrazu pri ohodnotení premenných . Ohodnotenie premenných je zoznam, v ktorom -ty prvok predstavuje hodnotu premennej .
Úloha. Vypočítajte hodnotu výrazov s kódmi a pomocou funkcie pri ohodnotení premenných .
Výpočtami pri rôznych ohodnoteniach otestujte, či ste správne určili :
3,5,7,0 = vs & Den(Term1,vs) = dt1 & Den(Term11,vs) = dt11
a :
7 = n & Den(Term3,n,0) = dt3 & n*(n+1) = dt31
Pomocou denotačnej funkcie môžeme presne vyjadriť vlastnosti výrazov a :
Programy počítajúce numerické výrazy. Všimnite si, že ak spustíme program so zásobníkom , na vrch zásobníka sa vypočíta hodnota výrazu pri ohodnotení premenných . Teda:
Podobný vzťah je medzi a i medzi a .
Úloha. Zadefinujte funkciu , ktorá skompiluje numerický výraz do programu pre postfixový stroj tak, že platí
Ako sme ukázali na prednáške, musíme použiť pomocnú funkciu , ktorá skompiluje výraz do programu, ktorý vypočíta hodnotu výrazu , keď sa na zásobníku nad ohodnotením nachádza medzivýsledkov :
Testovanie. Nasledujúce definície vám pomôžu pri testovaní kompilácie numerických výrazov. Napríklad dopyt:
Try(Term4,2,3,0) = x:Resf
by mal mať výsledok:
Úloha. Nájdite výrazy, ktorých hodnoty počítajú nasledujúce programy, teda pre daný nájdite taký , že platí
Táto úloha je opakom kompilácie, nazýva sa dekompilácia.
Program sa dá dekompilovať do výrazu tak, aby platilo . Pre program to ale neplatí. Výraz , ktorý nájdete, bude počítať rovnaké hodnoty, ale jeho kompiláciou dostanete iný program ako .
Prémiová domáca úloha du13. (3 body)
Pravidlá pre prémiové domáce úlohy nájdete na http://dai.fmph.uniba.sk/courses/udp/#pdu.
Definícia. Podvýraz výrazu nazývame konštantný, ak neobsahuje premenné. Konštantný podvýraz výrazu je maximálny, ak žiaden jeho nadvýraz v nie je konštantný.
Napríklad konštantnými podvýrazmi výrazu sú: , , a . Z nich a sú maximálne.
Zadanie. Zadefinujte funkciu , ktorá čiastočne vyhodnotí výraz , teda nahradí každý maximálny konštantný podvýraz výrazu konštantou , kde .
Príklad.
Návod. Naprogramujte vašu funkciu tak, aby postupovala zdola nahor: Najprv zavolajte rekurziu v tele klauzuly („za šípkou“). Ak rekurzia zredukuje oba podvýrazy na konštanty, môžete zredukovať aj celý výraz. Aby ste zbytočne nediskriminovali všetky možné výsledky rekurzívnych volaní, použite preddefinovaný predikát , ktorý platí práve vtedy, keď je konštanta. Pre vstupný výraz je tento postup naznačený v komponente funkcie nižšie.
Testovanie.
Parteval_test = r:Results_term