Kapitel 2: Modellierung Programmieren in Haskell 1 Eine Formelsprache für Musik Programmieren in Haskell 2 Formeln, die Musik bedeuten Note 0 (1/4) -Note 24 (1/1) -Pause (1/16) -Note 24 (1/4) :*: Note 26 (1/4) -Note 24 (1/4) :+: Note 28 (1/4) -Tempo 40 m -Tempo 100 m -Instr Oboe m -Instr VoiceAahs m -- Programmieren in Haskell Viertelnote tiefes C ganze Note c’ Sechzehntelpause :*: Note 28 (1/4) Anfang der C-Dur Tonleiter :+: Note 31 (1/4) C-Dur Akkord Musik m als Adagio Musik m als Presto Musik m von Oboe gespielt Musik m gesummt Modellierung: Eine Formelsprache für Musik 3 Formeltypen infixr 7 :*: infixr 6 :+: type GanzeZahl type Bruch type Ton type Dauer data Instrument data Musik Programmieren in Haskell = = = = = Int -- Ganze Zahlen und Brueche setzen wir Rational -- als gegeben voraus. GanzeZahl Bruch Oboe | HonkyTonkPiano | Cello | VoiceAahs deriving Show = Note Ton Dauer | Pause Dauer | Musik :*: Musik | Musik :+: Musik | Instr Instrument Musik | Tempo GanzeZahl Musik deriving Show Modellierung: Eine Formelsprache für Musik 4 Abkürzungen gP hP vP aP sP = = = = = Pause Pause Pause Pause Pause (1/1) (1/2) (1/4) (1/8) (1/16) adagio = 70; andante = 90; allegro = 140; presto = 180 Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 5 Halbtöne ce de eh ef ge ah ha = = = = = = = 0; 2; 4; 5; 7; 9; 11; c’ e’ g’ h’ u u u u = = = = cis dis eis fis gis ais his Note Note Note Note Programmieren in Haskell = = = = = = = 1; 3; 5; 6; 8; 10; 12 (ce+24) (eh+24) (ge+24) (ha+24) des es fes ges as be u; u; u; u; = = = = = = 1 3 4 6 8 10 d’ f’ a’ c’’ u u u u = = = = Note Note Note Note (de+24) (ef+24) (ah+24) (ce+36) u u u u Modellierung: Eine Formelsprache für Musik 6 C-Dur Tonleiter / Dur-Dreiklang cDurTonika = c’ (1/1) :+: e’ (1/1) :+: g’ (1/1) cDurSkala = Tempo allegro( c’ (3/8) :*: d’ (1/8) :*: e’ (3/8) :*: f’ (4/8) :*: g’ (1/8) :*: a’ (1/4) :*: h’ (1/8) :*: c’’ (1/2)) durDreiklang t = Note t (1/1) :+: Note (t+4) (1/1) :+: Note (t+7) (1/1) Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 7 Umkehrung / Transponierung umk ((Note t d) :+: n2 :+: n3) = n2 :+: n3 :+: (Note (t+12) d) transponiere transponiere transponiere transponiere transponiere transponiere i i i i i i (Pause d) (Note t d) (m1 :*: m2) (m1 :+: m2) (Instr y m) (Tempo n m) = = = = = = Pause d Note (t+i) d (transponiere i m1) :*: (transponiere i m1) :+: Instr y (transponiere i Tempo n (transponiere n (transponiere i m2) (transponiere i m2) m) m) gDurTonika = transponiere 7 cDurTonika Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 8 Gesetz Transponierung / Dur-Dreiklang transponiere i (durDreiklang t) = durDreiklang(t+i) Zur Überprüfung rechnen wir beide Seiten mittels der Definition von transponiere und durDreiklang aus und erhalten beide Male Note (t+i) (1/1) Programmieren in Haskell :+: Note (t+4+i) (1/1) :+: Note (t+7+i) (1/1) Modellierung: Eine Formelsprache für Musik 9 Verschiedenes wdh m = m :*: m ad_infinitum m = m :*: ad_infinitum m einsatz Programmieren in Haskell d m = (Pause d) :*: m Modellierung: Eine Formelsprache für Musik 10 Bruder Jakob phrase1 = c’ (1/4) :*: d’ (1/4) :*: e’ (1/4) :*: c’ (1/4) phrase2 = e’ (1/4) :*: f’ (1/4) :*: g’ (1/2) phrase3 = g’ (1/8) :*: a’ (1/8) :*: g’ (1/8) :*: f’ (1/8) :*: e’ (1/4) :*: c’ (1/4) phrase4 = c’ (1/4) :*: (transponiere (-12) (g’ (1/4))) :*: c’’ (1/2) strophe = wdh phrase1 :*: wdh phrase2 :*: wdh phrase3 :*: wdh phrase4 endlos = ad_infinitum strophe bruderJakob = Tempo andante (Instr VoiceAahs (einsatz (0/1) endlos :+: (einsatz (2/1) (transponiere 12 endlos)) :+: (einsatz (4/1) endlos) :+: (einsatz (6/1) endlos ))) Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 11 Bruder Jakob: Text Bruder Jakob, Bruder Jakob Schläfst du noch? Schläfst du noch? |: Hörst du nicht die Glocken? :| Ding dang dong, ding dang dong. Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 12 Typen als Hilfsmittel der Modellierung Programmieren in Haskell 13 Fehlerhafte Formeln Note 3/4 ce Pause Cello Tempo Oboe 100 Programmieren in Haskell Pause (1/2 :*: 1/4) Instr (Cello :+: Oboe) cDurTonika c’ :+: e’ :+: g’ Modellierung: Typen als Hilfsmittel der Modellierung 14 Einige Typen ce, cis, des, de, dis, es, eh, eis, fes, ef, fis :: Ton ges, ge, gis, as, ah, ais, be, ha, his :: Ton gP, hP, vP, aP, sP :: Musik cDurTonika :: Musik adagio, andante, allegro, presto :: GanzeZahl Programmieren in Haskell Modellierung: Typen als Hilfsmittel der Modellierung 15 Funktionstypen c’, d’, e’, f’, g’, a’, h’, c’’ :: Dauer -> Musik umk, wdh, ad_infinitum :: Musik -> Musik transponiere :: GanzeZahl -> Musik -> Musik transponiere 7 :: Musik -> Musik Programmieren in Haskell Modellierung: Typen als Hilfsmittel der Modellierung 16 Die Rolle der Abstraktion in der Modellierung Programmieren in Haskell 17 Abstrakte Noten tritonus_f_1 = Note ef (1/1) :+: Note ha (1/1) tritonus t d = Note t d :+: Note (t+6) d tritonus_f_1 :: Musik tritonus :: Ton -> Dauer -> Musik c’ u = Note (ce+24) u c’ :: Dauer -> Musik data Musik = Note Ton Dauer | ... Note :: Ton -> Dauer -> Musik Programmieren in Haskell Modellierung: Die Rolle der Abstraktion in der Modellierung 18 Modellierung in der molekularen Genetik Programmieren in Haskell 19 Nukleotide und Aminosäuren data Nucleotide = A | C | G | T data AminoAcid = | | | | | | | | Programmieren in Haskell deriving (Eq, Show) Ala Arg Asn Asp Cys Gln ... Trp Tyr Val ------- Alanin Arginin Asparagin Aspartat Cystein Glutamin -- Tryptophan -- Tyrosin -- Valin Modellierung: Modellierung in der molekularen Genetik 20 Kettenmoleküle A:C:C:A:G:A:T:T:A:T:A:T: ..., oder Met:Ala:Ala:His:Lys:Lys:Leu: ... Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 21 Polymorpher Listentyp data [a] = [] | a:[a] Programmieren in Haskell -- leere Kette -- (:) verlaengert Kette von a’s um ein a. Modellierung: Modellierung in der molekularen Genetik 22 Molekulare Sequenzen, Triplets type DNA = [Nucleotide] type Protein = [AminoAcid] type Codon = (Nucleotide, Nucleotide, Nucleotide) Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 23 Watson-Crick-Komplement wc_complement wc_complement wc_complement wc_complement Programmieren in Haskell A T C G = = = = T A G C Modellierung: Modellierung in der molekularen Genetik 24 DNA-Doppelstrang type DNA_DoubleStrand = (DNA,DNA) -- als Paar zweier Einzelstraenge type DNA_DoubleStrand’ = [(Nucleotide,Nucleotide)] -- als Kette von Watson-Crick-Paaren dnaDS_Exmpl1 = ([A,C,C,G,A,T],[T,G,G,C,T,A]) dnaDS_Exmpl2 = [(A,T),(C,G),(C,G),(G,C),(A,T),(T,A)] Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 25 Syntax und Semantik incorrectDoubleStrand = ([A,C,C,G,A,T],[T,G,G,C,A,T,C]) Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 26 DNA-Polymerase dnaPolymerase_Sequenz = Met:Ala:Pro:Val:His:Gly:Asp:Asp:Ser ... dnaPolymerase :: DNA -> DNA_DoubleStrand dnaPolymerase x = (x, complSingleStrand x) where complSingleStrand [] = [] complSingleStrand (a:x) = wc_complement a:complSingleStrand x Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 27 Ordentlich oder nicht? data Bool = True | False -- die abstrakten Urteile Wahr und Falsch wellFormedDoubleStrand :: DNA_DoubleStrand -> Bool wellFormedDoubleStrand (x,y) = (x,y) == dnaPolymerase x Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 28 Reparatur der Kopie exonuclease exonuclease exonuclease exonuclease exonuclease :: DNA_DoubleStrand -> DNA_DoubleStrand ([],[]) = ([],[]) ([],x) = ([],[]) -- Kopie wird abgeschnitten (x,[]) = dnaPolymerase x -- Kopie wird verlaengert (a:x,b:y) = if b == ac then (a:x’,b:y’) else (a:x’,ac:y’) where ac = wc_complement a (x’,y’) = exonuclease (x,y) exonuclease incorrectDoubleStrand ==> ([A,C,C,G,A,T],[T,G,G,C,T,A]) dnaCorr :: DNA_DoubleStrand -> DNA_DoubleStrand dnaCorr (x,y) = dnaPolymerase x Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 29 Genetischer Code genCode genCode genCode genCode genCode genCode genCode genCode genCode genCode ... :: Codon -> AminoAcid (A,A,A) = Lys; (A,A,C) = Asn; (A,C,_) = Thr (A,G,A) = Arg; (A,G,C) = Ser; (A,T,A) = Ile; (A,T,T) = Ile (A,T,G) = Met (C,A,A) = Glu; Programmieren in Haskell genCode (A,A,G) genCode (A,A,T) = Lys = Asn genCode (A,G,G) genCode (A,G,T) genCode (A,T,C) = Arg = Ser = Ile genCode (C,A,G) = Glu Modellierung: Modellierung in der molekularen Genetik 30 Translation ribosome :: DNA -> Protein ribosome (A:T:G:x) = Met:translate (triplets x) where triplets :: [a] -> [(a,a,a)] triplets [] = [] triplets (a:b:c:x) = (a,b,c):triplets x translate :: [Codon] -> Protein translate [] = [] translate (t:ts) = if aa == Stp then [] else aa:translate ts where aa = genCode t Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 31 Frames frames3 :: DNA -> [[Codon]] frames3 x = if length x < 3 then [[],[],[]] else [triplets x, triplets (tail x), triplets (tail(tail x))] where triplets :: [a] -> [(a,a,a)] triplets [] = [] triplets [_] = [] triplets [_,_] = [] triplets (a:b:c:x) = (a,b,c):triplets x findStartPositions :: [Codon] -> [[Codon]] findStartPositions [] = [] findStartPositions (c:x) = if c == (A,T,G) then (c:x):findStartPositions x else findStartPositions x Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 32 Open Reading Frames analyzeORFs :: DNA_DoubleStrand -> [[Protein]] analyzeORFs (strain,antistrain) = map (map translate) orfs where sixframes = frames3 strain ++ frames3 (reverse antistrain) orfs = map findStartPositions sixframes Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 33 Beispiele dna_seq3 = dnaPolymerase [A,A,T,G,T,C,C,A,T,G,A,A,T,G,C] analyzeORFs dna_seq3 ==> [[], [[Met, Ser, Met, Asn], [Met, Asn]], [[Met]], [[Met, Asp, Ile]], [], []] Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 34 dna_seq4 = dnaPolymerase [A,T,G,A,T,G,A,A,T,G,C,C,G,G,C,A,T,T,C,A,T,C,A,T] analyzeORFs dna_seq4 ==> [[[Met, Met, Asn, Ala, Gly, Ile, His, His], [Met, Asn, Ala, Gly, Ile, His, His]], [[Met, Pro, Ala, Phe, Ile]], [], [[Met, Met, Asn, Ala, Gly, Ile, His, His], [Met, Asn, Ala, Gly, Ile, His, His]], [[Met, Pro, Ala, Phe, Ile]], []] Programmieren in Haskell Modellierung: Modellierung in der molekularen Genetik 35 Anforderungen an Programmiersprachen • Ein strenges, aber flexibles Typkonzept • Ein hierarchisch organisierter Namensraum • Methoden zum Nachweis von Programmeigenschaften • Ein hohes Abstraktionsniveau Programmieren in Haskell 36