Kapitel 2: Modellierung Programmieren in Haskell 1
Eine Formelsprache für Musik Programmieren in Haskell 2
Formeln, die Musik bedeuten Note 0 (1/4) -- Viertelnote tiefes C Note 24 (1/1) -- ganze Note c Pause (1/16) -- Sechzehntelpause Note 24 (1/4) :*: Note 26 (1/4) :*: Note 28 (1/4) -- Anfang der C-Dur Tonleiter Note 24 (1/4) :+: Note 28 (1/4) :+: Note 31 (1/4) -- C-Dur Akkord Tempo 40 m -- Musik m als Adagio Tempo 100 m -- Musik m als Presto Instr Oboe m -- Musik m von Oboe gespielt Instr VoiceAahs m -- Musik m gesummt Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 3
Formeltypen infixr 7 :*: infixr 6 :+: type GanzeZahl = Int -- Ganze Zahlen und Brueche setzen wir type Bruch = Rational -- als gegeben voraus. type Ton = GanzeZahl type Dauer = Bruch data Instrument = Oboe HonkyTonkPiano Cello VoiceAahs deriving Show data Musik = Note Ton Dauer Pause Dauer Musik :*: Musik Musik :+: Musik Instr Instrument Musik Tempo GanzeZahl Musik deriving Show Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 4
Abkürzungen gp = Pause (1/1) hp = Pause (1/2) vp = Pause (1/4) ap = Pause (1/8) sp = Pause (1/16) adagio = 70; andante = 90; allegro = 140; presto = 180 Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 5
Halbtöne ce = 0; cis = 1; des = 1 de = 2; dis = 3; es = 3 eh = 4; eis = 5; fes = 4 ef = 5; fis = 6; ges = 6 ge = 7; gis = 8; as = 8 ah = 9; ais = 10; be = 10 ha = 11; his = 12 c u = Note (ce+24) u; d u = Note (de+24) u e u = Note (eh+24) u; f u = Note (ef+24) u g u = Note (ge+24) u; a u = Note (ah+24) u h u = Note (ha+24) u; c u = Note (ce+36) u Programmieren in Haskell 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 i (Pause d) = Pause d transponiere i (Note t d) = Note (t+i) d transponiere i (m1 :*: m2) = (transponiere i m1) :*: (transponiere i m2) transponiere i (m1 :+: m2) = (transponiere i m1) :+: (transponiere i m2) transponiere i (Instr y m) = Instr y (transponiere i m) transponiere i (Tempo n m) = Tempo n (transponiere n 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) :+: Note (t+4+i) (1/1) :+: Note (t+7+i) (1/1) Programmieren in Haskell Modellierung: Eine Formelsprache für Musik 9
Verschiedenes wdh m = m :*: m ad_infinitum m = m :*: ad_infinitum m einsatz d m = (Pause d) :*: m Programmieren in Haskell 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 (1/2 :*: 1/4) Pause Cello Instr (Cello :+: Oboe) cdurtonika Tempo Oboe 100 c :+: e :+: g Programmieren in Haskell 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 deriving (Eq, Show) data AminoAcid = Ala -- Alanin Arg -- Arginin Asn -- Asparagin Asp -- Aspartat Cys -- Cystein Gln -- Glutamin... Trp -- Tryptophan Tyr -- Tyrosin Val -- Valin Programmieren in Haskell 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] = [] -- leere Kette a:[a] -- (:) verlaengert Kette von a s um ein a. Programmieren in Haskell 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 A = T wc_complement T = A wc_complement C = G wc_complement G = C Programmieren in Haskell 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 :: DNA_DoubleStrand -> DNA_DoubleStrand exonuclease ([],[]) = ([],[]) exonuclease ([],x) = ([],[]) -- Kopie wird abgeschnitten exonuclease (x,[]) = dnapolymerase x -- Kopie wird verlaengert exonuclease (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 :: Codon -> AminoAcid gencode (A,A,A) = Lys; gencode (A,A,G) = Lys gencode (A,A,C) = Asn; gencode (A,A,T) = Asn gencode (A,C,_) = Thr gencode (A,G,A) = Arg; gencode (A,G,G) = Arg gencode (A,G,C) = Ser; gencode (A,G,T) = Ser gencode (A,T,A) = Ile; gencode (A,T,C) = Ile gencode (A,T,T) = Ile gencode (A,T,G) = Met gencode (C,A,A) = Glu; gencode (C,A,G) = Glu... Programmieren in Haskell 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