K-opgave E2001 - Konkordans. Mikkel Boje, Ulrik Schou Jørgensen, Martin Damhus



Relaterede dokumenter
Lagervisning. Dina Friis, og Niels Boldt,

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

Moduler i Standard ML

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

VisiRegn: En e-bro mellem regning og algebra

Indledning. MIO er optimeret til Internet Explorer. Læs endvidere under Ofte stillede spørgsmål.

Divide-and-Conquer algoritmer

ALMINDELIGT ANVENDTE FUNKTIONER

Manual til hjemmeside i Typo3

Løsning af simple Ligninger

Afstande, skæringer og vinkler i rummet

Velkommen til REX onlinehjælp

Skriftlig Eksamen Algoritmer og Datastrukturer (DM507)

Vejledning PROPHIX 11. Driftsbudgettering ved åbning af templates (Kun til Avanceret-brugere)

DM507 Algoritmer og datastrukturer

Bogfunktionen eller Slægtsbogen i FTM

Datastrukturer (recap)

DM507 Algoritmer og datastrukturer

Daglig brug af JitBesked 2.0

DM507 Algoritmer og datastrukturer

Easy Guide i GallupPC

Typografisk formatering i forskellige tekstbehandlingssystemer: Word, OpenOffice og WordPerfect. Foreløbig udgave.

Sproget Six. Til brug i rapportopgaven på kurset Oversættere. Vinter Abstract

Datastrukturer (recap)

Divide-and-Conquer algoritmer

IDAP manual Emission

DM507 Algoritmer og datastrukturer

7DVWHYHMOHGQLQJ#²#,QWHUQHW#([SORUHU

Mini-guide for opdatering af hjemmesiden for. SOIF

Afsnittet er temmelig teoretisk. Er du mere til det praktiske, går du blot til det næste afsnit.

Divide-and-Conquer algoritmer

ActiveBuilder Brugermanual

Hjemmesiden er opdelt i et sidehoved, en sidefod og mellem disse 3 kolonner: venstre, midterste og højre. Højre kolonne vises dog kun på forsiden.

Rekursion C#-version

Elementær Matematik. Mængder og udsagn

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

SÅDAN BRUGER DU

Afstande, skæringer og vinkler i rummet

Carsten hjælp. Carsten 4.0. Mikro Værkstedet A/S

Sådan indlægges nyheder på DSqF s hjemmeside trin for trin

Administration af subsites BRUGERVEJLEDNING FOR ADMINISTRATOREN

Divide-and-Conquer algoritmer

Danmarks Tekniske Universitet

Programmering C RTG

How to do in rows and columns 8

Hvordan søger du i LARM.fm?

Edb-tekstbehandling, præsentation mm

Tietgenskolen - Nørrehus. Data warehouse. Database for udviklere. Thor Harloff Lynggaard DM08125

DaTelTek ApS ich 4 SpAPI Telenor Serviceprovider API

Andengradsligninger. Frank Nasser. 12. april 2011

Typografi og layout i Word 2010

Lav dine egne hjemmesider/websider

App til indmelding af glemt check ud

G-MAIL (GOOGLE)

DM507 Algoritmer og datastrukturer

DM507 Algoritmer og datastrukturer

Effektiv søgning på web-steder

Periodiske kædebrøker eller talspektre en introduktion til programmet periodisktalspektrum

Finanstilsynets indberetningssystem. Vejledning til Regnearksskabelonerne

Skabelonfilen er udarbejdet i Word til Windows (Office 2010) og er også afprøvet i Word til Mac.

Brugervejledning om søgning, der blev idriftsat sommer 2009

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

At indsætte ord og billeder og brug af hjælpefunktionen.

22 Hobe. Noter. PS1 -- Hobe. Binære hobe. Minimum-hob og maximum-hob. Den abstrakte datatype minimum-hob. Opbygning af hobe. Operationen siv-ned.

Abonnementsstyring. Start af Stellar Abonnement. Indledende tekst. Indholdsfortegnelse

Klasse 1.4 Michael Jokil

It-sikkerhedstekst ST8

Abstrakte datatyper C#-version

DM507 Algoritmer og datastrukturer

18 Multivejstræer og B-træer.

Velkommen til 3. omgang af IT for let øvede

Skriftlig Eksamen Algoritmer og Datastrukturer (dads)

Grundlæggende køretidsanalyse af algoritmer

TAGISOLERING BRUGERVEJLEDNING (VERSION 0.9.2)

Quick Guide til MM Omstilling

FAQ Frequently Asked Questions

Grådige algoritmer. Et generelt algoritme-konstruktionsprincip ( paradigme ) for optimeringsproblemer.

Dokumentering af umbraco artikeleksport:

Søgeformularen i UVvej

Algoritmeskabeloner: Sweep- og søgealgoritmer C#-version

Indhold. 1. Adgang og afslutning

Brugervejledning til Design Manager Version 1.02

LaTeX på et øjeblik Kristian Knudsen Olesen

Vejledning for metadatabasen

Kapitel 3 Betinget logik i C#

Ide med Diff. Mål. Tidsplan. 1.uge: 2.uge:

Guide til Umbraco CMS

Sortering. Eksempel: De n tal i sorteret orden

Samspillet mellem databaser og kort styres af GeoCAD programmet GeoDB.

Listen over reserverede ord er meget lang, men de væsentligste vil jeg beskrive her i denne artikel:

e-konto manual e-konto manual Side 1

Vejledning til opbygning af hjemmesider

Pralemappen.dk Din online portfolio Brugerhåndbog til elever Brugerhåndbog til elever

Kursusmappen Kommuniker: På Tryk 2 (med ordforslag fra CD-ORD)

Sortering. Eksempel: De n tal i sorteret orden

Word-5: Tabeller og hængende indrykning

Transkript:

K-opgave E2001 - Konkordans Mikkel Boje, Ulrik Schou Jørgensen, Martin Damhus 20. december 2001

Indhold 1 Sammenfatning 5 1.1 Denne opgave.................................. 5 1.2 Ambitionsniveau................................ 5 1.3 Krav til læseren................................. 5 2 Problemorienteret analyse 6 2.1 Selve hjemmesiden............................... 6 2.2 Konkordans-opbygningen............................ 6 2.2.1 Entydighed af internetadresser..................... 6 2.2.2 Indeksering af ikke-html-dokument-filer?.............. 7 2.2.3 Det foranderlige internet........................ 7 2.2.4 Statistikker og oplysninger til brugeren................ 7 2.3 Søgningsformer................................. 8 2.4 Søgeords beskaffenhed - krav til inddata................... 8 2.4.1 Hvad er et ord?............................. 8 2.4.2 Specialtegn............................... 9 2.4.3 Blokbogstaver.............................. 9 2.4.4 Å i forhold til dobbelt-a et....................... 9 2.4.5 Almindelige ord............................. 10 2.5 Krav til uddata................................. 10 2.5.1 Søgeordet i sin kontekst - rent visuelt................. 10 2.5.2 Hvad er en kontekst?.......................... 10 3 Programmeringsovervejelser 12 3.1 Internetsiden.................................. 12 3.2 Typen af data lagret i konkordansen..................... 12 3.3 Rensning af HTML-kilden.......................... 13 3.3.1 Fjernelse af HTML-mærker og Javascript............... 13 3.3.2 CSS................................... 13 3.3.3 Framesets................................ 13 3.3.4 Import af eksterne fejl......................... 13 3.3.5 Antal gennemløb ift. køretid...................... 14 3.4 Fra HTML-kilde til intern repræsentation................... 14 2

3.4.1 Funktionsværdier af Src.getInternetpage............... 14 3.4.2 Æ, ø og å................................ 15 3.5 Repræsentationen af HTML-kilden i konkordansen.............. 15 3.5.1 Forkortelser............................... 16 3.5.2 Hvad er et ord?............................. 16 3.5.3 Hvad er et tegn?............................ 16 3.5.4 To forslag til en repræsentation.................... 17 3.5.5 Valg af repræsentation......................... 18 3.6 Søgning..................................... 18 3.6.1 Søgetræet - fordele og ulemper..................... 18 3.6.2 Sortering................................. 19 3.6.3 Opbygning af konkordans = indsættelse............... 19 3.6.4 Balancering og søgning......................... 20 3.7 Eksklusion af ord................................ 20 3.8 Uddata ved søgning............................... 20 3.8.1 Definition af kontekst.......................... 20 3.8.2 Prioritering, sortering, eller........................ 21 3.9 Programgennemløb............................... 21 4 Programbeskrivelse 23 4.1 Programmel og programudvikling....................... 23 4.1.1 Moscow ML 2.00............................ 23 4.1.2 Udviklingsmiljø............................. 23 4.2 Navngivning................................... 24 4.3 Funktionstyper................................. 24 4.4 Msp....................................... 24 4.5 Programmets grundstruktur.......................... 24 4.6 Beskrivelse af moduler og funktioner..................... 26 4.6.1 Modulet Conc.............................. 26 4.6.2 Funktoren SetTree........................... 28 4.6.3 Modulet CheckWord.......................... 29 4.6.4 Modulet HtmlMan........................... 29 4.6.5 Modulet CreateSentence........................ 30 4.6.6 Modulet MultipleSearch........................ 31 5 Brugervejledning 32 5.1 Brugerens forudsætninger........................... 32 5.2 Sådan benyttes programmet.......................... 32 5.2.1 At åbne programmet.......................... 32 5.2.2 Opbygning af korkordans........................ 33 5.2.3 Søgning................................. 33 3

6 Afprøvning 34 6.1 Ekstern afprøvning............................... 34 6.2 Specifikation................................... 34 6.2.1 Programstart.............................. 34 6.2.2 Konkordans-opbygning......................... 34 6.2.3 Søgning i konkordansen......................... 35 6.3 Strategi for ekstern afprøvning......................... 35 6.4 Testdata og resultater............................. 35 6.4.1 Programstart.............................. 35 6.4.2 Opbygning af konkordans....................... 36 6.4.3 Søgning................................. 36 6.4.4 Testdata................................. 37 7 Konklusion, litteraturliste, bilag 38 7.1 Konklusion................................... 38 7.1.1 Videre programudvikling........................ 38 7.2 Litteratur.................................... 39 7.3 Bilag - kildetekst................................ 39 4

Kapitel 1 Sammenfatning 1.1 Denne opgave Denne rapport er en besvarelse af K-opgaven i datalogi 0GA, stillet efteråret 2001. Rapportens mål er at give en præcis indføring i det program, vi har udviklet med henblik på at løse den stillede opgave. Problemet, der skal løses, er i sin hovedsag en opbygning af konkordanser over specificerede internetsider. Ved en konkordans vil vi i denne sammenhæng forstå en mængde struktureret data, der for hvert ord, der måtte optræde på de pågældende hjemmesider knytter en liste indeholdende samtlige sammenhænge, dette ord måtte indgå i. Problemstillingen er altså af sorterings- og søgemæssig karakter. 1.2 Ambitionsniveau Vi tilsigter naturligvis effektivitet i det konstruerede program, men det klassiske problem med korrekthed og overskuelighed versus effektvitet vil naturligvis spille ind. Vi regner derfor med, at vi visse steder må gå på kompromis med mere ambitiøse løsninger, der ville højne effektiviteten og mindske køretiden, men samtidig drastisk formindske overblik og umiddelbare muligheder for at rette fejl. Vi mener ikke, at vi på denne måde vil blive nødsaget til at benytte os af naive løsninger i noget tilfælde, hvorfor effektivitet og køretid under alle omstændigheder vil blive nogenlunde tilfredsstillende. 1.3 Forudsætninger for læsning af opgaven Læsere af nærværende rapport forudsættes relativt bekendt med funktionsprogrammeringssproget MoscowML (v. 2.00) som er benyttet til løsning af den stillede opgave, samt et beskedent (men dog eksisterende) kendskab til HTML (eng. Hypertext Markup Language). Intet af dette er dog en forudsætning for at anvende det udviklede program, se brugervejledningen (afsnit 5.1). 5

Kapitel 2 Problemorienteret analyse I sin helt overordnede forstand er vores opgave at udarbejde en hjemmeside med 2 indbyggende funktioner: - lagring af information fra hjemmesider i en datastruktur (opbygning af konkordans for de relevante sider) - søgning i denne information Der er altså 2 hovedaspekter, dataallokering og færdsel i denne. 2.1 Selve hjemmesiden Selve hjemmesiden agter vi at fremstille i et grafisk enkelt design og med intuitiv brugerflade. 2.2 Konkordans-opbygningen Selve konkordansen har karakter af til rådighed stående information og er i sig selv en tilstand for systemet bestående af hjemmesiden og programmet. Tilstanden skal så ændres ved, at brugere ønsker at tilføje ny hjemmesider til konkordansen. Altså skal konkordansen have en struktur, der muliggør udvidelse. 2.2.1 Entydighed af internetadresser Endvidere ville det være fornuftigt for konkordansen at kunne genkende ens internetsider på deres adresse (indtastet i feltet på hjemmesiden) for at undgå dobbeltindeksering. For det første skal konkordansen altså på adressen kunne genkende, om netop denne adresse er blevet behandlet før. For det andet skal den undersøge, om det er en forklædt udgave af en adresse til samme side: opbygges eksempelvis først konkordans over 6

"http://www.etellerandet.dk" og dernæst over "http://etellerandet.dk", skal konkordansopbygningsfaciliteten helst genkende adresserne som pegende på samme hjemmeside. 2.2.2 Indeksering af ikke-html-dokument-filer? Generelt er det jo hjemmesider og ikke andre typer filer, der skal opbygges konkordans over. Dette er imidlertid meget svært at tage højde for. Det er derfor brugerens egen fejl, hvis han indtaster en URI pegende på en fil, og derved enten får opbygget konkordans over filens tekstindhold eller får som svar, at konkordansopbygning ikke var mulig (alt efter funktionen Src.getInternerpage s reaktionsmåde). Derfor skal programmet ved indtastning af en URI reagere således: 1) Er URI en gyldig? Hvis nej, gå til 2), ellers gå til 3) 2) Meddel brugeren, at URI en er ugyldig. 3) ER URI en allerede indekseret? Hvis ja, gå til 4) ellers gå til 5) 4) Meddel brugeren, at indeksering allerede er foretaget. 5) Normaliser URI, tilføj denne til liste over allerede indekserede sider, og opbyg konkordans over siden. 2.2.3 Det foranderlige internet Internettet er under stadig forandring og hjemmesider vil til stadighed ændre udseende og indhold. Derfor vil en opbygget konkordans over en hjemmeside ikke være brugbar på seenre tidspunkter. Dette er dog et irrelevant problem (så længe brugeren er opmærksom herpå), da konkordansen nulstilles ved programmets afslutning. 2.2.4 Statistikker og oplysninger til brugeren Vi kunne forestille os, at brugere af hjemmesiden kunne ønske sig informativ uddata efter en konkordansopbygning, eksempelvis en statistik omfattende parametre såsom antal tilføjede ord i konkordansen, antal forskellige ord i konkordansen, antal sider i konkordansen, antal udeladte ord, opbygningstid. Efter indtastning af adresse og et klik på Send, skulle disse oplysninger så vises på siden. Vi mener dog ikke, at uddata for konkordansopbygning behøver være mere omfattende end end meddelse om antal indekserede sider i alt. Det, brugeren hovedsageligt er interesseret i, er trods alt søgningen i konkordansen. 7

2.3 Søgningsformer Søgningsproblemet har en række aspekter tilknyttet. Søgning i konkordanserne udkrystalliserer sig i to deltilfælde, der udtømmer samtlige mulige søgninger: Søgning på eet ord samt søgning på flere ord. Dette giver anledning til følgende sorteringsmetoder: 1. Enkelt-ords-søgning: Her er der tale om indtastning af et enkelt ord, der så skal slås op i konkordansen. Ganske ligetil. 2. Forenet søgning: Her indtastes mere end et ord. Forenet søgning er da en søgning på de involverede ord, der frasorterer alt andet end fællesmængden af resultaterne - hermed menes de konkordansopslag, der indeholder samtlige ønskede ord. 3. Søgning på et eller flere af de ønskede ord: Her indtastes mere end et ord. Som titlen antyder vil en sådan søgning resultere i foreningsmængden af de resulterende konkordansopslag - altså samtlige konkordansopslag, der indeholder et eller flere af søgeordene. Hvilken af disse søgninger, vi agter at implementere, vil bero på et skøn (med mange involverede parametre) - og vil blive nærmere omtalt i programmeringsovervejelserne (afsnit 3.6.4). Det skal i parentes bemærkes, at nr. 3 på ovenstående liste kan genereres ved hjælp af multiple søgninger af formen 1 eller 2. Derfor vil vi i sidste ende formentligt tage stilling til, om vi ønsker at implementere metode 1 eller 2. En ekstra detalje ved søgning er søgning på en delmængde af den tegnfølge, et ord udgør. Dette vil vi omtale nærmere i programmeringsovervejelserne, se 3.6.1, men som udgangspunkt er det ikke noget, vi agter at implementere, da det vil skabe uforholdsmæssige omkostninger i forhold til søgemetoden: denne ville ikke længere blot kunne slå op i en eller andet leksikalt ordnet struktur, men måtte gennemlede hvert eneste ord for eventuel matchning. 2.4 Søgeords beskaffenhed - krav til inddata 2.4.1 Hvad er et ord? I forbindelse med søgning skal vi have en formel definition af et ord slået fast. Vi vil her definere et ord - hvilket i hvert fald er den definition en bruger af programmet vil benytte sig af ved indtastningen - ved, at et ord er det, der til begge sider afgrænses af et blanktegn. Denne definition vil ikke være tilstrækkelig senere hen (internt i programmet) - detaljer herom senere. Et særligt problem i denne forbindelse er forkortelser, der jo netop kendetegnes ved rigeligt med punktummer. 8

2.4.2 Specialtegn En række krav til de indtastede søgeord skal specificeres. I forbindelse med specialtegn er vi eksempelvis nødt til bestemme deres funktion. Skal eksempelvis emailadressen di010539@diku.dk (af os) opfattes som adskillige ord separeret af nogle specialtegn (ikke-alfanumeriske) istf. mellemrum? I dette tilfælde er svaret klart nej, søger man på en emailadresse, ønsker man kun oplyst de sammenhænge, hvor emailadressen indgår i, og ikke samtlige sammenhænge, hvori fx. ordet diku indgår. Derfor må vi fastslå, at visse tegn - når vi går i gang med at programmere - ikke deler ord op. (Eksempelvis skal punktummer, kommaer og spørgsmålstegn adskilles fra ordene, på trods af at i fx. mere is? skrives is? ud i et). Vi har bestemt os for, at tegnene ^, _, @ er tegn, der kan og bør skrives uden orddelende effekt. Disse tegn vil vi altså opfatte som en slags bogstaver. 2.4.3 Blokbogstaver Et andet spørgsmål er små bogstaver ift. blokbogstaver. Er fx. F det samme som f? Der mener vi - med afsæt i den følgende begrundelse - at de fleste brugere vil finde det mest praktisk, at store og små udgaver af samme bogstav er ensbetydende. For det første skal der være mulighed for søgning på ord i begyndelsen af sætninger, disse starter rimeligvis med stort og må medtages såvel i denne som i andre sætningskontekster. For det andet forefindes muligheden for slåfejl, stavefejl og stavning af egenavne med småt, fejl der ikke bør hindre brugeren i adgang til det pågældende ord. 2.4.4 Å i forhold til dobbelt-a et Med det danske alfabet opstår et par konkrete særtilfælde: skal vi identificere et AA, Aa eller aa med Å? Eftersom vi nu har vedtaget at undlade skelnen mellem store og små bogstaver, stiller vi reelt kun eet spørgsmål, og vi har valgt at lade svaret være nej. Søger man på et ord indeholdende et å, ønsker man ikke resultater i stil med salsaaften, Haag eller andre ord indeholdende dobbelt-a er. Det samme gælder selvfølgelig omvendt. Vi vurderer, at tabet ved denne vedtagelse (fx. at Aalborg ikke vil blive fundet af søgning på Ålborg ) er mindre end gevinsten. De forskellige stavemåder af det samme ord er reelt set et ekko af et mere generelt problem, som ville være meget ressourcekrævende at løse tilfredsstillende: Eksempelvis forskellig stavning af ord på hhv. engelsk og amerikansk. At skulle indbygge en mekanisme til oversættelse af disse ensbetydende, forskelligt stavede ord, ville være nærmest umuligt. Det er et problem vi derfor må give videre til brugeren, der her må søge fx. på både Fåborg og Faaborg for at få samtlige sammmehænge listet - eller fx. både color og colour (amerikansk og engelsk). 9

2.4.5 Almindelige ord Eftersom vi skal konstruere en mekanisme til effektiv sortering af data og opbygning af fornuftige datastrukturer til søgning i, forekommer det fornuftigt at specificere, hvilke ord, vi overhovedet vil medtage i en konkordans over en side. Sjældent - for ikke at sige aldrig - vil en bruger ønske at søge på de helt almindelige ord, der er nødvendige for sætningskonstruktion. Vi tænker her på visse biord og artiklerne en og et. Det virker rimeligt at udarbejde præcise krav til et givent ord, der kan afgøre, om ordet skal medtages i konkordansen eller ej. Hvorledes skulle disse krav så være udformet? Man kunne slette samtlige ord af længde (antal tegn) 2 eller mindre. Herved ville væsentlige ord som ål, si og ag dog desværre gå tabt. Meningen var jo at fjerne de ubetydelige, sætningssammenbindende ord. Som en anden løsning kunne man fabrikere en oversigt over samtlige ord, man ikke ønskede medtaget. Denne ville vel i sin enkleste udformning ikke bestå af meget mere end 20-30 ord. Ved at frasortere ord fra denne liste i konkordansopbygningsfasen, ville meget spares, da de aller-hyppigste ord som de, er og og udgør en meget stor del af enhver (dansk) tekst. Denne liste ville naturligvis blive national, og skulle derfor have mulighed for opdatering samt tilføjelse af andre sprog. Som udgangspunkt vil vi nok kun opregne de almindeligste ord fra dansk og engelsk, da danske brugere formentligt hovedsageligt vil søge på danske eller engelske hjemmesider. 2.5 Krav til uddata Vi bør have nogle regler for uddatas udseende, herunder en klar definition af, hvad der forstås ved en sammenhæng. Et søgeord skal jo præsenteres i sin kontekst. 2.5.1 Søgeordet i sin kontekst - rent visuelt Vi vil lade søgeordet optræde i sin kontekst, ikke erstattet af et symbol. Det mener vi vil give det klareste og mest læsbare indtryk af de ønskede sammenhænge. For at øge overskueligheden, vil vi markere søgeordet med fed samt lade 3 punktummer i starten og slutningen antyde, at vi befinder os i en beskåret kontekst - omfattende flere ord end vist. 2.5.2 Hvad er en kontekst? Den kontekst, et søgeord skal præsenteres i, er langtfra entydigt givet. Det er klart, at ordet skal ledsages af et antal ord foran samt et antal ord bagefter. Ofte vil den enkle definition af en sammenhæng søgeordets n foregående ord + søgeordet + søgeordets efterfølgende n ord give et nogenlunde tilfredsstillende resultat. Man kan dog let risikere, at der vil blive skåret midt igennem sætninger. Man kunne forestille sig uddata i stil med (søgeord markeret med fed): 10

... nede. Han kiggede mod himlen. Søren var træt af alle disse... der ikke er særlig sigende om sammenhængen. En informativ sammenhæng skulle altså muligvis være mere orienteret i retning af at udlevere de sætninger, hvori søgeordet indgår. Skulle man lade en sammenhæng være defineret ved en sætning? Dette ville have den fordel, at man på forhånd ville kunne dele en tekst op i disjunkte sammenhænge, hvorefter hvert søgeords sammenhæng var givet ved dens tilhørsforhold til disse delmængder (hvis forening ville udtømme den oprindelige tekst) af den oprindelige streng. Desværre er dette heller ikke nogen udelukkende god idé. Sætninger er af meget varierende længde og indhold, så man kunne risikere alt for korte sammenhænge, men også ikke-sluttende, hvis man fx. søgte i en lyrisk tekst uden normal tegnsætning (idet vi her lader en sætning være defineret som en sekvens af ord, startende og sluttende med punktum, spørgsmålstegn eller udråbstegn). For at denne idé skal levere fornuftige sammenhænge, skal en eller anden kontrolinstans finpudse sammenhængen: beskære den passende hvis den er for lang, udvide den hvis den er for kort og fjerne irriationsmomenter i enderne såsom uinformative brudflager af sætninger, fx. skulle eksemplet ovenfor renoveres til... Han kiggede mod himlen. Søren var træt af alle disse mågers flyven rundt.... Vi vil tage stilling til problemet i afsnit 3.8.1. 11

Kapitel 3 Programmeringsovervejelser Afgørende for programmeringen er det, at programmet udvikles robust. Der er reelt kun een anledning til, at ønsket om konkordansopbygning må affejes med en fejlmeddelse, nemlig det, hvor brugeren har specificeret en fejlbehæftet adresse / URI. I dette tilfælde skal brugeren informeres grundigt herom, samt at konkordansopbygningen måtte stoppes. I alle andre tilfælde skal programmet terminere med en konkordansopbygning, hvorfor enhver situation må tages i betragtning og enhver undtagelse gribes. 3.1 Internetsiden Internetsiden skal besvare søgninger, der udmunder i et eller flere søgningsresultater, skal have ved hvert søgeresultat have en hyperreference (eng. link) til den side, hvorpå konteksten er fundet.. 3.2 Typen af data lagret i konkordansen Vi kan med rimelighed sige, at en enkelt oplysning af typen (søgeord,sammenhæng) i ML må være af typen string * string. Skal der til samme søgeord knyttes en hel række sammenhænge, må typen blive string * string list - men det går heller ikke. For hver sammenhæng, vi angiver, skal det også specificeres, fra hvilken af de indekserede sider, sammenhængen er hentet. Så en komplet oversigt for eet ord i konkordansen må altså have formen (søgeord, (adresse, sammenhæng) - liste), hvoraf typen bliver string * (string * string) list. Konkordansens samlede lagrede data skal altså være en samling informationer af denne type. Selve konkordansen skal dog også indeholde information om hvilke sider, der allerede er opbygget konkordans over. Derfor skal vi til den struktur, der sammenknytter string * (string * string) list -informationen tilnkytte en liste over hvilke sider, der er blevet indekseret. I opbygningsfasen skal det tjekkes, om siden er indekseret inden opbygning går i gang. 12

3.3 Rensning af HTML-kilden 3.3.1 Fjernelse af HTML-mærker og Javascript Funktionen Src.getInternetpage, præprogrammeret, vil for en specificeret URI returnere en streng, indeholdende kildeteksten. Modulet Src benytter Unix-programmet Lynx til at modtage kildekoden for HTML-dokumentet (altså skal Lynx være installeret, før vores program virker). Lynx kan rejse undtagelser som skal gribes. Strengen fra Src.getInternetpage vil indeholde HTML-mærker. Indholdet af disse skal naturligvis ikke medtages i konkordansen. Derfor skal HTML-kilden renses for mærker, inden vi kan opbygge konkordansen. Eftersom alle HTML-mærker har udseendet <... > eller <...>... <..>, reduceres denne renselsesproces til at fjerne alt mellem begyndelses- og sluttegnene < og >. Javascript på hjemmesider har i kildekoden formatet <script... </script> 1. Derfor vil sletning af al tekst mellem HTML-mærkerne også fjerne Javascript. 3.3.2 CSS Et problem hermed bliver de såkaldte CSS (eng. cascade styling sheet) - en udvidelse af de simple HTML-mærker - et problem. De har nemlig formen <style>... kode... </style>. Altså står tekst, der skjules af netfremvisere, mellem mærkerne. Derfor vil vi med denne metode i konkordansen blotte kode fra sider med CSS. Vi vurderer dette problems omfang som værende lille i forhold til den enklere implementation, der ikke tager højde for dette. 3.3.3 Framesets Vi vil med denne fremgangsmåde ikke få medtaget tekstindhold af framesets, der har formen <FRAMESET> <FRAME SRC = filnavn > </FRAMESET>, hvorved et tekstindhold hentes ind fra en fil (det er ikke repræsenteret i kildekoden). Dette problem har vi ikke mulighed for at løse. 3.3.4 Import af eksterne fejl Vi vil tillade os at antage, at de hjemmesider, der bygges konkordans over, er perfekte eller fejlfri. Dette skal forstås derhen, at fejl i kildeteksten til siden vil skabe problemer for vores programmering, eksempelvis hvis et HTML-mærke (eng. tag) ikke afsluttes. Som anført ovenfor vil vi jo benytte os af, at HTML-kilden er opbygget af brødtekst og så kommandoer indkapslet i mærker - så kan teksten renses for HTML ved simpelt hen at 1 Hvilket i øvrigt oprindeligt var tilpasset HTML-formatets start- og slutmærker: således kunne ældre netfremvisningsprogrammer stadigvæk fremvise siderne, de kunne blot se bort fra scriptet indkapslet i mærkerne. 13

fjerne al tekst mellem mærkernes start og slut. Vi kan naturligvis heller ikke tage højde for andre detaljer af denne art - andre fejl i koden, stavefejl i al almindelighed, etc. etc. 3.3.5 Antal gennemløb ift. køretid Kaldet af funktionen Src.getInternetpage giver en streng indeholdende kildeteksten for en hjemmeside. Der skal ske adskillige ting med denne streng: 1. Fjernelse af HTML-mærker, Javascript samt uønskede tegn produceret af Src.getInternetpage (se 3.4.1). 2. Omsætning af strengen til intern repræsentation af HTML-kildens brødtekst (som vi kalder concsrc). 3. Indsættelse af denne repræsentation i vores konkordans-struktur. Det ville være uhensigtsmæssigt at lade strengen gennemløbes 3 gange, hvis flere af de ovennævnte operationer kan udføres simultant. De operationer, der skal udføres, kræver nemlig, at hvert tegn i teksten undersøges, fjernes hvis det er i et HTML-mærke, og ellers bliver returneret uskadet. Derfor vil vi formentligt satse på iterative funktioner (erstatte eventuelle naive implementeringsforslag hermed). 3.4 Fra HTML-kilde til intern repræsentation Uanset udseendet af den interne repræsentation af HTML-kildekoden, ønsker vi at definere en type for repræsentationen og benævne denne type concsrc (eng. conc Source). 3.4.1 Funktionsværdier af Src.getInternetpage Den indre repræsentation af HTML-kilden er en eller anden inkarnation af resultatet af kaldet af funktionen Src.getInternetpage, der som funktionsværdi giver en streng eller kaster en undtagelse, hvis en specificeret URI ikke peger på nogen eksisterende hjemmeside. Src.getInternetpage giver strenge med indhold af HTML-mærker og Javascript, der skal fjernes efter recepten angivet i 3.3.1, samt CSS, som vi som omtalt ikke vil forsøge at fjerne. Endvidere produceres tegnene \n, \r, \t. Disse har noget at gøre med udseendet af kildekoden, som vi er fuldstændigt ligeglade med. Derfor skal disse tegn fjernes. Linieskift i kildekoden "\n" (opfattes som et enkelt tegn) betyder i ML-sammenhæng linieskift, og returneres af den forprogrammerede getinternetpage når der i kildekoden for den pågældende hjemmeside er foretaget et linieskift. Disse liniekift ønsker vi dog ikke at beholde, hvorfor concsrc ikke skal kunne mærke linieskift. \n skal altså fjernes. En total fjernelse kan dog 14

have uheldige konsekvenser. Eksempelvis kunne et linieskift være det eneste, der adskilte to ord (forekommer hyppigt i fx. brug af overskrifter), og disse to ord ville da blive koblet sammen til et: "Tryksager en miljøtrussel\nsundhedsministeriet advarer om.." Da ville søgning på miljøtrussel ikke give noget resultat, mens søgning på miljøtrusselsundhedsministeriet ville give resultater. Vi vil derfor erstatte tegnet \n med et punktum - den grafisk mest tilfredsstillende løsning (selvom vi muligvis (sjældent) vil komme til at sætte punktummer midt i sætninger). Tabulation og retur-markører "\t" betyder tabulator, altså at der i kildekoden for den pågældende side er benyttet indrykning af en vis, bestemt længde. Dette er heller ikke noget, vi ønsker gemt i concsrc, så \t skal altså fjernes. Tabulator er meget sjældnere anvendt end linjeskift. Endvidere er situationer med ord, kun adskilt af tabulation - i hvert fald ifølge vores undersøgelser - fåtallige, så vi har i denne situation, såvel som i tilfældet for "\r" (tast på retur ) valgt at lade tegnet udgå, snarere end at erstatte det med noget andet (punktum, blanktegn, etc.) [2, s. 347]. 3.4.2 Æ, ø og å Æ, ø og å repræsenteres ikke entydigt i Src.getInternetpage s funktionsværdi. Disse danske specialtegn repræsenteres nemlig ikke entydigt i HTML: 1. Æ repræsenteres som "Æ"eller "æ" 2. Ø repræsenteres som "Ø"eller "ø" 3. Å repræsenteres som "Å"eller "å" Derfor skal en funktion stå for at oprette en entydig repræsentation af æ, ø og å i concsrc. Dette er, hvad der skal gøres ved Src.getInternetpages funktionsværdi, inden den videre behandling af kildeteksten kan begynde. 3.5 Repræsentationen af HTML-kilden i konkordansen Hvorledes skal vi konstruere den interne repræsentation af en konkordans? En konkordans rummer meget information - er meget datatung. For et givet antal sider, skal konkordansen indeholde information om samtlige vigtige ord. Derfor skal strukturen indeholde sorteret information, der muliggør effektiv søgning. Inden vi beskæftiger os med selve repræsentationen af HTML-kilden i vores i program, skal nogle indledende spørgsmål afklares. 15

3.5.1 Forkortelser Forkortelser (herunder de, der er formaliseret til dagligsprog eller egentlig dansk retstavning - som fx. "NATO","cd","etc.") er problematiske på to måder: 1. Punktummer. Hvorledes skelnes forkortelser med afsluttende punktum fra et ord placeret til sidst i en sætning? Hvis a er en tegnfølge - afsluttet med punktum - da er a et egentligt ord, hvis det efterfølgende ord begynder med stort - medmindre a er en forkortelse efterfulgt af en ny sætning eller et egennavn. Det er altså ikke let at afgøre, hvornår et ord er en forkortelse. Samtidig er det livsvigtigt for vores søgning, at eventuelle punktummer i slutningen af et ikke-forkortelse -ord fjernes. 2. Flertydighed. De fleste forkortelser indeholder punktummer, og disse har ofte en flertydig stavningsmåde (fx. "bla."og "bl.a."). Dette kan vi - ligesom ved ord med flere stavningsmåder - ikke tage højde for. Vi har valgt at lade forkortelsesproblematikken høre en under den klasse af meget specielle problemer, som vi af hensyn til simplere kodning og hurtigere søgning har undladt at beskæftige os med. Se 7.1.1. 3.5.2 Hvad er et ord? Mens et "ord"for brugeren som omtalt i (afsnit) vil være det, der er omgivet af blanktegn, vil vi til brug i kodningen sætte et ord til at være Et ord er en tekststreng, der kun indeholder lovlige tegn. De lovlige tegn er tal, store og små bogstaver (inklusive æ,ø og å) samt specialtegnene ^, @, _. Denne definition sikrer os, at vi kan fjerne alle andre specialtegn fra ordene i HTMLkilden uden at samle ord, hvor det ikke er meningen. Undtagelserne herfra vil være, at vi kommer til at samle forkortelser ved interne punktummer (fx. vil "p.t." blive til ordet "pt") og vi vil risikere sammensmeltning af halvdele i ord med interne bindestreger (fx. "Maj-Britt"). Til gengæld sikrer vi os mod den almindeligste anvendelse af bindestregen, nemlig til orddeling (hvis ordet "pølse-vogn" er delt med en bindestreg, vil vores fjernelse af specialtegnet "-" normalisere ordet til "pølsevogn"). 3.5.3 Hvad er et tegn? Et specialtegn vil vi definere som alle tegn, der opdeler ord (bortset fra blanktegnet, hvis rolle er helt speciel), dvs. alle tegn, der ikke er omtalt ovenfor. 16

3.5.4 To forslag til en repræsentation Strengen fra Src.getInternetpage skal nu omdannes til sin indre repræsentation. Vi har været i tvivl om, hvordan typen på concsrc skulle defineres. Vi kom frem til to mulige repræsentationer, med hver deres formelle definition af, hvad et ord egentlig er. Her følger definitionen på de to bud: Def. af ord Det, der ikke indeholder blank- eller specialtegn. 1. bud Liste af par bestående af strenge og sandhedsværdier. Strengen indeholder enten et ord eller et specialtegn. Sandhedsværdien indikerer om strengen er et ord (true) eller et tegn (false). Et ord kan ikke indeholde tegn pånær æ er, ø er og å er samt de i afsnit 2.4.2 specificerede. Endvidere kan ord indeholde tegnet @, der jo indgår i emailadresser. Def. af ord Umiddelbart: Det, der afgrænses af blanktegn. Reelt: Det, der er renses for specialtegn. 2. bud Liste af strenge. Strengene består af ord, som kan indeholde tegn selvom ordene ikke er danske eller forkortelser. Ord skabes ved at opdele det fra getinternetpage indkommende data ved hvert mellemrum. Der er fordele og ulemper ved begge forslag. Liste af par af strenge og sandhedsværdier Strengene skal undersøges fra en ende af: Indeholder de specialtegn? I så fald skal de fjernes, hvilket komplicerer den funktion vi skal skabe, der genererer concsrc udfra HTML. Den funktion, der for hvert ord skal samle en kontekst, bliver også indviklet: Den skal generere sætninger udfra tupler af ord og tegn, og somme tider skal den indsætte mellemrum og somme tider ikke, fx. vil parrene [("mine",true),("venner",true),("\&",false),("jeg",true),(":",false), ("tre",true),("datalogistuderende",true)] skulle give sætningen "mine venner & jeg: tre datalogistuderende" Som vi ser, skal "&" og ":" forsynes med et forskelligt antal foranstillede blanktegn. En kontekst-fremstillende funktion ville derfor skulle undersøge hvert specialtegns blanktegnskarakteristika. Til gengæld ville den funktion, der skal afgøre, om et ord skal indsættes i konkordansen eller ej, få det let: den skal blot indsætte, hvis ordet har fået tildelt sandhedsværdien true og ikke er indeholdt i en oversigt over forbudte ord. 17

Liste af strenge Den liste af strenge, der ville fremkomme vel at opdele den indkommende kildetekst ved hvert blanktegn, ville indeholde ord påklistret specialtegn: "mine venner & jeg: tre datalogistuderende" ville blive til ["mine","venner","&","jeg:","tre","datalogistuderende"] hvor ordet "jeg" har et påklistret ":". Derfor ville denne repræsentation aftvinge en funktion, der ved indsættelse af ordene i konkordansen rensede ordene for specialtegn (og det efter besværlige regler - fx. vil rensningerne af ordene "Lykkeligt.", "...til", "deres!", "dages-ende..." forløbe meget forskelligartet for at være korrekt). Til gengæld ville den funktion, der skulle generere kontekster for hvert søgeord få let spil: den skulle så bare tage ordene i listen og sætte sammen med et mellemrum imellem. 3.5.5 Valg af repræsentation Vi vil benytte os af første bud på en repræsentation af concsrc. Som definition på, hvad der skal forsynes med fortegnet true, vil vi benytte ovenstående definition af et ord. Tegn forsynes således med false. Valget er begrundet med, at vores funktion til indsættelse af ord i konkordansen bliver meget enkel: Den skal ikke løbe ordet igennem og tjekke for specialtegn, blot tjekke fortegn. Specialtegn og foranstillede blanktegn Specialtegn kan deles op i to klasser af modsat paritet: dem der har et foranstillet blanktegn (fx. "&"), og dem der ikke har (fx. ".") Den funktion til generering af kontekster, vi vil programmere, vil således sætte blanktegn alt efter hvilken kategori et blanktegn tilhører. Kun et problem opstår herved: specialtegnet "(" samt diverse møntfodssymboler(som fx. "$"), kræver - som de eneste specialtegn, vi har opdaget - foranstillet blanktegn, men skal derefter hæftes umiddelbart på det efterfølgende ord. Dette problem er for specifikt til, at vi vil gøre noget ved det, og vi har ignoreret problemet. Altså vil alle start-parenteser og møntfods-tegn få et blanktegn bagpå ("(dumt)" bliver til "( dumt)", "$200" vil blive til "$ 200"). 3.6 Søgning 3.6.1 Søgetræet - fordele og ulemper Vi skal have opbevaret en endelig (men betragtelig) mængde data. Dataen skal være indlejret i en datastruktur, der effektiviserer søgning, hvorfor vi har valgt at opbygge konkordansen som et søgetræ. 18

Søgetræer er ekstremt effektive at søge i; til gengæld er det ressourcekrævende at konstruere dem. For at søgetræet skal være effektivt er det nødvendigt, at det er balanceret. Hvis et træ er balanceret er det muligt kun ved maks 20 skridt at finde frem til 10 6 forskellige elementer [1, s. 144] - generelt kan med n skridt nås 2 n forskellige elementer. Et søgetræ er balanceret, hvis hver knudes undertræer har lige mange elementer [1, s. 143]. I vores tilfælde vil vi lade knuderne være information af typen string * (string * string) list Disse knuder vil så indlysende nok blive sorteret i træet efter søgeordet i front. Eftersom vi vil bane os vej ned gennem træet vha. streng-sammenligninger, vil søgning på delmængder af ord ikke være mulig, for søgning på tegnfølgen "bso" vil lede os ned gennem søgetræet til ord startende med "b", og ikke finde ordet "absolut", som indeholder den ønskede tegnfølge. Hvilke kriterier skal denne sortering benytte? 3.6.2 Sortering Mankunne overveje at sortere ordene efter aftagende længde, da mylderet af småord ville havne i bunden af træet og dermed ville være vanskeligst at nå frem til - i harmoni med, at det oftest er længere og mere komplicerede ord man søger efter. Denne metode ville dog kræve, at ord af samme længde var alfabetisk ordnet. Dermed skulle vi for hvert ord gennemløbe det for at finde dets alfanumeriske karakteristika og længde. Eftersom vi alligevel gennemløber ordet, er det fristende at sortere alfabetisk. Dette har en klar fordel - overskuelighed. En ide til optimering alfabetisk ordning kunne være at tilknytte et tal til hvert ord, svarende til det første bogstavs placering i alfabetet. Dermed ville søgningen ikke skulle sammenligne strenge hele vejen ned gennem træet, først når det korrekte tal var nået. Men i og med, at søgetræers struktur muliggør ekstremt effektiv søgning, vil næsten ingen sammenligningskriterier have indflydelse på effektiviteten. Det er opbygningstiden for et søgetræ, det gælder om at beskære (herunder tilknytningen af disse talværdier, der ville skulle undersøge ordet ved konkordansopbygningen) - og ikke søgetiden. Vi har derfor valgt at undlade implementeringen af denne idé (selvom man kunne forestille sig situationer, hvor alt handlede om reduktion af søgetiden). 3.6.3 Opbygning af konkordans = indsættelse Med den valgte datastruktur - søgetræet - reduceres opbygningen af konkordansen til indsættelse af data i et søgetræ. Selve søgetræet vil - som ellers - have data i knuderne og slutte i bladene. Indsættelse af data heri er altså en spørgsmål om omskrivning af de allerede eksisterende funktioner til indsættelse i et søgetræ. 19

3.6.4 Balancering og søgning Balancering af søgetræer kan foregå på to måder: 1. Løbende balancering - hertil skal benyttes balancerende træalgoritmer. (Et sådan selv-balancerende binært søgetræ er blevet udviklet af Adams (1993) [1, s. 154]). 2. Indsættelse af alle elementer, derefter balancering (træet balanceres altså, når der skal søges i det, ikke i opbygningsfasen) Et af problemerne ved at balancere søgetræet efter metode 2 er, at man skal vide, hvornår det (tidsmæssigt) er effektivt at balancere søgetræet - overvejelser en bruger skal en bruger i vores konkrete tilfælde naturligvis ikke involveres i. For os har det været logisk at lade tidspunktet for afbalancering af træet være efter endt tilføjelse af en side til konkordansen. Vi mplementerer altså ingen selv-afbalancerende træer. Man kan balancere et søgetræ ved først at konvertere træet til en liste af elementer og derefter konstruere et nyt træ [1, s. 153]. Da søgetræets elementer er midterpositioneret, skal øverste element i træet være placeret midt i listen. Da vores sorteringskriterium vil blive leksikal ordning, vil der altså i træets topknude være ord med begyndelsesbogstav ca. fra midten af alfabetet. 3.7 Eksklusion af ord Som omtalt i 2.4.5 ønsker vi at fjerne visse uinteressante, almindeligt forekommende ord under konkordansopbygningen. Ordene vil være de trivielle (de hyppigst forekommende sætningssammenbindende ord) fra dansk og engelsk, og vi vil formentlig putte disse ord ind i en struktur der gør det let at undersøge om et givent ord er almindeligt - denne struktur kunne eksempelvis være et fra konkordansen uafhængigt søgetræ. Det skal endvidere være muligt at redigere i udvalget af almindelige ord. Man kunne forestille sig behov for søgning på forbigåede ord, eller man kunne forestille sig, at søgningen yderligere skulle begrænses af en bruger med brug for en hurtig søgning. Man kunne sågar forestille sig behov for at censurere visse ord bort fra konkordansen. Derfor agter vi at lade disse omstridte få ord figurere i en separat tektfil, der så kan redigeres før programstart. 3.8 Uddata ved søgning 3.8.1 Definition af kontekst Som omtalt i 2.5.2 skal søgeordets præsenteres i en fornuftig sammenhæng, og vi har udarbejdet to forslag: 1. Et antal foregående ord (n) efterfulgt af søgeordet efterfulgt at et antal (m) derpå kommende ord 20

2. En intelligent algoritme finpudser en kontekst udvundet efter metode 1. Nr. 1 er intuitiv og let at implementere med vores definition af concsrc. Nr.2 ville imidlertid kræve en temmelig indviklet algoritme. Denne skulle løbe samtlige kontekster igennem efter endt konstruktion af dem vha. metode 1. Algoritmen skulle så - for at resultat-konteksten blev mest mulig informativ - helst defineres dels udfra nogle krav om minimal og maksimal længde, og dels udfra kriterier for udseendet af starten og slutningen af konteksten. Det er klart, at jo højere krav vi stiller til finpudsningen af en sammenhæng, desto langsommere vil søgefunktionen blive, og desto mere afhængige vil vi være af den helt konkrete udformning af concsrc. Imidlertid forekommer forslag nr. 2 for ambitiøst til at konstruere, så køretiden bliver bare nogenlunde rimelig (for hvert lovligt ord i en tekst, der skal opbygges konkordans over, skal et antal ord før og et antal ord efter skanderes fra en ende af og derefter tilpasses og evt. beskæres). Derfor vil vi implementere første forslag, med n = m = 20 (hvilket naturligvis kan ændres). Derved undgås ekstremt beskårne tekststumper som eksemplificeret i 2.5.2. Endvidere højnes effektiviteten af vores konkordansopbygning. I sidste ende bliver dette valg altså til gavn for brugeren, som er interesseret i en hurtigtfungerende hjemmeside - fremfor en 100 % fejlfri præsentation af kontekster og en meget lang opbygningstid. Den helt korrekte udgave af konteksten kan jo beses ved at klikke sig hen på den hjemmeside, man er interesseret i, som søgningen har fundet til een. 3.8.2 Prioritering, sortering, eller... Man kan mene, at uddata i og for sig bør prioriteres eller ordnes efter hjemmesidetilhørsforhold. Med vores angrebsmåde - indeksering af ord på en hjemmeside fra en ende af - vil ordene internt på een hjemmeside i hvert fald komme i den rækkefølge, de stod på hjemmesiden i. Da vi også indekserer de ønskede sider een ad gangen, vil listen af (sammenhæng,adresse) i den enkelte søgetræsknude være sorteret efter adresser - i den rækkefølge de blev indekseret. Derfor vil uddata automatisk have en slags prioritering af søgningsresultaterne, og y- derligere omflytning og prioritering vil tage unødvendig tid fra søgningen. Vi agter således ikke at behandle dette aspekt yderligere. 3.9 Programgennemløb Figuren nedenfor illustrerer, hvordan programmet skal reagere, alt efter situationen. Gennemføres alle operationer i dette skema korrekt, må programmet altså siges at fungere. Figuren kan vi også benytte til vores specifikation af krav til programmets opførsel, se 6.2. 21

22

Kapitel 4 Programbeskrivelse 4.1 Programmel og programudvikling 4.1.1 Moscow ML 2.00 Programmet er skrevet i programmeringssproget Moscow ML 2.00, som kan hentes på http://www.dina.dk/~sestoft/mosml.html Generel information, vejledning og dokumentation kan nås via adressen http://www.dina.dk/~sestoft/mosmllib/index.html 4.1.2 Udviklingsmiljø Programmet er udviklet under variende operativsystemer: 1. Microsoft Windows XP, vha. Emacs til Windows (med SML-mode) 2. Unix (Xwindows) med Emacs (med SML-mode) Nærmere information kan hentes på nedenstående hjemmesider eller nås via disse: http://www.microsoft.com/ http://www.emacs.org http://www.gnu.org 23

4.2 Navngivning Vi har opereret med mange forskellige værdi-typer i programmeringen, og har valgt følgende konvention for navngivning: 1. Funktioner, typer og variable skrives med lille begyndelsesbogstav. Har det pågældende udtryk en kompleks opgave, tilstræbes sigende navngivning. Skal en funktion eksempelvis omsætte HTML til vores interne repræsentation af HTML-kilden (concsrc), gives funktionsnavnet html2concsrc. For at mindske navnelængden, kan vokaler udelades, så en variabel der udgør en ordliste kunne fx. hedde wrdlst. 2. Funktorer, signaturer samt strukturer navngives med stort begyndelsesbogstav. Da funktionen html2concsrc ligger i strukturen HtmlMan, er det fulde navn altså HtmlMan.html2concSrc. 4.3 Funktionstyper Mange funktioner er helt små og overskuelige og er ikke i speciel grad kommenteret eller omtalt i funktionsbeskrivelsen nedenfor. Disse funktioner udgøres ofte af få programlinier og tjener som hjælpefunktioner i mere avancerede funktioner. Ved konstruktionen af de mere avancerede funktioner har vi i rigt omfang benyttet os af iterative funktioner (hvori resultatet kumuleres i et af argumenterne) for at mindske køretiden. Derfor vil funktioner af mange variable af forskellig betydning optræde - og skabe forvirring. Argumenternes betydning vil dog i disse tilfælde specificeres i kommentarer såvel som i funktionsbeskrivelsen nedenfor. 4.4 Msp Vi har benyttet ML s standard-bibliotek Msp til hurtig HTML-generering [3]. 4.5 Programmets grundstruktur Programmet er modulært opbygget, forstået på den måde, at separate programmoduler løser specifikke delproblemer. Programmet er mere omfattende end den i bilag A anførte kildekode, da adskillige præprogrammerede hjælpefiler er benyttet. Opbygningen af Conc.sml, som det har været vores opgave at skrive, er derfor den, vi vil beskæftige os med her. Programmet er illustreret vha. to figurer, den ene viser samtlige mulige programgennemløb (se afsnit 3.9). Nærværende figur illustrerer mere kode-orienteret den modulære opbygning af hovedfilen Conc.sml og dens brug af funktionerne erklæret i substrukturerne. 24

25

4.6 Beskrivelse af moduler og funktioner Her følger en beskrivelse af de moduler, vi har programmeret (dvs. filerne server.sml, Src.sml er udeladt i beskrivelsen), de væsentligste funktioner i dem samt deres opgaver. Vi har konsekvent valgt at gøre modulerne transparante, da modulerne imellem sig benytter et væld af hinandens funktioner. 4.6.1 Modulet Conc Den overordnede ramme for programmets kørsel og hjemmesidens udseeende. Modulet koordinerer funktionskald fra alle de andre moduler. Målet er et afsluttende kald af funktionen handleget, der returnerer en konkordans (ændret, hvis brugeren ønskede at tilføje en side til konkordansen, uændret ellers) og en streng, som så fortolkes som HMTL-kode og giver hjemmesiden et nyt udseende (fx. vises efter endt søgning søgeresultaterne på siden). - conc : Typen af den interne repræsentation af konkordansen: Et søgetræ (indeholdende søgeord og oplysninger om deres kontekster og konteksternes adresser) samt en adresseliste over allerede indekserede sider. - empty : Den tomme konkordans: Ingen indekserede sider. - commonwrds : almindelige ord, lagret i et søgetræ. Disse ord indsættes ikke i konkordansen - frasorteres i opbygningsfasen - start : Den initielle hjemmeside - inden opbygning og søgning er påbegyndt. addconc addconc kaldes, når konkordans skal opbygges. Funktionen kaldes med parametrene contree - den initielle konkordans søgetræsdel xtendedwrds - en udvidet udgave af den concsrc vi skaffer i handleget (se denne) wrd::wrds - HTML-kilden omsat til concsrc addy - adressen på den side, vi er i gang med at tilføje til konkordansen. Funktionens gang: 1. Undersøg vha. checkword (se denne), om det første ord i wrd::wrds er lovligt. Hvis ja, gå til 2) ellers til 4) Hvis wrds er tom, gå til 5) 2. Kontekst genereres ved et kald af CreateSentence.createSentence. Gå til 3) 3. Indsæt ord (#1 wrd - der jo er en (string*bool)- tuple) og kontekst i konkordansen. Gå til 1) 26

4. Ignorer ordet og kald igen med næste ord i wrds. 5. Balancer søgetræsdelen af konkordansen. handleget handleget kaldes med parametrene (contree,addyls) - Den initielle konkordans: (søgetræ,adresseliste) service - ordren til handleget om, hvilken operation der skal udføres: konkordansopbygning ("mkconc") eller søgning ("search"). HTML-variable i liste - Ved benyttelse af HTML-formularer benyttes variable i form af par, og disse lagres principielt (ved flere forespørgsler) i en liste. For os vil tilfældet dog altid være det, at listen bliver 1 element lang, og indeholder enten parret ("URI","adresse") eller ("search","søgeord"). Funktionens gang (illustreres bedst ved de i rapporten inkluderede figurer): 1. Hvis service = mkconc gå til 2), hvis service = search gå til 3), ellers gå til 4) 2. Konkordans skal opbygges. Er den specificerede URI gyldig? Hvis ja gå til 5) ellers til 6) 3. Består søgeordet af et ord (gå til 9) eller flere (gå til 10)? 4. Klientforespørgslen ugyldig. Ingen ændring i konkordans eller hjemmeside. 5. Er siden indekseret? Hvis ja, gå til 7) ellers gå til 8). 6. URI ugyldig: Meddel brugeren herom. 7. URI allerede indekseret. Ingen ændring i konkordans eller hjemmeside. 8. Konkordans skal opbygges over siden. HTML-kilde hentes med getinternetpage og renses med html2concsrc. Kald addconc med de relevante parametre. 9. Kald ConcTree.search med de rette parametre. Generer HTML med de fundne søgeresultater, returner initiel konkordans. 10. Kald MultipleSearch.multipleSearch med de rette parametre. Generer HMTL med de fundne søgeresultater, returner initiel konkordans. 27

4.6.2 Funktoren SetTree Da vi skulle bruge en søgetræs-struktur to gange, men med forskelligt indhold i knuderne i hvert af tilfældene, ville en masse programmering af funktioner til søgning, indsættelse og balancering skulle skrives for forskelligt knudeindhold - hvis det ikke var for funktoren SetTree. Denne funktor benyttes til at skabe de to strukturer 1. WordTree : Vores søgetræ over ekskluderede ord 2. ConcTree : Vores interne repræsentation af søgetræs-delen af konkordansen Funktioner i SetTree De erklærede funktioner i SetTree er kopier af kendte funktioner for træer. - key : Typen af den etiket, træets knuder har. - data : Data lagret i træets knuder. - search : Efter en i den struktur, der tages som argument, angivet key - sammenligningsmetode, afsøges træet. - insert : Indsætter en værdi af type key på sin rette plads i træet (vha. search). - balancetree : Balancerer et søgetræ ved divide and conquer -metoden: Først laves træet om til en liste. Dernæst opdeles listen i en midte og to sublister, midten bliver topknude og de to subtræer udgøres så af balancetree virkende på sublisterne. WordTree Dette søgetræ har typen key defineret til string, og etiketterne repræsenterer det lagrede ord. Typen data er sat til string og indeholder en kopi af søgeordet, som returneres med søgefunktionen. Heraf bliver compare-funktionen (krævet i signaturen for funktorens argumenter) til String.compare. ConcTree Typen key er string, og repræsenterer ord, der er opbygget konkordans over. Typen data bliver (string * string) list, som faktisk er en (string * HtmlMan.address) list), se 4.6.4 - en liste af kontekster for et søgeord, kombineret med den adresse, hvorpå konteksten er fundet.compare-funktionen bliver således atter String.compare. 28

4.6.3 Modulet CheckWord CheckWord-modulet omfatter funktionen checkword og dens hjælpefunktioner. checkword skal afgøre, om et ord skal indsættes i konkordansen - altså om hvorvidt om et ord tilhører listen over de forbudte ord eller er et specialtegn. Hjælpefunktionerne er simple (readfile muliggør lagringen af listen over ekskluderede ord i en separat fil). - checkword har to mønstre. Det ene rammer indkommende tupler af formen (_,false). Disse er IKKE ord, men tegn, og skal derfor ikke indsættes i konkordansen. De andre har formen (_,true) og ER altså ord. Disse undersøges så for evt. medlemsskab af den sorte liste. 4.6.4 Modulet HtmlMan Benytter hjælpefunktioner [2,table D.12 og D.13 s. 321]. Indeholder de funktioner, der på en eller anden måde manipulerer med HTML-kode (herunder Msp-funktioner 1 [3]). De definerede typer udtømmende kommenteret. Modulet HtmlMan har 4 opgaver: 1. HTML-kilde skal konverteres til concsrc 2. Normalisering af søgeord 3. Msp-funktioner 4. Filbehandlingsfunktioner concsrcfromhtml Denne funktion har mange argumenter, klarer mange opgaver på een gang og er iterativ. Funktionen har 3 opgaver, mens den arbejde sig gennem HTML-kilden: 1. Rensning af den indkommende HTML-tekst for HTML-mærker (og Javascript) 2. Omsætning af de danske bogstaver æ, ø og å til deres HTML-repræsentationer (for entydigt uddata). 3. Transformation af HTML-kilden til concsrc. Funktionen er af typen (char list) * bool * string * (string * bool) list -> concsrc. De 4 argumenter har betydningerne - char list : Er en liste af de karakterer, vi får ved at anvende explode-funktionen på den streng (hstring), getinternetpage har skaffet. - bool : En parameter, der angiver, om vi befinder os i et HTML-mærke eller ej. 1 Et HTML-manipulerende ML-biblioteksmodul vi har anvendt 29