Dagens föreläsning. TDDC67 Funktionell programmering och Lisp Fö 8 och 9

Relevanta dokument
Abstrakta datatyper. Dagens föreläsning. Abstract data types (ADT)

Dataabstraktion. TDDD73 Funktionell och impterativ programmering i Python Föreläsning 12. Peter Dalenius Institutionen för datavetenskap

Dataabstraktion. TDDD73 Funktionell och imperativ programmering i Python Föreläsning 12. Peter Dalenius Institutionen för datavetenskap

Dagens föreläsning Programmering i Lisp Fö 5

Tentamen i. TDDC67 Funktionell programmering och Lisp

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson 2

Uppgift 4A - Definition av enkla funktioner

Imperativ programmering. Imperativ programmering konstruktioner i Lisp. Datastrukturer (kap ) arraystruktur poststruktur

Dagens föreläsning. Diverse Common Lisp. Konstanter, parametrar, globala variabler

Två fall: q Tom sekvens: () q Sekvens av element: (a b c) ; (sum-rec '(2 4 6)) = 12. q Första elementet uppfyller vissa villkor: (2 a b c)

TDDC74 Programmering, abstraktion och modellering DUGGA 2

TDDC74 Programmering, abstraktion och modellering. Tentamen

Dagens föreläsning Programmering i Lisp. - Bindning av variabler (avs 14.6) fria variabler statisk/lexikalisk och dynamisk bindning

Uppgift 6A - Frekvenstabell

Rekursiva algoritmer sortering sökning mönstermatchning

Universitetet i Linköping Institutionen för datavetenskap Anders Haraldsson

TDDC74 Programmering, abstraktion och modellering. Tentamen

TDDC74 Programmering, abstraktion och modellering. Tentamen

Dagens föreläsning Programmering i Lisp Fö 7. Sammanfattning funktionell programmering Exempel på funktionella programspråk

Idag: Dataabstraktion

allt.cl Page 1 of 17 Date: torsdag 7 december 2006

TENTAMEN I PROGRAMSPRÅK -- DVG C kl. 08:15-13:15

LABORATION 1. Inledande Lisp - rekursion

TDDC74 Programmering: Abstraktion och modellering Datordugga 2 - exempel

TDDC74 Programmering: Abstraktion och modellering Tenta, kl 14 18, 11 juni 2014

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

n Detta för att kunna koncentrera oss på n Tal: number? n Symboler: symbol? n Strängar: string? n Tecken: char? n Boolskt: boolean?

TDDC74 Programmering, abstraktion och modellering DUGGA 2

Sista delen av kursen

Programspråkslingvistik. Sista delen av kursen. Ett programspråk

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Sista delen av kursen

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 3 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Symbolisk data. quote. (define a 1) (define b 2) (jacek johan david) (list a b)

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 08-12

TDDC74 Programmering: Abstraktion och modellering Datortenta

Exempel på typer av datorspråk EXCEL

Idag: Par och listor. Scheme. DA2001 (Föreläsning 6) Datalogi 1 Hösten / 29

TDDC74 Programmering, abstraktion och modellering. Tentamen

TDDC74 Programmering: Abstraktion och modellering Datortenta , kl 14-18

Idag. Javas datatyper, arrayer, referenssemantik. Arv, polymorfi, typregler, typkonvertering. Tänker inte säga nåt om det som är likadant som i C.

Idag: Par och listor. Symboler. Symboler används för att uttrycka icke-numeriska data såsom namn, adress, bilregisternummer, boktitel, osv.

Det är principer och idéer som är viktiga. Skriv så att du övertygar rättaren om att du har förstått dessa även om detaljer kan vara felaktiga.

TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 17-19

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 29 augusti 2015, kl 8 12

TDDC74 Programmering: Abstraktion och modellering Dugga 2, , kl 14-16

Instruktioner - Datortentamen TDDE24 och TDDD73 Funktionell och imperativ programmering (i Python)

Parameteröverföring. Exempel. Exempel. Metodkropp

Länkade strukturer. (del 2)

TDDC74 Lab 02 Listor, sammansatta strukturer

Lösningsförslag. TDDC74 Programmering: Abstraktion och modellering. Dugga 3 (provkod TEN1), Tid: kl 14-16, Datum:

TDDC74 Programmering: Abstraktion och modellering Tentamen, lördag 27 augusti 2016, kl 8 12

Föreläsning 1 Datastrukturer (DAT037)

Samlingar Collection classes

Programmering II (ID1019) :00-17:00

Signalflödesmodellen. Två (gamla) exempel: Kvadratera alla jämna löv.

Abstrakt datatyp. -Algoritmer och Datastrukturer- För utveckling av verksamhet, produkter och livskvalitet.

Idag: Dataabstraktion

Lambdas. (och fler design patterns) Objekt-orienterad programmering och design (DIT952) Niklas Broberg, 2017

Datalogi, grundkurs 1. Lösningsförslag till tentamen

TDDC74 PROGRAMMERING: ABSTRAKTION OCH MODELLERING VT 2017

TDDC74 Programmering: Abstraktion och modellering Tentamen, onsdag 9 juni 2016, kl 14 18

(Man brukar säga att) Java är... Denna föreläsning. Kompilering av Java. Historik: Java. enkelt. baserat på C/C++ Allmänt om Java

TDDE44 Programmering, grundkurs

Föreläsning 2 Datastrukturer (DAT037)

Digitalitet. Kontinuerlig. Direkt proportionerlig mot källan. Ex. sprittermometer. Elektrisk signal som representerar ljud.

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 11 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Introduktion till objektorientering. Vad är objektorientering egentligen? Hur relaterar det till datatyper? Hur relaterar det till verkligheten?

Tommy Färnqvist, IDA, Linköpings universitet

Tentamen ID1004 Objektorienterad programmering October 29, 2013

Statistik över heltal

Tentamen. Datalogi I, grundkurs med Java 10p, 2D4112, Lördagen den 30 november 2002 kl , salar E33, E34

Typsystem. Typsystem... Typsystem... Typsystem... 2 *

Ändringsbar (mutable compound) data. TDDC74 Programmering: abstraktion och modellering. Sätta - samman listor kopiering. Hitta sista cons-cellen

Typsystem. DA2001 (Föreläsning 23) Datalogi 1 Hösten / 19

TDDC74 Programmering, abstraktion och modellering DUGGA 3

TDDC74 Programmering, abstraktion och modellering DUGGA 1

Datastrukturer och algoritmer. Innehåll. Tabell. Tabell - exempel. Gränsyta till Tabell. Tabell. Modell. Hashtabell Relation, lexikon.

Programmering II (ID1019)

Föreläsningsanteckningar, Introduktion till datavetenskap HT S4 Datastrukturer. Tobias Wrigstad

Föreläsning 15: Repetition DVGA02

Programmeringsteknik II

Introduktion till formella metoder Programmeringsmetodik 1. Inledning

Exempel på typer av datorspråk EXCEL

Datastrukturer. Arrayer. Arrayer. Arrayer. Array av arrayer. Array av arrayer

Innehåll. F7: Tabell, hashtabell, relation & lexikon. Gränsyta till Tabell. Tabell. Tabell Hashtabell Relation Lexikon.

ITK:P1 Föreläsning 1. Programmering. Programmeringsspråket Java. Stark typning Explicit typning Strukturerat Hög säkerhet

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

TDDC74 Programmering: Abstraktion och modellering Dugga 2, kl 8 10, 5 mars 2015

Programmering A. Johan Eliasson

Introduktion till objektorientering. Vad är objektorientering egentligen? Hur relaterar det till datatyper? Hur relaterar det till verkligheten?

Komma igång med Allegro Common Lisp

Föreläsning 9 Innehåll

Klassdeklaration. Metoddeklaration. Parameteröverföring

Föreläsning 13. Träd

TENTAMEN: Algoritmer och datastrukturer. Läs detta!

Introduktion till Datalogi DD1339. Föreläsning 2 22 sept 2014

Språket Python - Del 1 Grundkurs i programmering med Python

Transkript:

1 Dagens föreläsning TDDC67 Funktionell programmering och Lisp Fö 8 och 9 Dataabstraktion - Abstrakta datatyper - datatypbeskrivning - datatyplikhet - sammansättningar av datatyper med sekvens, tupel, ändlig avbildning, mängd - val av primitiver beroende på sammansättning - ansvar för primitiver Komplexitet / abstraktion - abstraktionsbariärer (abstraction barriers) - gömma information (information hiding) Exempel: Deriveringsexempelet (kap 9) Genomgång av almanackan (kap 10) - datatyper - representation Orientering om objektorientering Datadriven programmering

2 Abstrakta datatyper Abstract data types (ADT) Denotes a class of objects whose behavior is defined by a set of values and a set of operations, including constructors, selectors and iterators. (Grady Booch, Software Components with ADA) Mål: - höja abstraktionen - programmeringsnivån - förstå struktur och operationer på dataobjekt - gömma representationen (information hiding) - kunna byta representationen Abstrakta datatyper är basen för objektorientering - klassbegreppet.

3 Datatyper Datatyper på olika nivåer: Hårdvaran ger oss vissa datatyper: bitar, heltal, flyttal, tecken Programmeringsspråket ger oss högre datatyper: Lisp ger heltal (godtycklig precision), bråk, flyttal, symbol, lista, tecken, sträng, post, arraystruktur etc etc Abstrakta datatyper beskriver nya datatyper, som ej direkt finns i programspråket: - allmänna datatyper, tex stack, kö, tabell, graf - tillämpningsnära datatyper, t ex formeluttryck, personer, bilar, LiTH'are, scheman, klockslag

4 En datatyp har en mängd med objekt. Vi kan tänka oss ändliga mängder (t ex sanningsvärdena) eller oändliga mängder som datatyper (t ex heltalen) Vi hanterar nu i kursen datatyper fritt, dvs vi kan bilda de datatyper (dvs mängder av dataobjekt) som är lämpliga för tillämpningen. Programspråk har vanligen restriktioner på hur datatyper kan skapas och sammansättas. Observera följande fall: - sammannlagda datatyper talen är unionen av heltalen, bråken och flyttalen - rekursiva datatyper binära träd är ett löv eller en sammansättning av två binära träd

5 Primitiva operationer på datatyper Dessa funktioner brukar kallas för datatypens gränsyta (interface) konstruktorer constructors - för att skapa objekt selektorer selectors - för att komma åt delarna igenkännare recognizers - för att känna igen objekt av viss datatyp iteratorer iterators - för att gå igenom alla elementen i ett objekt (ofta i form av en högre ordningens funktion) jämförare - när är objekt lika, delstrukturer modifikatorer modifiers - för att ändra i ett objekt andra operationer som det är vanligt att kunna utföra för en viss datatyp ex. aritmetiska operationer på tal

6 Arbetsmetodiken 1. Bestäm datatyper Studera tillämpningen. Identifiera datatyper. Karakterisera den mängd som beskriver dataobjekten. För sammansatta datatyper bestäm hur den ingående delarna är relaterade till varandra. 2. Bestäm primitiver constructor - skapa ett objekt recognizer - känna igen ett objekt selector - ta ut delarna i ett objekt iterator - gå igenom alla delarna i ett objekt andra primitiver 3. Bestäm representationen För varje datatyp bestäm hur de enskilda objekten skall representeras 4. Definiera primitiverna Definiera varje primitiv i den givna representationen

7 Första exemplet: Representationsberoende -> -> Representationsoberoende version Symbolisk derivering derivatan av x 2 med avseende på x är 2x Deriveringsregler: du ----- dx = 1 om u = x du ----- dx = 0 om u ej är en funktion i x du ( + v) du dv ------------------- = ----- + ----- dx dx dx du ( v ----------------- ) = v du ----- + u dv ----- dx dx dx d ( x + 4) = 1 dx d ( 3x + 4) ( 2x + 1) = ( 2x + 1) 3 + ( 3x+ 4) 2 dx

8 Representationsberoende (oabstrakt) version Valet av representation är inbyggt i själva algoritmen. Jämför hur ni löste logikvärdesuppgiften. Ett aritmetisk uttryck representeras och hanteras som en lista (uttryck operator uttryck) (deriv 'x 'x) => 1 (deriv '(x + 10) 'x) => (1 + 0) = 1 (defun deriv (expr x) (cond ((eq expr x) 1) ((symbolp expr) 0) ((eq (second expr) '+) (list (deriv (first expr) x) '+ (deriv (third expr) x))) ((eq (cadr expr) '*) (list (list (first expr) '* (deriv (third expr) x)) '+ (list (deriv (first expr) x) '* (second expr))) (t (error "Felaktigt uttryck: ~a" expr))))

9 Vilka dataobjekt består ett aritmetiskt utryck utav? Vi kan identifiera operatorer uttryck konstanter variabler sammansatt uttryck Ett sammansatt uttryck bildas av en operator och två uttryck uttryck konstant 2 17 6 x variabel y sammansatta-uttryck z x+y 2-(3+x) ((x+2)+1)+0 Vi inför de abstrakta datatyperna: operator, konstant, variabel, sammansatt-uttryck och uttryck.

10 För varje datatyp inför vi primitiva funktioner: Konstruktorer En eller flera operationer för att skapa objekt av datatypen. Funktionen cons är en konstruktor för listan eller punkterade paret. Selektorer Operationer för att ur sammansatta datatyper kunna ta ut delarna. Funktionerna first/car och rest/cdr är selektorer för listan och det punkterade paret. Igenkännare Recognizers. Operationer för att känna igen objekt av den givna datatypen. Funktionen listp är en recognizer för listan. Beskrivning av en funktions datatyp (signatur). Datatypen på de formella parametrarna och datatypen på värdet. Vi följer följande konvention: funktion: datatyp par1 x datatyp par2 x... -> datatyp värde

11 Konstruktorer skapa-summa: uttryck x uttryck -> sammansatt-uttryck skapar ett summa-uttryck från två uttryck skapa-produkt: uttryck x uttryck -> sammansatt-uttryck skapar ett produkt-uttryck från två uttryck skapa-konstant: lisp-tal -> konstant skapa-variabel: lisp-symbol -> variabel skapa-operator: lisp-symbol -> operator (skapa-konstant 3) => konstanten 3 (skapa-operator +) => operatorn + (skapa-summa uttrycket 4 uttrycket 5 * x ) => uttrycket 4 + 5 * x )

12 Selektorer argument-1: sammansatt-uttryck -> uttryck tar fram första argumentet ur ett sammansatt uttryck argument-2: sammansatt-uttryck -> uttryck tar fram andra argumentet ur ett sammansatt uttryck operator: sammansatt-uttryck -> operator tar fram operatorn ur ett sammansatt uttryck (operator uttrycket 4 + 3 ) => operatorn + (argument-2 uttrycket 4 + 3 ) => uttrycket 3

13 Igenkännare Recognizers konstant?: uttryck -> sanningsvärde testar om ett godtyckligt uttryck är en konstant variabel?: uttryck -> sanningsvärde testar om ett godtyckligt uttryck är en variabel summa?: sammansatt-uttryck -> sanningsvärde testar om ett sammansatt uttryck är ett summa-uttryck produkt?: sammansatt-uttryck -> sanningsvärde testar om uttrycket är ett produkt-uttryck Jämförare Här kan man diskutera olika möjligheter. Skall uttrycken vara exakt lika strukturellt eller räcker det med att uttrycket står för samma värde. Det kanske skall finnas två olika jämförare. samma-uttryck?: uttryck x uttryck -> sanningsvärde samma-värde?: uttryck x uttryck -> sanningsvärde

14 Representationsobereonde (abstrakt) version En ny version där representationen av uttryck ej syns. datatypsignatur (defun derivera (uttr var) ; uttryck x variabel -> uttryck (cond ((konstant? uttr) (skapa-konstant 0)) ((variabel? uttr) (if (samma-variabel? uttr var) (skapa-konstant 1) (skapa-konstant 0))) ((summa? uttr) (skapa-summa (derivera (argument-1 uttr) var) (derivera (argument-2 uttr) var))) ((produkt? uttr) (skapa-summa (skapa-produkt (argument-1 uttr) (derivera (argument-2 uttr) var)) (skapa-produkt (argument-2 uttr) (derivera (argument-1 uttr) var)))) (t (error "Felaktigt uttryck: ~a" uttr)))))

15 Val av representation Vi väljer följande representation: Objekten av datatypen konstant representeras som tal i Lisp. För att, av ett Lisp-tal, skapa ett objekt av den abstrakta datatypen konstant används funktionen skapa-konstant. Objekten av datatypen variabel representeras som symboler. Objekten av datatypen operator representeras enligt följande: operatorn + representeras som symbolen + Objekten av datatypen sammansatt-uttryck representeras som en lista på formen (uttryck operator uttryck)

16 Definition av primitiva funktioner: Konstruktorer (defun skapa-produkt (op1 op2) ; uttryck x uttryck -> (list op1 '* op2)) ; sammansatt-uttryck (defun skapa-summa (op1 op2)... ) (defun skapa-konstant (tal) tal) (defun skapa-variabel (var) var) ; lisp-tal -> konstant ; lisp-symbol -> variabel Selektorer (defun argument-1 (uttr) ; sammansatt-uttryck -> (first uttr)) ; uttryck (defun argument-2 (uttr)... ) (defun operator (uttr) ; sammansatt-uttryck -> (second uttr)) ; operator Igenkännare Recognizers (defun konstant? (uttr) (numberp uttr)) ; uttryck -> sanningsvärde Jämförare (defun samma-variabel? (var1 var2); variabel x variabel -> (eq var1 var2)) ; sanningsvärde

17 Ändring av representationen Vi behöver endast definiera om prinitiverna för en abstrakt datatyp. Tillämpningsprogrammen (t ex derivera-funktionen) skall ej behöva ändras. Vi kan till exempel ha en sk typad representation. Alla objekten representeras som en lista där första elementet anger objektets typ och andra elementet är själva värdet. Objekt av typen konstant representeras som (konstant Lisp-tal) Objekt av typen variabel representeras som (variabel Lisp-symbol) Objekt av typen operator representeras som (operator Lisp-symbol) Objekt av typen sammansatt-uttryck representeras som (uttryck (operator uttryck uttryck))

18 Primitiverna för varje abstrakt datatyp definieras om: (defun konstant? (uttr) ; uttryck -> lisp-sanningsvärde (eq (first uttr) 'konstant)) (defun operator (uttr) (second (second op)) ) ; sammansatt-uttryck -> operator (defun skapa-variabel (var) ; lisp-symbol -> variabel (list 'variabel var)) Man kan ha generella funktioner som lägger till resp tar bort typ-taggen (jfr almanackslabben) (typa-värde konstant 10) = konstanten 10 = (konstant 10) (värdet konstanten 10 ) = 10 (defun typa-värde (datatyp värde) (list datatyp värde)) (defun värdet (objekt) (second objekt)) (defun typen (objekt) (first objekt))

19 Vi kan ställa krav på våra primitiva funktioner. De skall kontrollera att argumenten är korrekta. En konstruktorfunktion skall aldrig kunna returnera ett dataobjekt som ej är korrekt enligt reglerna för datatypen. (defun skapa-produkt (op1 op2) ; uttryck x uttryck -> (if (and (uttryck? op1) ; sammansatt-uttryck (uttryck? op2)) (list op1 '* op2) (error fel datatyp )) (defun uttryck? (uttryck) (or (summa? uttryck) (produkt? uttryck))) Man skulle kunna tänka sig optimeringar: (skapa-summa (skapa-konstant 10) (skapa-konstant 0)) => 10

20 Sammansatta dataobjekt. Olika möjligheter att sätta samman med diskretmatematiska begrepp Tupel: ett fixt antal element, där varje element har en given datatyp <integer, symbol> <1, kalle>, <5, lisa>, <-100, hus> Sekvens: inget, ett eller flera element av given datatyp {{integer}}* (tomma sekvensen ingår) {{integer}} + (sekvensen har minst ett element) {{}}, {{1}}, {{1, 2}}, {{1, 2, 3}}, {{1, 1, 1, 1}} Ändlig avbildning (finite mapping): indexmängd med n antal element av en given datatyp. Position beskrivs av index ur indexmängden [integer, integer, integer, integer, integer] [1,3,5,7,9], [100, 99, 98, 97, 96] Mängd (potensmängden) {integer} {}, {1, 3, 5, 7}, {100, 101}

21 Exempel TUPEL Abstrakt datatyp datum: 3 februari, 12 april, 7 oktober <månadsdag, månadsnamn> 3 feb månadsdag är en grundläggande datatyp med värdena 1, 2 t.o.m. 31 månadsnamn är en grundläggande datatyp med värdena jan, feb, t.o.m. dec Är alla värden (tupler) av dessa två datatyper (mängder) korrekta datum? Nej. Endast 366 av de 12x31=372 möjliga värden är korrekta. Vi måste precisera oss noggrannare. Vissa kombinationer är ej giltiga! <30, feb>, <31, nov> Abstrakt datatyp mätvärden: {{heltal-0-till-9}}* SEKVENS 6 8 4 6 5 2 3

ÄNDLIG AVBILDNING Abstrakt datatyp betygstabell: 22 [integer, integer, integer, integer,] med index betygsgrad UK betygsgrad är en grundläggande datatyp med 3 värdena UK, 3, 4, 5 12 42 MÄNGD Abstrakt datatyp grupp: {klass} 5 19 där klass är en grundläggande datatyp med värdena anna, lisa, mia, stina, bo, sten och karl 4 28 anna bo lisa sten mia karl bo mia

Sammansättningar av datatyper och vanliga representationer i Lisp, Ada, Java, C/C++ tupel <d1, d2,.., dn> Lisp: lista post/struktur C/Ada: post - record, struktur (struct) Java: klassobjekt sekvens {{d}}* Lisp: lista C/Ada: länkad lista Java/C++: i programbibliotek (collections, STD) ändlig avbildning (map) [d, d,..., d] Lisp: associationslista arraystruktur hashtabell C/Ada: arraystruktur - array, fält, vektorer Java/C++: array, i progambibliotek (collections, STD) 23 mängd {d} Lisp: C/Ada: Java/C++: lista länkad lista i programbilbliotek (collections, STD) Valet beror även på om vi programmerar funktionellt med kopiering av strukturer eller om vi tillåter destruktiva ändringar i strukturer,

24 Ada har till exempel: tupel ändlig avbildning - post - arraystruktur type date is record day : 1..31; month : 1..12 end record; type year is array (1..12) of integer;

Hantering av en almanacka. 25 Detta är ett relativt stor exempel på hur vi kan strukturera större problem. I laboration 4 kommer ni att få en hel del kod och skall komplettera med egna funktioner och använda den för att lösa olika typer av problem. Laborarationen är ett krav för att få påbörja projektarbetet om några veckor. Vi vill kunna tillämpningsprogram som använder tid, datum, bokningar mm för att t ex kunna skriva tillämpningsprogram för - en personlig almanacka boka 10-12 den 12 jan för Lisp-fö skriv ut möten 12 jan - ett schemaläggningsystem Olika slags objekt: datum, månad, timme, minut, klockslag, mötestid, dagalmanacka, månadsalmanacka, årsalmanacka

Val av primitiva operationer för grundläggande/odelbara/primitiva datatyper: 26 Exempel: minut, timme, dagnummer, månad primitiva operationer: Konstruktor constructor skapar ett objekt konvertering av Lisp-objekt till abstrakt objekt Lisp-tal (10) -> minut Lisp-sträng ( januari ) -> månad igenkännare recognizer känna igen objekt konverteringsfunktion konvertering abstrakt objekt till Lisp-objekt in-/utmatningsfunktion andra operationer

27 Exempel på en primitiv datatyp: timme 1 timme 15 timmar skapa-timme : Lisp-naturligt-tal-> timme (skapa-timme 5) => 5 timmar timme? : Lisp-objekt -> sanningsvärde heltal : timme -> Lisp-heltal skriv-timme : timme -> addera-timme : timme x timme -> timme (skriv-timme (addera-timme (skapa-timme 5) (skapa-timme 7)))

28 Val av primitiver för sammansättningen med tupel Konstruktor skapa nytt objekt av givna delar en selektor för varje del ta ut en given del recognizer Exempel på tupel: klockslag = <timme, minut> 0<=timme<24, 0<=minut<60 skapa-klockslag : timme x minut -> klockslag timdel : klockslag -> timme minutdel : klockslag -> minut klockslag? : Lispobjekt -> sanningsvärde

29 Val av primitiver för sammansättning med ändlig avbildning ändlig avbildning: konstruktor skapa tomt objekt lägg in nytt värde för givet index selektor ta ut värde för givet index igenkännare recognizer iterator för varje element gör något

30 Exempel på ändlig avbildning: årsalmanacka = [månadsalmanacka,..., månadslamanacka] indexmängd är månad, dvs (jan, feb, mar..) skapa-tom-årsalmanacka : -> årsalmanacka lägg-in-ny-månadsalmanacka : månad x x månadsalmanacka x årsalmanacka -> -> årsalmanacka månadsalmanacka : månad x årsalmanacka -> -> månadsalmanacka årsalmanacka? : Lisp-objekt -> sanningsvärde för-varje-månad : årsalmanacka x (månad x månadsalmanacka ->) ->

31 Exempel på ändlig avbildning: årsalmanacka = [månadsalmanacka,..., månadslamanacka] indexmängd är månad, dvs (jan, feb, mar..) skapa-tom-årsalmanacka : -> årsalmanacka lägg-in-ny-månadsalmanacka : månad x x månadsalmanacka x årsalmanacka -> -> årsalmanacka månadsalmanacka : månad x årsalmanacka -> -> månadsalmanacka årsalmanacka? : Lisp-objekt -> sanningsvärde för-varje-månad : årsalmanacka x (månad x månadsalmanacka ->) ->

32 Val av primitiver för sammansättning med sekvens Sekvens: konstruktor skapa tomma objektet lägg till ett elem ent först selektor första elementet resten av elementen igenkännare recognizer tomma objektet iterator för varje element i objektet gör något

33 Exempel på sekvens: dagalmanacka = {{mötestid}}* skapa-tom-dagalmanacka : -> dagalmanacka lägg-in-mötestid : mötestid x dagalmanacka -> dagalmanacka första-mötestid : dagalmanacka -> mötestid resten-dagalmanacka : dagalmanacka -> dagalmanacka tom-dagalmanacka? : dagalmanacka -> sanningsvärde dagalmanacka? : Lisp-objekt -> sanningsvärde

34 Likhet av datatyper? klockslag = <timme, minut> kl 2.15 kl 23.45 tidsrymd = <timme, minut> 2 timmar 15 minuter 48 timmar 20 minuter Namnlikhet eller strukturlikhet Vad är tillåtet? klockslag + klockslag = klockslag klockslag + tidsrymd = klockslag tidsrymd + tidsrymd = tidsrymd

35 Krav på primitiver - kontrollera att datatypen på argumenten är korrekta - kontrollera att alla restriktioner och samband mellan ingående delar gäller - ett värde som en konstruktor skapar skall alltid vara korrekt! (skapa-klockslag (skapa-timme 25) (skapa-minut 100)) (lägg-in-ny-dagalmanacka (skapa-dag 31) Kalles-dag-almanacka (skapa-tom-månadsalmanacka (skapa-månad februari)))

36 Abstraktion - representation Vi vill gömma representationen för användaren (information hiding). (skapa-klockslag (skapa-timme 10) (skapa-minut 30)) => kl 10:30 (klockslag (timme. 10) (minut. 30)) Man får ej skapa eller ändra abstrakta objekt direkt i representationen. (skapa-tidsperiod '(klockslag (timme. 50)(minut. 100)) '(klockslag (timme. 55)(minut. 0))) => kl 50:100 - kl 55:00 Här anser vi att argumenten till skapa-klockslag är listor och av felaktig typ, ty skapa-tidsperiod: klockslag x klockslag -> tidsperiod Hur kontrolleras detta? I Lisp måste vi själva kontrollera detta. I typade språk (t ex Ada, Java) kan en del kontroller utföras av kompilatorn.

37 Exempel på tillämpningsfunktioner: (defun lägg-in-mötestid-om-ledigt (m-tid d-alm) ; mötestid x dagalmanacka -> dagalmanacka (if (ledig-tid? (tidsperiodsdel m-tid) d-alm) (lägg-in-möte m-tid d-alm)) d-alm)) (defun ledig-tid? (t-per d-alm) ; tidsperiod x dagalmanacka -> Lisp-sanningsvärde (cond ((tom-dagalmanacka? d-alm) t) ((överlappar? t-per (tidsperiodsdel (första-mötestid d-alm))) nil) (t (ledig-tid? t-per (resten-dagalmanacka d-alm))))) (defun överlappar? (t1 t2) ; tidsperiod x tidsperiod -> Lisp-sanningsvärde (and (före-klockslag (start-klockslag t1) (slut-klockslag t2)) (före-klockslag (start-klockslag t2) (slut-klockslag t1) ) ))) (defun före-klockslag (k1 k2) ; klockslag x klockslag -> Lisp-sanningsvärde (or (< (heltal (timdel k1)) (heltal (timdel k2))) (and (= (heltal (timdel k1)) (heltal (timdel k2))) (< (heltal (minutdel k1)) (heltal (minutdel k2))) )))

38 Typad representation Man måste från själva dataobjektet kunna avgöra dess abstrakta datatyp. Inför typmärkning av dataobjektet. (skapa-timme 10) => (timme. 10) (skapa-tom-dag-almanacka) => (dagalmanacka) timme klockslag årsalmanacka punkterat par på formen: (timme. Lisp-heltal) lista på formen: (klockslag timme minut) typad associationslista på formen: (årsalmanacka. ((januari. månadsalmanacka) (februari. månadsalmanacka)... (december. månadsalmanacka)) dagalmanacka lista på formen: (dagalmanacka mötestid... mötestid) Vi behöver två primitiver: Lägg till typmärkning och ta bort typmärkning. I boken funktionerna typa och värde. I laborationen packa-ihop och packa-upp.

Alternativ representation 39 Nytt förslag: Gles representation Har man stora dataobjekt behöver inte alla delar ha en explicit representation. För en strukutr som är sammansatt som en ändlig avbildning (t ex årsalmanackan) så behöver man inte ha plats för alla elementen (månadsalmanackorna) om ett element är tomt eller har ett standardvärde (t ex 0). Vi har endast lagra månadsalmanackor för mars och november. (årsalmancka (mars. icke-tom-månadsalmanacka ) (nov. icke-tom-månadsalmanacka )) Primitiven månadsalmanacka : månad x årsalmanacka -> månadsalmanacka måste definieras så att om inte månaden finns skall de returnera en tom månadsalamancka, som den primitiven skapar själv med skapa-tom-månadsalamancka.

40 Komplexitet - abstraktionsbarriärer Nivåuppdelning En tillämpning som använder almanackan, t ex Universitets schemaläggningssystem boka gemensamma-tider byggstenar skriv-ut DATOR LISP ALMANACKA append Lisp-primitiver Maskininstruktioner Hårdvaran ledig-tid? överlappar? lägg-in-dagalmanacka primitiver skapa-minut skapa-klockslag remove car lägg-in-möte-om-ledigt ADD mapcar cons eq + cond COMP JMP

41 Deklaration av datatyper Allla funktioner skall ha en kommentar eller dokumentationssträng som anger parametrarnas och värdets datatyper. (defun skapa-klockslag (tim min) timme x minut -> klockslag (defun skapa-klockslag (tim min) ;; timme x minut -> klockslag (defun skapa-klockslag (tim min) tim : timme, min : minut, värde : klockslag Många programspråk är sk starkt typade och kräver motsvarande deklarationer. Gäller för Ada och Java.

42 Notationen för datatypbeskrivning. fak: nat-tal -> nat-tal append: lista x lista -> lista derivera: uttryck x variabel -> uttryck subst: atom x atom x lista -> lista Vi ser datatyperna som mängder: xärkartesiska produkten (ordnat par, tupel) mellan mängder. -> avbildning (mapping) mellan två mängder Funktionen derivera är en avbildningen mellan ett par av ett uttryck och en variabel och en lista. En datatypbeskrivning brukar kallas för en funktions signatur.

43 Olika signaturer för en predikatfunktion: listp : Lisp-uttryck -> sanningsvärde för en funktion utan parametrar: (lambda () 10) : -> integer för en funktion som inte returnerar något (intressant) värde, ex (setf x (a b c)) setf : symbol x Lisp-uttryck -> (Java använder void för att ange inget värde) för en funktion som tar funktionsparametrar: (mapcar # (lambda (e)..) l) : (Lisp-uttryck -> Lisp-uttryck) x lista -> lista

44 Typerna i alla uttryck skall överensstämma. Vi kan ibland kunna härleda typen för en funktion. Vissa funktionella språk (ML och Haskell) gör detta. Vilken typ (av Lisp s typer) är denna funktion definierad för? (defun f (l) (mapcar # (lambda (n) (if (= n 0) noll ej-noll)) l))) f : lista av tal -> lista av symbol

45 Abstrakta datatyper - objekt-orienterad design (Ada, Java, C++) Inkapsling (encapsulation) Runt varje abstrakt datatyp har vi skapat primitiva funktioner (konstruktor, selektorer, iterators etc..) Inom objektorientering vill man starkt gruppera samma dessa och skapar därför klasser. En klass beskriver de data som skall ingå i objektet samt de funktioner (metoder) som skall operera på dessa data. Vi skapar sedan objekt från dessa klasser. Klass klockslag två datafält: timme, minut som i sin tur är objekt eller grundläggande värden t ex heltal konstruktor för att skapa ett objekt metoder: timdel, minutdel, klockslag+tidsperiod, skriv-klockslag etc Skapa objektet kl 10.15 (i Java) Klockslag kl10_15 = new Klockslag(new Timme(10), new Minut(15))

46 Låt konstruktorn normalisera och ev optimera sina argument. (skapa-summa (skapa-konstant 10) (skapa-konstant 0)) => konstanten 10 (skapa-tidsrymd (skapa-timme 10) (skapa-minut 200)) => 13 tim 20 min

47 Strukturen på sammansättningen beskriver programstrukturen Exempel. Utskrift av dataobjekt i almanackan. klockslag tupel <timme,minut> (defun skriv-klockslag (kl) klockslag -> (skriv-timme (timdel kl)) (princ # :) (skriv-minut (minutdel kl))) dagalmanacka sekvens {{mötestid}}* (defun skriv-dagalmanacka (dag) dagalmanacka -> (cond ((tom-dagalmanacka? dag) nil) (t (skriv-möte (första-mötestiden dag)) (skriv-dagalmanacka (resten-dagalmanacka dag))) ))

48 Hur gör vi med operationer som redan finns i Lisp, t ex aritmetik klockslag + tidsrymd -> klockslag 10:30 + 2 tim 45 min = 13:15 (kl+tr (skapa-klockslag (skapa-timme 10) (skapa-minut 30)) (skapa-tidsrymd (skapa-timme 2) (skapa-minut 45)) => 13:15 Alternativ 1: (defun kl+tr (kl tr) klockslag x tidsrymd -> klockslag (let ((minutes (min+ (minut-del kl) (minut-del tr)) (60-min (skapa-minut 60)) (1-tim (skapa-timme 1))) (if (min>= minutes 60-min) (skapa-klockslag (tim+ (tim+ (timdel kl) (timdel tr)) 1-tim)) (min- minutes 60-min)) (skapa-klockslag (tim+ (timdel kl) (timdel tr)) minutes)) )) Aritmetiska operationer för varje datatyp införs. (defun min+ (m1 m2) minut x minut -> minut (skapa-minut (+ (heltal m1) (heltal m2))))

49 Alternativ 2: Konvertera direkt till heltal och använd Lisp-operationerna (defun kl+tr (kl tr) klockslag x tidsrymd -> klockslag (let ((minutes (+ (heltal (minut-del kl)) (heltal (minut-del tr)))))) (if (>= minutes 60) (skapa-klockslag (skapa-timme (+ (heltal (timdel kl)) (heltal (timdel tr)) 1)) (skapa-minut (- minutes 60)) (skapa-klockslag (skapa-timme (+ (heltal (timdel kl)) (heltal (timdel tr))) (skapa-minut minutes)) ))) Nackdel: Alternativ 1 - många funktioner Alternativ 2 - ingen kontroll på att operationerna görs korrekt

50 Kan vi aldrig blanda in Lisp-objekt med i de abstrakta objekten? Jo, internt kan man vilja skapa strukturer som ej har en tillämpningsmotsvarighet, utan av programmeringspraktiska skäl vill vi ex vis samla på oss klockslag genom att bilda en lista av klockslag När börjar alla möten längre än 2 timmar den 17:e? Skriv ut dessa. (skriv-klocklista (långa-möten dag-17 2-tim)) (defun långa-möten (d tr) dagalmanacka x tidsrymd -> lista av klockslag (cond ((tom-dagalmanacka? d) ()) ((längre-möte? (första-mötestiden d) tr) (cons (start-klockslag (tidsperioddel (första-mötestiden d))) (långa-möten (resten-dagalmanacka d) tr))) (t (långa-möten (resten-dagalmanacka d) tr)))) (defun skriv-klocklista (kl-lista) lista av klockslag -> (mapc #'skriv-klockslag kl-lista)))

51 Datadriven programmering sid 169 - deriveringsexemplet Gör varje deriveringsregel till en funktion: (defun derivera-2 (uttr var) ; uttryck x variabel -> uttryck (cond ((konstant? uttr) (skapa-konstant 0)) ((variabel? uttr)...) ((summa? uttr) (derivera-summa uttr var)) ((produkt? uttr) (derivera-produkt uttr var))... här kan nya deriveringsregler läggas in (t (error... )) ))

52 Datadriven struktur: Lagra alla regler som funktioner (lambda-uttryck) i en datastruktur, t ex en associationslista: (setq *deriveringsregler* (list (cons + # (lambda (uttr var) ; utryck x variabel -> uttryck (skapa-summa...))) (cons * # (lambda (uttr var)...)) )) övriga regler Vi måste här skapa ett funktions-objekt genom att beräkna ett # - (function) uttryck

53 sid 170 (defun derivera-3 (uttr var) ; uttryck x variabel -> uttryck (cond ((konstant? uttr)..) ((variabel? uttr)..) ((deriveringsregel? (operator uttr)) (applicera-regel (hämta-regel (operator uttr)) uttr var)) (t (error...)) )) (defun deriveringsregel? (fn) (assoc fn *deriveringsregler*)) (defun hämta-regel (fn) (cdr (assoc fn *deriveringsregler*))

54 (defun applicera-regel (deriv-fn uttr var) ; (uttryck x variabel -> uttryck) x uttryck x ; x variabel -> uttryck (funcall deriv-fn uttr var)) Den datadrivna strukturen möjliggör nu att vi kan lägga till nya regler i form av Lisp-funktioner i associationslistan, utan att behöva gå in i programkoden!