Jesper Juellund Jensen      

Prolog-program til rytmemodeller

Rytme


Jeg vil i dette afsnit omforme den generelle model for rytme til Prolog. Det vil foregå ved først at vælge en datarepræsentation i Prolog og derefter omforme hver enkelt regel til prolog.


1. Datarepræsentation

Prolog kan naturligvis ikke umiddelbart arbejde med symboler som fjerdedelsnode og u. I stedet må der anvendes en repræsentation, som Prolog kan anvende.

Tal – teksttryk, tonelængder og metriske positioner

Der anvendes tal til at repræsentere teksttryk, tonelængder og metriske positioner (Bratko 1986: 28ff):

Teksttryk er repræsenteret ved heltal. Jeg har valgt at arbejde med seks teksttryk: 1 (u`), 2 (u), 3 (u´), 4 (-`), 5 (-) og 6 (-´).

Rytmiske længder er ligeledes repræsenteret ved med heltal. Da længder skal tilhøre det laveste lag i metrummet (regel d2), vil jeg for nemheds skyld lade denne rytmiske værdi være repræsenteret ved værdien 1. Man kan så selv bestemme, hvad man vil tolke det som: Hvis man for eksempel tolker 1 som 8.-delsnode , vil 4 være en repræsentation af halvnode osv.

Metriske positioner repræsenteres også ved heltal, der angiver afstanden fra startpositionen i metrummet. Positionen 0 er således typisk første slag i første (betonede) takt. Et andet eksempel er positionen 12, der – hvis startpositionen er første slag i første takt, det laveste lag i metrummet er 8.-delsnode , og taktarten er 4/4 – kan tolkes som tolv ottendedele efter første slag i første takt eller med andre ord 3-slaget i anden takt:

Positionen 12 som 3. slag i anden takt (i 4/4)

Struktur – toner

En tone består jo ifølge regel a2 af tre egenskaber:

a2) En „tone“ X er karakteriseret ved følgende tre egenskaber:
      XTeksttryk: Teksttrykket for tonens tekst
      XPosition: Tonens metriske position
      XLængde: Tonens rytmiske længde

I Prolog repræsenteres en tone ved et struktureret objekt (Bratko 1986: 30ff) – der også ofte bare kaldes en struktur. En struktur er netop en samling af egenskaber – i dette tilfælde af teksttryk, position og længde. En struktur har et navn (funktor), og jeg har her valgt navnet tone. En struktur angives som navnet efterfulgt af delene i parentes.

Et eksempel på en tone er tone(5,12,4), der således kan tolkes som en tone med en trykstærk stavelse (5 for -), der starter på 3-slaget i anden takt (12) og har længden halvnode (4):

tone(5,12,4) som en halvnode på 3. slag i anden takt (i 4/4)

Lister – metrum og rytmer

Metrummet (regel b1 og b2) vil blive repræsenteret af en liste af heltal. Som nævnt ovenfor vælger jeg altid at sætte det laveste lag i metrummet til tallet 1. I Prolog angives lister med kantede parenteser (Bratko 1986: 64ff), og et eksempel på en angivelse af et metrum er således [8,4,2,1]. Hvis man for eksempel antager, at 1 her er 8.-delsnode , er der altså tale om metrummet [ helnode  ,  halvnode  ,  fjerdedelsnode  ,  8.-delsnode  ].

En rytme er ifølge regel a3 defineret som en liste af toner. Et eksempel er rytmen [ tone(5,0,3) , tone(2,3,1) ] . Lad os her forudsætte, at startpositionen er første slag i første takt, og det laveste lag i metrummet er 8.-delsnode  . Vi kan så tolke de to toner:

Liste af to toner

  1. Den første tone, tone(5,0,3), har teksttrykket 5 (-), starter på metrummets startposition (0, dvs. 1-slaget i første takt) og har længden 3 (3·8.-delsnode = fjerdedelsnode .).
  2. Den næste tone, tone(2,3,1), har teksttrykket 2 (u), starter 3 8.-delsnode efter metrummets startposition (dvs. „2og“ i første takt) og har længden 1 (8.-delsnode ).

Når man henviser til lister, kan man undertiden brug for at opdele listen i det første element og resten. Dette gøres i Prolog ved hjælp af en lodret streg: L = [ A | Resten ]. Her betegner A således det første element, mens Resten betegner resten af listen.


2. Klausuler

Grundlæggende består Prolog-programmer af en række klausuler. En klausul definerer et eller andet forhold og kan have to former: faktum eller regel.

Faktum

Et faktum (Bratko 1986: 3ff) angiver et eller andet, der altid er sandt. Et eksempel fra Prolog-programmet, der definerer rytme, er:

teksttryk(1).

Denne regel angiver simpelthen blot, at 1 er et gyldig teksttryk.

Regel

En regel (Bratko 1986: 8ff), der angiver, at en konklusion er sandt, hvis en eller flere betingelser er opfyldt.

Et eksempel på en simpel regel er:

forælder(F, D) :- datter(D, F).

Denne regel siger, at hvis D er F’s datter, så er F følgelig D’s forælder. Eller med andre ord: Hvis betingelsen »D er F’s datter« er opfyldt, så er konklusionen »F er D’s forælder« sand. Som i eksemplet her, kan det undertiden være lettest at læse klausuler fra venstre mod højre.

Hvis flere betingelser skal være opfyldt, adskilles de af komma. For eksempel:

mor(M, D) :- datter(D, M), kvinde(M).

Denne regel siger altså (igen læst bagfra): Hvis betingelserne »M er en kvinde« og »D er M’s datter« er opfyldt, så er konklusionen »M er D’s mor« sand.

Reglerne ovenfor gør brug af variabler, der generelt skrives med stort begyndelsesbogstav (f.eks. „M“ eller „Resten“). Variabler anvendes, når man har brug for at henvise til „det samme“ flere gange i en regel.

En speciel variabel er _, der bare betyder „et eller andet“.

Rekursive regler

En rekursiv regel er en regel, der kan anvendes flere gange til at beskrive et eller andet. Man kan også sige, at en rekursiv regel er en regel, der anvender konklusionen i betingelsen. Rekursive regler anvendes blandt andet i logik, sprogvidenskab og datalogi. I musik kendes rekursion blandt andet fra Per Nørgårds kompositionsprincipper. Som eksempel kan tages reglen om tekstrytme ovenfor:

a1) En „tekstrytme“ for en frase er en liste med teksttryk

Denne regel kan omformes til en rekursiv regel:

a1+) En liste af et teksttryk og en tekstrytme er en tekstrytme

Hvis for eksempel vi har teksttrykket -´ og tekstrytmen [u,-,u], så siger regel a1+, at [-´,u,-,u] også er en tekstrytme.

Regel a1+ er dog ikke tilstrækkelig til at definere tekstrytme, hvilket vi kan se, hvis vi forsøger at anvende reglen til at undersøge, om for eksempel [u,-,u] er en tekstrytme. Dette vil foregå af følgende skridt:

  1. Da u er et teksttryk, så må [u,-,u] være en tekstrytme, hvis [-,u] er en tekstrytme, da [u,-,u] kan sammensættes af u og [-,u].
  2. Da - er et teksttryk, så må [-,u] være en tekstrytme, hvis [u] er en tekstrytme, da [-,u] kan sammensættes af - og [u].
  3. Da u er et teksttryk, så må [u] være en tekstrytme, hvis [] er en tekstrytme, da [u] kan sammensættes af u og [].

Men nu kan vi ikke komme længere med regel a1+, da [] ikke er sammensat af et teksttryk og en tekstrytme. Den tomme liste kan anskues som et grænsetilfælde og giver altså anledning til regel a1°, der siger, at [] er en tekstrytme:

a1°) En tom liste er en tekstrytme

Rekursive definitioner vil som regel være opbygget af to regler, som jeg her vil give symbolerne + og °:

  • + Selve den rekursive regel.
  • ° Det simplest mulige tilfælde, der blot er et faktum.

De to regler for tekstrytme kan nu let omformes til Prolog:

a1+) En liste af et teksttryk og en tekstrytme er en tekstrytme

tekstrytme( [ T | R ] ) :- teksttryk(T), tekstrytme(R).

Denne regel siger altså (igen læst bagfra): Hvis betingelserne »T er et teksttryk« og »R er en tekstrytme« er opfyldt, så er konklusionen »[T|R] er en tekstrytme« sand. Notationen [T|R] angiver som nævnt en liste, hvor T er det første element, og R er resten af listen.

a1°) En tom liste er en tekstrytme

tekstrytme( [] ).

Denne klausul er et simpelt faktum, der blot siger, at [] er en tekstrytme.

Jeg vil nedenfor i vid udstrækning gøres brug af rekursive regler, og en del af de oprindelige regler omformes til rekursive definitioner. Dette gælder i særdeleshed defintioner, hvor betingelser skal være opfyldt for alle elementer i en liste.


3. Simple data (regel a1-2 og d1-2)

Jeg har allerede ovenfor diskuteret datarepræsentationen, men vil her kort redegøre for de klausuler (fakta og regler), som det resulterer i i programmet.

Teksttryk

De seks teksttryk repræsenteres som nævnt ved heltal: 1 (u`), 2 (u), 3 (u´), 4 (-`), 5 (-) og 6 (-´). Dette kan i Prolog angives med følgende seks fakta:

teksttryk(1).    teksttryk(3).    teksttryk(5).
teksttryk(2).    teksttryk(4).    teksttryk(6).

Rytmiske længder

Rytmiske længder angives med heltal, hvor 1 er afstanden mellem slag i det laveste metriske lag, for eksempel 8.-delsnode  .

Man kan bemærke, at regel d2 – »længder skal tilhøre det laveste metriske lag i metrummet« – med denne repræsentation automatisk er opfyldt, da der kun anvendes heltal til længder, og da det laveste lag i metrummet jo altid sættes til 1.

I princippet kan længder være alle naturlige tal, da toner kan vilkårligt lange. Af hensyn til den procedurale mening af Prolog-programmet, må man dog konkret angive nogle gyldige længder. Da længder i de to modeller for rytmiske normer højst kan være tre gange det laveste metriske lag, kan længder altså være enten 1, 2 eller 3, hvilket i Prolog kan angives med følgende fakta:

laengde(1).     laengde(2).     laengde(3).

Rytmiske positioner

Rytmiske positioner repræsenteres jo også ved heltal, der angiver afstanden fra metrummets startposition.

Herved er også regel regel d1 – »positioner skal tilhøre det laveste metriske lag i metrummet« – automatisk opfyldt, da der kun anvendes heltal til positioner.


4. Rytme (regel a3-4 og d3)

Repræsentationen af data ifølge regel a1 og a2 (samt d1, d2) er nu beskrevet, og med hensyn til de simple data mangler nu blot definitionen af en „rytme“, således som den er beskrevet af regel a3, a4 og d3:

a3) En „rytme“ for en frase er en liste af toner

a4) For en given tone X og dens efterfølger Y, skal XPosition + XLængde = YPosition

d3) Den sidste tone skal ende på en position, der tilhører det næstlaveste metriske lag i metrummet/p>

Disse regler kan omformuleres til en rekursiv definition af rytme, hvor der skelnes mellem rytmer af mindst to toner og rytmer af præcis en tone:

r+) En liste af to toner, X og Y, og en rytme, R, er en rytme, hvis
        XPosition + XLængde = YPosition
    og
        listen af Y og R er en rytme

Regel r+ omhandler rytmer af mindst to toner. Reglen udnytter, at hvis den sidste tone i listen af Y og R ender på en positition, der tilhører det næstlaveste metriske lag i metrummet, så må det jo også gælde rytmen af Y, X og R. Der er derfor ingen grund til at medtage regel d3 i den rekursive regel om rytmer med mindst toner.

r°) En liste af én tone, X, er en rytme, hvis X ender på en position, der tilhører det næstlaveste metriske lag i metrummet

Regel r° handler om rytmen med netop én tone, og her er regel d3 relevant, da tonen i en rytme med kun en tone jo i sagens natur også er den sidste tone. Til gengæld er regel a4 ikke relevant, da den handler om rytmer med mindst to toner.

Disse to regler, r+ og r°, giver anledning til følgende to Prolog-regler, der altså udtrykker en rytme i et metrum:

rytme( [X,Y|R], Metrum ) :-
    X = tone(Xteksttryk,Xposition,Xlaengde),
    teksttryk(Xteksttryk),
    laengde(Xlaengde),
    Y = tone(Yteksttryk,Yposition,Ylaengde),
    teksttryk(Yteksttryk),
    Yposition is Xposition + Xlaengde,
    laengde(Ylaengde),
    rytme([Y|R], Metrum ).

rytme( [X], Metrum) :-
    teksttryk(Xteksttryk),
    laengde(Xlaengde),
    X = tone(Xteksttryk,Xposition,Xlaengde),
    Slutposition is Xposition+Xlaengde,
    tilhoererNaestlavesteMetriskeLag(Slutposition,Metrum).

Rytme med start i „første periode“

Med den angivne definition er begge nedenstående rytmer eksempler på rytmer:

To ens rytmer, der start i hhv. første og tredje takt

Men disse to rytmer opfattes jo som to udgaver af den „samme“ rytme, og for ikke helt bogstaveligt at få uendelig mange løsninger, vil jeg kræve, at rytmer skal starte i et bestemt tidsområde, som jeg vil kalde første periode. I eksemplet ovenfor i 4/4 er første periode den første takt. Generelt vil jeg definere første periode som [0 .. S-B], hvor S er det højeste lag i metrummet, og B er det laveste lag i metrummet.

Er metrummet for eksempel [ helnode  ,  halvnode  ,  fjerdedelsnode  ,  8.-delsnode  ], er S altså helnode , og B er 8.-delsnode  . S-B er derfor helnode 8.-delsnode  = halvnode ufjerdedelsnode u8.-delsnode eller med andre ord netop „4og“ i første takt. Første periode er altså fra 1-slaget til „4og“ i første takt.

I den valgte repræsentation kan det udtrykkes således:

Første periode er [0 .. S-1], hvor S er det højeste lag i metrummet

Er metrummet for eksempel [8,4,2,1], er første således periode [0 .. 7], og den første tone har altså et af disse tal som startposition.

Der defineres derfor en relation mellem en rytme og et metrum, hvor positionen af den første tone i rytmen skal være i „første periode“ af metrummet. Definitionen på en rytmeMedStartIFoerstePeriode kan angives således:

rytmeMedStartIFoerstePeriode([Tone|RestRytme], Metrum) :-
    iFoerstePeriode(P, Metrum),
    Tone = tone(_,P,_),
    rytme([Tone|RestRytme]).

Definitionen kan (læst bagrfra) udtrykkes således: Hvis listen af [ Tone | RestRytme ] er en rytme, Tone har positionen P, og positionen P er i første periode af Metrum, så er listen [ Tone | RestRytme ] en rytmeMedStartIFoerstePeriode i Metrum.

Jeg vil ikke her omtale relationen iFoerstePeriode, da den er forholdvis triviel.


5. Metrum (regel b1-2)

Metrummet (regel b1 og b2) et som nævnt repræsenteret ved en liste af heltal, hvor det laveste lag i metrummet er tallet 1. For eksempel vil [ helnode  ,  halvnode  ,  fjerdedelsnode  ,  8.-delsnode  ] således skulle angives [8,4,2,1].

Regel b2 indeholder et krav om at et tal (et lag) skal kunne udtrykkes som et multiplum af et andet tal (det efterfølgende lag). At et tal, X, kan udtrykkes som et multiplum af et andet, Y, kan også formuleres som, at Y-resten af X skal være 0: Hvis man dividerer X med Y skal resten altså være 0. I Prolog angives Y-rest af X som „ X mod Y“ (modulus), og at Y-resten af X skal være 0 skrives „(X mod Y) =:= 0“.

Reglerne om metrum omformuleres her til en rekursiv definition, der igen består af to regler:

m+) En liste af to lag, X og Y, og et metrum, M, er et metrum, hvis
          Y-resten af X er 0 (dvs. X kan udtrykkes som et multiplum af Y)
      og
          listen af Y og M er et metrum

 

m°) Listen [1] er et metrum

I Prolog kan disse to regler udtrykkes:

metrum([X,Y|M]):-
    (X mod Y) =:= 0,
    metrum([Y|M]).

metrum([1]).


6. At tilhøre et metrisk lag (regel c1-2 og til dels d3)

Positioner

Regel c1 definerer, hvad det vil sige, at en position tilhører et metrisk lag:

c1) En position P siges at „tilhøre“ et metrisk lag M, hvis P kan udtrykkes som et multiplum af M

Igen omformuleres reglen om at et tal, her P, skal være et multiplum af et andet, her M, til at M-resten af P skal være 0: (P mod M) =:= 0

I Prolog kan man derfor definere relationen tilhoerer mellem en position og et metrisk lag således:

tilhoerer(P,M) :- P mod M =:= 0.

Længder

Regel c2 definerer, hvad det vil sige, at en længde tilhører et metrisk lag:

c2) En længde L siges at „tilhøre“ et metrisk lag M, hvis L kan udtrykkes som et multiplum af M

Regel c2 er ikke nødvendig at definere i Prolog, da den eneste regel, der handler om længder og metriske lag (regel d2) – »længder skal tilhøre det laveste metriske lag, dvs. det sidste element, i metrummet» – jo som nævnt ovenfor allerede er opfyldt i kraft af repræsentationen.

At tilhøre det næstlaveste metriske lag

Ovenfor klaredes regel d3 om at sidste tone skal tilhøre det næstlaveste metriske lag ved at anvende relationen tilhoererNaestlavesteMetriskeLag, som jeg nu vil vende tilbage til. Relationen definerer, at en position tilhører det næstlaveste metriske lag i et metrum, og den kan defineres ud fra to regler i en rekursiv definition:

t+) Hvis P tilhører det næstlaveste lag i et metrum, M, så tilhører P også det næstlaveste lag i et metrum, der består af et vilkårligt lag og metrummet M

Et eksempel: Hvis P tilhører det næstlaveste lag i metrummet [4,2,1], så tilhører det også det næstlaveste lag i for eksempel metrummerne [8,4,2,1] og [12,4,2,1] – det næstlaveste lag er jo i alle tilfælde 2.

t°) Hvis P tilhører et metrisk lag, L, så tilhører P det næstlaveste metriske lag i et metrum af to lag, hvor det højeste (og dermed næstlaveste) lag er L

I Prolog kan disse to regler udtrykkes således:

tilhoererNaestlavesteMetriskeLag(P,[_|M]) :-
    tilhoererNaestlavesteMetriskeLag(P, M).

tilhoererNaestlavesteMetriskeLag(P,[L,_]) :-
    tilhoerer(P, L).


7. Metrisk betoning (regel e)

Reglen om metrisk betoning siger:

e) For et par af positioner P, Q gælder, at P „er mere metrisk betonet end“ Q, hvis og kun hvis P tilhører et højere metrisk lag end Q

Reglen kan omformuleres til, at det højeste metriske lag, som P tilhører i det givne metrum, skal være større end det højeste metriske lag, som Q tilhører. Der er derfor brug for en relation, der beskriver det højeste metriske lag, en position tilhører:

En positions højeste metriske lag

En positions højeste metriske lag kan formuleres ved hjælp af endnu en rekursiv definition:

e+) Hvis L er det højeste lag, som en position, P, tilhører i et metrum, M, så er L også det højste lag, som P tilhører i metrummet af et højere lag, H, og M, hvis P ikke tilhører H

Er M for eksempel [4,2,1], og P tilhører laget 2 i denne liste, er 2 også det højeste metriske lag, som P tilhører i listen af 8 og [4,2,1], dvs. [8,4,2,1], hvis P ikke tilhører laget 8.

e°) Hvis P tilhører det højeste lag, L, i et metrum, så er L det højeste lag i metrummet, som P tilhører

Er metrummet for eksempel [8,4,2,1], og en position tilhører det første lag i denne liste (8), er dette lag det højeste lag, som positionen tilhører – der ér jo slet ikke højere lag i metrummet.

Igen lader reglerne sig nu let oversætte til Prolog:

hoejesteMetriskeLag(P, [L|M], H) :-
    not tilhoerer(P,L),
    hoejesteMetriskeLag(P, M, H).

hoejesteMetriskeLag(P, [L|_], L) :-
    tilhoerer(P,L).

Forhold mellem metrisk betoning af to positioner

Selve definitionen af det metriske betoningsforhold mellem to positioner, P og Q, kan nu udtrykkes således:

erMereBetonet(P, Q, Metrum) :-
    hoejesteMetriskeLag(P, Metrum, Pmax),
    hoejesteMetriskeLag(Q, Metrum, Qmax),
    Pmax>Qmax.

Det højeste metriske lag, som P tilhører – her kaldet Pmax – i det givne metrum, skal altså være større end det højeste metriske lag, som Q tilhører – kaldet Qmax.


8. Afslutning – rytme

Alle reglerne for rytme er nu omformet til Prolog. De findes i dokumentet „Rytme.pro“ (inkl. en relation, harTekstrytmen, der ikke har været omtalt, og som først bruges senere):