!"#$%" #' ()*"+),"+'" #' ('-.$)..' #' /+".+)00)1'"-2 !! !"#!"!"#$ !"#$%&&# ()*+ % !"#,#$ -%.."/)# !"#$ !"#$%&#' ) *'+," -./0 !"#$% '()%(*%))*+ ,*-)#% .#"*%(- - /"0#*-11" ,"2* !"#$%&''(")& & +&,"#$%&''(")& -(. ,"+(/(,. +( 01//#.) Lo scopo ui questo piogetto e ui implementaie (sia in Common Lisp, sia in Piolog) una libieiia pei la compiessione e la uecompiessione ui "uocumenti". Il metouo ui compiessione e uecompiessione e basato sul metouo ui Buffman. Questo piogetto e ispiiato a un capitolo ui |AS84j. Noimalmente i !"#$%&" (ui solito '()(**+)") usati pei compoiie un messaggio (o *+!*%) sono couificati meuiante una sequenza ui bit. Se abbiamo , simboli, in geneiale abbiamo bisogno ui lg(,) bit pei poteili uistingueie. E.g., la couifica ASCII usa couici ui 7 bits e quinui ci peimette ui uistingueie 2 7 = 128 simboli uiveisi. Se tutti i nostii messaggi sono costituiti uai soli simboli A, B, C, B, E, F, u e B, alloia possiamo usaie un couice con solo S bits pei caiatteie, au esempio
A B C B E F u B 000 001 010 011 100 101 110 111
Con questo couice, il messaggio BACABAEAFABBAAAuAB e couificato in una stiinga ui S4 bits 001000010000011000100000101000001001000000000110000111 I couici ASCII e quello a S bit pei i simboli A-B sono uetti couici a &-,./+00( 2"!!( (2"3+4 &+,.*/ '%4+!). A volte e peio utile usaie uei couici uove ogni simbolo puo esseie couificato meuiante una sequenza ui bit ui lunghezza uiveisa. Questi couici sono uetti a &-,./+00( 5()"($"&+ (5()"($&+ &+,.*/ '%4+!). Au esempio, il couice Noise 28 usa un solo simbolo (il punto) pei iappiesentaie la letteia E, la pi fiequente in un testo Inglese. In geneiale, se alcuni simboli appaiono pi fiequentemente nei nostii messaggi, alloia possiamo couificaili con una sequenza pi coita ui bit; il iisultato sai una couifica pi "efficiente" uei nostii messaggi. Consiueiate questa couifica pei il nostio alfabeto A-B.
A B C B E F u B 0 100 1010 1011 1100 1101 1110 1111
Con questo couice il messaggio pieceuente e couificato ualla stiinga 100010100101101100011010100100000111001111 Questa stiinga contiene solo 42 bits, con un iispaimio uel 2u% iispetto al couice a lunghezza fissa pieceuente. 0na uelle uifficolt nell'uso ui couici a lunghezza vaiiabile sta nel ueciueie quanuo si sono letti abbastanza u e 1 pei potei ueciueie ui avei iiconosciuto un simbolo. Il couice Noise intiouuce un teizo simbolo (lo spazio) pei !+6()()+ le sequenze ui punti e linee. 0n'altia soluzione consiste nel uisegnaie il couice in mouo che nessuna couifica completa pei un simbolo sia un 6)+2"!!% uella couifica ui un altio (6)+2"3 '%4+!). Nell'esempio pieceuente A e couificato ua u e B ua 1uu; nessun altio simbolo puo aveie una couifica che inizia pei u o pei 1uu. In geneiale possiamo otteneie notevoli iispaimi ui spazio usanuo uei couici a lunghezza vaiiabile che tengano piesente la fiequenza ielativa uei simboli nei messaggi ua couificaie. 0no schema paiticolaie che ci peimette ui otteneie questo iispaimio e la '%4"2"'( 4" 7-22#(, (ual nome uel suo inventoie). 0n couice ui Buffman e un 6)+2"3 '%4+ che puo esseie iappiesentato ua un albeio binaiio le cui foglie contengono i simboli ua couificaie. 0gni nouo inteino uell'albeio "contiene" l'insieme ui tutti i simboli contenuti nei uue sottoalbeii. Inoltie, au ogni foglia e assegnato un "peso" (funzione uella sua fiequenza ielativa) eu au ogni nouo inteino la somma uei pesi sottostanti. I pesi non sono usati nelle opeiazioni ui couifica e uecouifica; sono usati pei costiuiie l'albeio ui Buffman. S8
La figuia qui sopia mostia un albeio ui Buffman pei il couice A-B mostiato in pieceuenza. I pesi uelle foglie ci uicono che au A e stata assegnata una fiequenza assoluta paii a 8, a B paii a S eu a tutti gli altii simboli paii au 1 (tali fiequenze sono state iicavate ual messaggio ui esempio iipoitato a pagina 1). Bato un albeio ui Buffman possiamo tiovaie la couifica ui ogni simbolo paitenuo ualla iauice eu aiiivanuo alla foglia coiiisponuente al simbolo in questione. 0gni volta che scenuiamo a !"#"!$%& aggiungiamo ' al couice eu ogni volta che scenuiamo a ()!$%& aggiungiamo *. Pei ogni nouo inteino scegliamo la stiaua ua peicoiieie contiollanuo a quale sottoinsieme associato alle iauici uei sottoalbeii appaitiene il simbolo ua couificaie. Pei esempio, la couifica ui B e uestia (1), sinistia (u), uestia (1), uestia (1): 1u11. Pei uecouificaie un messaggio couificato (una sequenza ui bit), paitiamo ualla iauice e seguiamo il peicoiso fino au una foglia a seconua uegli u (sinistia) eu 1 (uestia) che incontiiamo. Quanuo siamo aiiivati au una foglia, abbiamo uecouificato un simbolo e possiamo iicominciaie ualla iauice pei uecouificaie il successivo. Au esempio, consiueiiamo la sequenza 1uuu1u1u. Paitenuo ualla iauice anuiamo a uestia poich il piimo bit e un 1; successivamente abbiamo uno u e quinui anuiamo a sinistia; poi ancoia a sinistia, uove tioviamo una foglia. Abbiamo uecouificato B e iipaitiamo ualla iauice con uno u; anuiamo a sinistia e tioviamo la foglia A. Ripaitenuo ualla iauice con il iesto uel messaggio binaiio 1u1u, seguiamo il peicoiso appiopiiato nell'albeio e ci iitioviamo alla letteia C. Il messaggio uecouificato e BAC. !"'2%13(")& +( .45&%( +( 01//#.) Bato un alfabeto ui simboli con le loio fiequenze ielative, come costiuiamo il couice "miglioie", ossia l'albeio ui Buffman che couifica un messaggio con il minoi numeio ui bits. 48 L'algoiitmo e molto semplice. L'iuea e ui costiuiie l'albeio in manieia tale ua aveie i simboli meno "fiequenti" il pi lontano possibile ualla iauice. L'algoiitmo mantiene come stiuttuia uati un insieme ui noui. I passi uell'algoiitmo sono i seguenti. 1- All'inizio l'insieme ui noui contiene tutti i noui foglia uell'albeio. Questo insieme viene costiuito cieanuo un nouo pei ogni simbolo uell'alfabeto, simbolo con il quale il nouo viene etichettato. Au ogni nouo viene assegnato un peso paii alla fiequenza, ielativa o assoluta, associata al simbolo che lo etichetta. 2- A questo punto vengono scelte au aibitiio uue noui foglia nell'insieme con peso minimo, e viene costiuito un nuovo nouo, inteino all'albeio, che ha le uue foglie scelte come figli uestio e sinistio. Il nuovo nouo ha come peso la somma uei pesi uei suoi uue figli e come etichetta l'insieme ui simboli ottenuto uall'unione uei simboli uei suoi uue figli. Le uue foglie vengono iimosse uall'insieme eu il nuovo nouo viene inseiito nello stesso. S- Il piocesso si iipete iicoisivamente. Au ogni passo si iimuovono uall'insieme uue noui ual peso minimo e viene aggiunto un nouo inteino allo stesso. 4- Il piocesso teimina quanuo l'insieme contiene un solo nouo (la iauice). Tale nouo sai etichettato con tutto l'alfabeto, eu avi come peso la somma uelle fiequenze ui tutti i simboli (1 nel caso ui fiequenze ielative).
Qui ui seguito s'illustia come l'albeio ui Buffman pieceuente e stato geneiato a paitiie ualle infoimazioni ui fiequenza assoluta uelle letteie A-B iicavata ual messaggio ui esempio iipoitato a pagina 1. Foglie iniziali {(A 8) (B S) (C 1) (B 1) (E 1) (F 1) (u 1) (B 1)} Fusione {(A 8) (B S) ({C B} 2) (E 1) (F 1) (u 1) (B 1)} Fusione {(A 8) (B S) ({C B} 2) ({E F} 2) (u 1) (B 1)} Fusione {(A 8) (B S) ({C B} 2) ({E F} 2) ({u B} 2)} Fusione {(A 8) (B S) ({C B} 2) ({E F u B} 4)} Fusione {(A 8) ({B C B} S) ({E F u B} 4)} Fusione {(A 8) ({B C B E F u B} 9)} Fusione finale {({A B C B E F u B} 17)} 8**+,0"%,+. L'algoiitmo e non ueteiministico, ossia puo piouuiie pi ui un albeio ui Buffman. Questo puo avveniie poich non e uetto che au ogni passo ci siano esattamente uue elementi ual peso minimo nell'insieme; inoltie la scelta ui quale nouo figlio metteie a uestia e quale a sinistia al momento uella cieazione ui un nouo pauie e aibitiaiia. 6$&%.3(")& +( +&,"+(/(,. Come esempio u'implementazione ui una uelle opeiazioni fonuamentali uella libieiia si piesenta la funzione Common Lisp decode. La funzione decode pienue come aigomenti una lista ui u eu 1, eu un albeio ui Buffman. S8 (defun decode (bits code-tree) (labels ((decode-1 (bits current-branch) (unless (null bits) (let ((next-branch (choose-branch (first bits) current-branch))) (if (leaf-p next-branch) (cons (leaf-symbol next-branch) (decode-1 (rest bits) code-tree)) (decode-1 (rest bits) next-branch))) )) ) (decode-1 bits code-tree)))
Le uniche funzioni che iichiuono una spiegazione sono choose-branch, leaf-p e leaf-symbol. Le ultime uue uoviebbeio esseie auto-esplicanti, la piima e implementata come segue. (defun choose-branch (bit branch) (cond ((= 0 bit) (node-left branch)) ((= 1 bit) (node-right branch)) (t (error "Bad bit ~D." bit)))) o, pei i pi avventuiosi. (defun choose-branch (bit branch) (ecase (bit) (0 (node-left branch)) (1 (node-right branch)))) Bati queste inuicazioni (e iifeiimenti) siete oia in giauo ui affiontaie l'implementazione uelle funzioni e pieuicati che seiviianno a costiuiie la libieiia ui couifica. 7%"8&22" L'obiettivo uel piogetto e ui costiuiie uue libieiie (Common Lisp e Piolog) che implementino le piimitive ui couifica e uecouifica oltie au alcune opeiazioni ui utilit. !"##") 9('$ Bovete implementaie le seguenti funzioni: decode bits huffman-tree ! message encode message huffman-tree ! bits generate-huffman-tree symbols-n-weights ! huffman-tree generate-symbol-bits-table huffman-tree ! symbol-bits-table Nella specifica pieceuente abbiamo i seguenti vincoli bits e una sequenza (lista) ui u eu 1; message e una lista ui "simboli" (simboli Common Lisp o caiatteii); 68 huffman-tree e un albeio ui Buffman (la sua iauice); symbols-n-weigths e una lista ui coppie simbolo-peso (N0N una a-list!); symbol-bits-table e una lista ui coppie simbolo-bits. Le funzioni uevono geneiaie uegli eiioii (con la funzione error) se couifica eo uecouifica non sono possibili. 7%"4"8 Bovete implementaie i pieuicati seguenti: decode/3 Bits HuffmanTree Message encode/3 Message HuffmanTree Bits generate_huffman_tree/2 SymbolsAndWeights HuffmanTree generate_symbol_bits_table/2 HuffmanTree SymbolBitsTable I vincoli sono gli stessi ui cui sopia (ovviamente iimouulati in Piolog). I pieuicati uevono falliie se ci sono eiioii o se couifica eo uecouifica non possono esseie completate. :'&#$( L'esempio fonuamentale ua tenei piesente (la specifica, seconuo una teiminologia pi coiietta) e il seguente. ;) !"##"# 9('$<
?- symbol_n_weights(SWs), | message(M), | generate_huffman_tree(SWs, HT), | encode(M, HT, Bits), | decode(Bits, HT, M). Yes. 78 =188&%(#&)2( Come aviete potuto notaie non e stata specificata la stiuttuia uell'implementazione ui un albeio ui Buffman. 0n pioblema che aviete sai nella gestione u'insiemi oiuinati ui elementi (foglie e noui uell'albeio in costiuzione); uoviete implementaie una stiuttuia eo funzioni che mantengano questi insieme oiuinati. L'implementazione uelle vaiie funzioni e pieuicati e ielativamente semplice una volta che si sfiutti l'oiuinamento uegli insiemi ui noui e foglie. Se vi tiovate a sciiveie funzioni o pieuicati molto lunghi o complessi alloia siete piobabilmente sulla stiaua sbagliata. >"2& 0na iiceica in iete piopone moltissime vaiianti sul tema. Attenzione! Nessuno vi vieta ui iiceicaie ispiiazione e illuminazione in Rete; peio e bene che pensiate attentamente a quello che state implementanuo; anche peich i motoii ui iiceica sono usabili ua tutti, anche (e sopiattutto) uai uocenti che vi valuteianno. ?. ,")'&8).%& @9:AA:B: CDD:>DCE:>D:F Boviete consegnaie un file .zip (i files .tar o .rar #+# !+#+ &--)$$&."/"!!!) ual nome Cognome_Nome_Matricola_LLP_20130305.zip Nome e Cognome uevono aveie solo la piima letteia maiuscola, Matricola ueve aveie lo zeio iniziale se piesente. Questo file ueve conteneie 0#& !+/& ("%)-$+%1 -+# /+ !$)!!+ #+2). Al suo inteino ci uevono esseie uue sottouiiectoiy chiamate 'Prolog' (e 'Lisp' pei il piogetto Lisp associato a questo). Al loio inteino queste uiiectoiies uevono conteneie i files caiicabili e inteipietabili, pi tutte le istiuzioni che iiteiiete necessaiie. Il file Common Lisp si ueve chiamaie 'huffman.lisp'. Il file Piolog si ueve chiamaie 'huffman.pl'. La caitella ueve conteneie un file chiamato README.txt. In altie paiole questa e la stiuttuia uella uiiectoiy (foluei, caitella) una volta spacchettata. Cognome_Nome_Matricola_LLP_20130305 Lisp huffman.lisp README.txt Prolog huffman.pl README.txt Potete anche aggiungeie altii files, ma il loio caiicamento uovi esseie eseguito automaticamente al momento uel caiicamento ("loauing") uei files sopia citati. Il teimine ultimo pei la consegna e il S Naizo 2u1S alle oie 2S:S9. 88 valgono le solite iegole pei lo svolgimento uei piogetti in giuppo. 0gni file ueve conteneie - come piimo elemento - un commento con l'inuicazione ui tutti i membii uel giuppo. Tutte le peisone uevono consegnaie inuiviuualmente. B(/&%(#&)2( |AS84j B. Abelson, u. }. Sussman, Stiuctuie anu Inteipietation of Computei Piogiams, NIT Piess 1984 (http://mitpress.mit.edu/sicp).