Det er almindeligt anerkendt indenfor sprogvidenskaben, at menneskets evne til at digte oprindeligt stammer fra digtermjøden, som er brygget på visdomsguden Kvasers blod. Vores poetiske sans er altså en del af den rus, som har cirkuleret i hele menneskehedens fælles blodårer, lige siden vi for et mytologisk antal generationer siden smagte dette rimeglade rusmiddel for første gang.
I anledning af min eksamen i computerlingvistik har jeg valgt at destillere et par dråber af min egen beskedne andel af den litterære læskedrik for at producere et program, som tager del i denne rus – mere specifikt et computerprogram, som kan skrive sine egne digte.
For dem, der allerede har kendskab til computerprogrammering, vil mit projekt givetvis synes ret enkelt. Der findes allerede programmører, som kan lære computere at digte med langt større kreativitet og elegance end jeg kan med mine få måneders erfaring med at kode i Python (hvilket i denne sammenhæng er navnet på et programmeringssprog, og dermed kun en smule mere intimiderende end en rigtig pythonslange). Men hvis du er en sprognørd, der ikke har nogen erfaring med at programmere, og hvis du undrer dig over, hvad computerprogammering overhovedet har at gøre med lingvistik, så tror jeg, at mit projekt er et godt eksempel på, hvad sprog og computere kan bruge hinanden til – og dét er grunden til, at jeg vælger at dele det her på bloggen.
Lige et par korte bemærkninger, inden jeg begynder at beskrive mit program: For det første har jeg indtil videre kun lært funktionen engelske ord, så alle dens digte er på engelsk. For det andet er dette indlæg hovedsageligt rettet mod læsere, der ikke har forhåndsviden om programmering (præcis som mig selv for et års tid siden), så jeg kommer ikke til at bruge en overflod af fagtermer. Så hvis du gerne vil have et indblik i oplevelsen af at programmere, men ikke ved om du har mod på den tekniske side, så læs endelig videre!
Når jeg skriver, at mit program kan finde ud af at skrive digte, overdriver jeg måske en smule. I min eksamensopgave definerer jeg et digt som “En tekst bestående af alment accepterede ord, som passer i et givent poetisk meter”. Den opmærksomme læser bemærker måske, at jeg hverken nævner syntaks eller betydning, hvilket ellers – som enhver lingvist kan bekræfte – er forholdsvis vigtige elementer, når det kommer til sprog. Denne udeladelse kommer sig af, at mit program faktisk slet ikke tager højde for disse dele af sproget, hvilket resulterer i digte som det følgende:
Descend parade this parrot rat declare,
if prance profound compare two made is flare
De fleste af digtene er i samme dur: Tekster, som kunne være taget direkte ud af en førsteårssprogstuderendes værste mareridt (bed mig ikke om at tegne et syntakstræ over dét digt!). Men selvom digtet på overfladen er komplet nonsens, følger det stadig visse mønstre; i dette tilfælde er mønsteret en kuplet, altså et digt på to linjer, der rimer til sidst.
For at en tekst kan passe i sådan et mønster, er der tre ting, der må gøre sig gældende. For det første skal teksten have det rette antal stavelser. For det andet skal den have tryk på de rigtige stavelser. Og for det tredje skal den rime lige netop de steder, som meteret kræver (i dette tilfælde er det f.eks. i slutningen af hver linje). Mit mål, da jeg skrev mit program – eller funktion, som det også kaldes – var at få den til at generere tekster, der opfyldte disse tre krav. Og for at være ærlig, var jeg allerede på det tidspunkt klar over, at det ville overstige mit nuværende niveau også at få tekster til noget så indviklet som at give mening.
De overvejelser satte altså rammerne for, hvad mit projekt skulle kunne: Skrive digte, men ikke nødvendigvis digte der betyder noget. Men hvordan bare jeg mig så ad med dét? Min funktion består af tre dele. Den første del indeholder informationer om alle de forskellige typer digte, funktionen kan producere. Jeg har lært den fem forskellige poetiske metre, hver med sin egen kombination af antal stavelser, trykfordeling og rim.
Del nummer to er ordforrådet. Denne del består grundlæggende af en stor æske med en masse ord i. Men for hvert af disse ord har jeg tilføjet et par ekstra stykker information: Hvor mange stavelser har ordet, hvilken stavelse ligger trykket på, og hvilke andre ord rimer det på?
Den tredje del er selve kernefunktionen, altså et sæt instruktioner til, hvordan funktion skal bære sig ad, når den skriver et digt. Den begynder med at stille et spørgsmål: Hvilken slags digt skal jeg skrive? Dette besvarer man ved at vælge en af de fem digttyper, jeg har programmeret ind i funktionen. Derefter kigger funktionen igennem hele sit ordforråd, og for hvert enkelt ord stiller den spørgsmålet: Passer dette ord i denne type digt?
Når den så står tilbage med en liste over alle de ord der passer, fylder den meteret med tilfældigt udvalgte ord fra den liste. Og på et lidt forenklet plan er det sådan, min funktion fungerer!
Det betyder dog ikke, at vejen allerede nu var fuldstændigt fri for forhindringer. Det første digt, jeg fik funktionen til at skrive, så sådan her ud:
‘astoundachooachooachooastound/
subdueachooprofoundprofoundastound’
Selvom disse to linjer rent ud sagt emmer af poetisk ynde, vil du nok være enig med mig i, at et par mellemrum ville pynte gevaldigt. Men selv efter mellemrummene er tilføjet, var der stadig et par problemer, jeg måtte tage mig af:
‘astound achoo achoo achoo astound /
subdue achoo profound profound astound’
Ser man bort fra nyseanfaldet i midten af den første linje, er det største problem i dette digt, at det rimer ‘astound’ med ‘astound’. Teknisk set lever det op til mine krav, men det er altså ikke den mest imponerende digterkunstneriske manøvre, så jeg besluttede mig for at tilføje lidt ekstra kode til min funktion, som ville forhindre den i at rime et ord med sig selv, medmindre det viste sig at være strengt nødvendigt. Det viser sig sjovt nok, at min funktion i denne sammenhæng tolker ‘kun hvis det er strengt nødvendigt’ som ‘indimellem, men kun i limericks’.
Nyseriet er en følge af, at jeg på dette tidspunkt ikke havde lært min funktion særligt mange forskellige ord, så den gjorde sit bedste for at udfylde digtet ved at gentage det samme ord mange gange. Men det begrænsede ordforråd viste sig også på andre måder. Jeg havde programmeret funktionen til at indsætte bogstavet X, når den ikke kunne finde et ord, der passer i meteret – et lille x for hver stavelse uden tryk, og et stort X for hver stavelse med tryk. På den måde vidste jeg for eksempel, at jeg manglede ord med strukturen xXx, da min funktion gav mig denne såkaldte limerick:
‘xXx xXx achoo / xXx xXx subdue / xXx profound / xXx astound /
xXx xXx subdue’
Det var på dette tidspunkt, at jeg i et øjeblik blev så opslugt af min egen kode, at jeg glemte, at mit improviserede system med X’erne ikke var en universelt udbredt måde at beskrive stavelsesstrukturer. Så jeg besluttede mig for at prøve at finde nogle flere af denne slags ord ved at søge på nettet efter ‘syllable structure xXx’.
Et godt råd: Vær forsigtig med at søge efter noget som helst, der indeholder en række af tre X’er. Det viser sig nemlig, at søgemaskiner har en helt bestemt måde at tolke dét på.
I sidste ende lykkedes det mig at tilpasse funktionen, så den slet ikke behøver xXx-ord, ved at få den til at kigge efter to korte ord i stedet for ét langt. Dette er kun én af den slags udfordringer, man kan løbe ind i, når man koder, og det er et godt eksempel på min egen oplevelse med at skrive en funktion.
Funktionen er nu færdiggjort, og man kan følge dette link for at prøve den selv, men tillad mig alligevel at dele et par eksempler på den slags digte, den kan skrive. Udover kupletter kan funktionen skrive kompleks Shakespeare-dialog:
forbade conflate finance finance jubee!
hot carrot front-gate front-gate parrot plea
was where unpacked allot unpacked the snacked
the compact decent carrot carrot stacked
…mildt foruroligende limericks:
extract musketeer concentrate
aware contemplate laminate
a rat circumvent
dessert of lament
not carrot content here inflate
…jambiske oktametre (altså vers, der kan synges til melodien fra Gilbert & Sullivan’s Modern Major General Song):
demand enhance cannot of carrot steer if true delayed portrayed
jubee! conflate descent instate subdue parade jubee! instate
…samt visdomsord på haiku:
aware and profound
contemplate quacked au contraire
carrot Budapest
Når jeg kigger igennem de forskellige vers, slår det mig, at min funktion lader til at have en voldsom forkærlighed for gulerødder!
Og hvad er så formålet med hele dette projekt? Ingenting – eller i hvert fald er der intet videnskabeligt formål. Men jeg er vild med at lege med sprog, og det har været en fornøjelse for mig at lære en computer at løse enkle ‘sproggåder’ på denne måde. I reel forskning er der mange lingvister, der bruger computerprogrammering på andre måder – for eksempel til at analysere store mængder af data, eller til at genkende talesprog. Hvis f.eks. din telefon kan aktiveres med stemmekommandoer, er det computerlingvisters indsats, der har lært den dét.
Det fascinerer mig også, hvordan vi mennesker kan reagere på disse digte. Ifølge det engelske sprogs regler, som vi kender dem, er det tydeligt, at der ikke er nogen betydning i disse digte. Men menneskehjernen er vild med mønstre og mening, og har det med at se begge dele selv de steder, hvor de ikke findes. En af mine venner, som fik genereret haiku’et: “young frequent enough, counteract robot contract, millionaire this clicked”, fortolkede det som en fortælling om en robots rejse gennem arbejdsmarkedet. Det er selvfølgelig ikke et fænomen, som min funktion er ansvarlig for, men det er noget, som disse nonsensvers har det med at aktivere i menneskehjernen, og jeg finder det voldsomt interessant!
Der er også professionelle programmører, som har lavet endnu sejere udgaver af den slags program, som jeg har givet mig ud i her. For eksempel findes der Hafez, som blev programmeret i 2016 (Ghazvininejad et al). Hafez kan skrive digte om emner, som brugeren selv vælger, og disse digte passer ikke blot ind i poetiske metre (ligesom min funktions) – de er også syntaktisk sammenhængende! Dette er blot ét eksempel på, hvordan vi bliver bedre og bedre til at lære computere at imitere sprog, inklusive sprog’lege’ såsom poesi. Jeg tror, at computerkodning er noget, som enhver lingvist ville drage fordel af at have et grundlæggende kendskab til – hvis ikke af praktiske årsager, så blot for at opleve endnu en vinkel at beskue sprog fra.
REFERENCELISTE:
Ghazvininejad, Marjan, Xing Shi, Yejin Choi & Kevin Knight. 2016. Generating Topical Poetry. In Proceedings of the 2016 Conference on Empirical Methods in Natural Language Processing, Pp. 1183–1191
Gustav Styrbjørn Johannessen er kandidatstuderende på Lingvistik på Aarhus Universitet. Med
både dette projekt og sin deltagen i Lingoslam 2022 har det forgange semester vist sig særdeles
poetisk for ham – ikke at det er noget at klage over! Professionelt har Gustav til funktion at vise
den bredere befolkning, hvor mange spændende ting der er at lære om sprog og lingvistik.
Sikke dog et ovenud fantastisk og brugbart stykke kode du dér har fabrikeret. Stor applaus
Tusind tak!