Uppgift 1 --------- På föreläsningen gick vi igenom ett exempel på deklarativ programmering där vi använde s.k. continuations för att hoppa tillbaka och försöka igen om en tilldelning inte blev som vi tänkt oss. Vi använde detta för att lösa ett problem angående vad Kalle köpte i kiosken. Koden från föreläsningen finns i filen amb_test.rb. Nu ska du, med samma metod, lösa ett problem där Kalle har varit och handlat i affären. Kalle köpte exakt tre varor, alla olika. De kostade tillsammans 69 kr och Kalle vill att du ska lista ut vad de enskilda varorna kostade. Han ger dig nio olika prislappar att välja mellan: 5, 8, 18, 20, 23, 24, 27, 35 eller 40. Skriv kod som visar alla unika möjligheter som man kan välja ut tre olika varor bland dessa priser som totalt blir 69 kr. Visa dessutom hur många olika kombinationer du har sökt igenom. Klistra in körexempel som en kommentar sist i koden. Uppgift 2 --------- Klassen DiceRoller definierar ett språk för enkla matematiska uttryck som involverar tärningsslag. Vi vill utöka språket så att vi kan definiera egna tärningar som har särskilda intervall. En tärning som har två till fyra prickar vill vi definiera så här: set a 2..4 Vi vill sedan kunna använda den genom att skriva da vilket slår en tärning av typ a, vilket bör ge ett svar i intervallet två till fyra. Utöka parsern i filen rdparse.rb så att man kan definiera och använda egna tärningar på detta sätt. Det ska även gå att slå tärningen flera gånger genom att sätta ett tal framför. Exempel: [diceroller] set a 2..4 [diceroller] da => 3 [diceroller] da => 2 [diceroller] 3da+1 => 9 Uppgift 3 --------- I filen constraint_networks.rb finns samma restriktionsnät som inför det fjärde seminariet. Skapa en ny typ av constraint Squarer som har två in- och utgångar som vi kan kalla n och sq_n. Om man ger n ett värde ska sq_n sättas till kvadraten av n. Om man ger sq_n ett värde ska n sättas till (den positiva) kvadratroten av n. Squarer ska inte implementeras genom att bygga ihop andra constraints, utan ska skrivas från grunden. Använd därefter denna nya constraint för att bygga upp ett nätverk som kan beräkna arean av en cirkel. Den är som bekant pi gånger radien i kvadrat. (Denna del av uppgiften kan lösas i teorin, men inte testas, utan att Squarer finns.) Ett bra värde på pi kommer man åt via Math::PI och kvadratroten kan beräknas med Math::sqrt. Du behöver inte fixa buggen i constraint- nätverket som skulle fixas till fjärde seminariet. Uppgift 4 --------- Stina och hennes företag Bookshop Solutions Ltd utvecklar programvara som tar hand om all information som en bokhandel behöver hantera: lager, fakturor, beställningar, kassakvitton, etc. Deras programvara är utvecklad i Ruby och för varje installation finns en konfigurationsfil som talar om grundläggande information om det aktuella företaget i form av ett antal strängar. Följande exempel finns även i filen config.rb: store_name "Berras bokhandel" company_name "Bertilssons Bokhandel AB" first_name "Bertil" last_name "Bertilsson" name first_name+" "+last_name receipt_header store_name receipt_footer "Välkommen åter önskar #{first_name}!" invoice_header "Faktura från #{company_name}" Stina vill att du ska betrakta konfigurationsfilen som ett litet domänspecifikt språk och skriva en mycket enkel parser för att läsa in denna information till ett Ruby-objekt, enligt de tekniker vi har gått igenom i kursen. Hon vill alltså att man ska kunna skriva t.ex. så här: >> c=Configuration.load("config.rb") => ... >> c.receipt_footer => "Välkommen åter önskar Bertil!" Implementera klassen Configuration. Uppgift 5 --------- Följande teorifrågor ger max 2,5 poäng vardera: a) Vad är en continuation? Hur skapas den, vad innehåller den och vad kan man ha den till? Ge ett kort körexempel som illustrerar din förklaring. b) Vad är fördelarna med att betrakta konfigurationsfilen i uppgift 4 som ett domänspecifikt språk? Vad skulle alternativet vara?