Presentation fixed
[ailab3.git] / rapport.tex
blobd4b5120cba77fbfbe500a9ef06b5fd41548bbaee
1 \documentclass[a4paper, 12pt]{article}
2 \usepackage[swedish]{babel}
3 \usepackage[utf8]{inputenc}
4 \usepackage{verbatim}
5 \usepackage{fancyhdr}
6 \usepackage{graphicx}
7 \usepackage{parskip}
8 % Include pdf with multiple pages ex \includepdf[pages=-, nup=2x2]{filename.pdf}
9 \usepackage[final]{pdfpages}
10 % Place figures where they should be
11 \usepackage{float}
13 % vars
14 \def\title{Projekt}
15 \def\preTitle{Laboration 3: Information Retrieval \& Extraction}
16 \def\kurs{Artificiell Intelligens med inriktning mot kognition och
17 design B, ht 2008}
19 \def\namn{Anton Johansson}
20 \def\mail{dit06ajn@cs.umu.se}
21 \def\namnett{Victor Zamanian}
22 \def\mailett{dit06vzy@cs.umu.se}
24 \def\handledareEtt{Dennis Olsson, denniso@cs.umu.se}
25 \def\inst{datavetenskap}
26 \def\dokumentTyp{Laborationsrapport}
28 \begin{document}
29 \begin{titlepage}
30 \thispagestyle{empty}
31 \begin{small}
32 \begin{tabular}{@{}p{\textwidth}@{}}
33 UMEÅ UNIVERSITET \hfill \today \\
34 Institutionen för \inst \\
35 \dokumentTyp \\
36 \end{tabular}
37 \end{small}
38 \vspace{10mm}
39 \begin{center}
40 \LARGE{\preTitle} \\
41 \huge{\textbf{\kurs}} \\
42 \vspace{10mm}
43 \LARGE{\title} \\
44 \vspace{15mm}
45 \begin{large}
46 \namn, \mail \\
47 \namnett, \mailett
48 \end{large}
49 \vfill
50 \large{\textbf{Handledare}}\\
51 \mbox{\large{\handledareEtt}}
52 \end{center}
53 \end{titlepage}
55 \newpage
56 \thispagestyle{empty}
57 \mbox{}
58 \newpage
60 \pagestyle{fancy}
61 \rhead{\footnotesize{\today}}
62 \lhead{\footnotesize{\namn, \mail \\ \namnett, \mailett}}
63 \chead{}
64 \lfoot{}
65 \cfoot{}
66 \rfoot{}
68 \section*{Sammanfattning}
69 Reguljära uttryck (Regular Expressions) är uttryck som innehåller
70 olika syntax för att identifiera specifika textsträngar ur en större
71 mängd text. Detta kan användas inom ämnet Artificiell Intelligens för
72 att till exempel validera och tolka indata och specificera olika typer
73 av språk.
75 \newpage
76 \tableofcontents
77 \newpage
79 \rfoot{\thepage}
80 \pagenumbering{arabic}
82 % TODO @anton - Problem-solving as search, basic to AI, Norvig.
84 \section{Introduktion}
85 % till ämnet.
86 Denna rapport går igenom användandet av Reguljära uttryck (Regular
87 Expressions på engelska, även förkortat som ''regexp'' eller bara
88 ''regex'') med hänseende på informations hämtning inom ämnen
89 Artificiell intelligens.
91 Rapporten är formulerad och utförd enligt specifikation på sidan:\\
92 \verb!http://www.cs.umu.se/kurser/5DV063/HT08/assignments/!\\
93 \verb!lab3-spes-ht08.html!
95 \section{Syfte}
96 % med uppgiften, beskrivet med egna ord.
97 Syftet med rapporten är att fördjupa sig inom ett smalt ämne inom
98 området Artificiell Intelligens och presentera teori för det valda
99 ämnet på ett vetenskapligt sätt.
101 \section{Metodbeskrivning}
102 %: beskrivning av metod, material, design och procedur
103 Denna rapport är sammanställd främst genom en litteraturstudie inom
104 området Artificiell Intelligens i förhållande till Reguljära uttryck.
105 Information och tankar är samlade från böcker och internetsidor, för
106 att försöka få en överblick över de Reguljära uttryckens betydelse och
107 användande inom området.
109 \section{Litteraturstudie}
110 %, teoretisk fördjupning
111 Enligt \cite{speech} härstammar Reguljära uttryck från Alan Turings
112 modell (1936) för aritmetisk beräkning, även kallad
113 Turingmaskin. Denna maskin var abstrakt, ett tankeexperiment, för att
114 utföra beräkningar.
115 % TODO Church-Turings hypotes säger att varje tänkbar process kan
116 % utföras av en Turingmaskin, och alltså finns det rent principiellt
117 % inte någon mer kraftfull beräkningsmekanism. Enligt wikipedia
118 % http://sv.wikipedia.org/wiki/Turingmaskin
120 Inspirerad av Turings arbete skapade sedan Warren McCulloch och Walter
121 Pitts (1943) en förenklad modell för neuronen, se \cite{norvig}
122 kapitel 18.
124 Stephen Cole Kleene definierade sedan (1951 och 1956) Ändlig
125 automation (Finite automation), Reguljära uttryck och påvisade deras
126 likhet.
128 Både Reguljära uttryck och Finite automation är en del av den språktyp
129 som brukar kallas Reguljära språk, (Regular Language).
131 I \cite{speech} ger man ett exempel på hur Finite automation och
132 Reguljära uttryck förhåller sig till varandra. Säg att man ska
133 definiera ett naturligt språk, för enkelhets skull försöker vi
134 definiera vad som är ''ko-språk''. Vi kan säga att korrekt
135 ''ko-språk'' definieras av kombinationerna:
137 \begin{verbatim}
138 Muu!
139 Muuu!
140 Muuuu!
142 \end{verbatim}
144 Detta skulle kunna beskrivas med en modell för \textbf{Finite-state
145 automation} enligt figur nedan.
147 \begin{figure}[H]
148 \begin{center}
149 \includegraphics[width=110mm]{images/state.pdf}
150 \caption{Ändlig automation för ''ko-språk''}
151 \label{state.pdf}
152 \end{center}
153 \end{figure}
155 Tillstånden \verb!q0-q4! är de giltiga tillstånd som finns, \verb!q1!
156 är starttillståndet och \verb!q4! representerar sluttillstånd. Pilarna
157 i figuren markerar möjliga förflyttningar mellan tillstånden.
159 Denna information går även att representera som en
160 \textbf{State-transition-tabell}, se nedan:
162 \begin{center}
163 \begin{tabular}{|c|l|l|l|}
164 \hline
165 & \multicolumn{3}{|c|}{Indata} \\
166 \hline
167 Tillstånd & M & u & ! \\
168 \hline
169 0 & 1 & 0 & 0 \\
170 1 & 0 & 2 & 0 \\
171 2 & 0 & 3 & 0 \\
172 3 & 0 & 3 & 4 \\
173 4 & 0 & 0 & 0 \\
174 \hline
175 \end{tabular}
176 \end{center}
178 Ovanstående tabell läses uppifrån och ner. Starttillståndet \verb!0!
179 har en giltig förflyttning till tillstånd \verb!1!, detta gäller
180 enbart för indata \verb!M!, för alla andra indata finns inga giltiga
181 förflyttningar, detta markeras med \verb!0!.
183 Det korresponderande \textbf{Reguljära uttrycket} för att beskriva
184 ''ko-språk'' skulle vara:
186 \begin{verbatim}
187 Muu+!
188 \end{verbatim}
190 Man läser det ungefär som man läser vanlig text. \verb!M! är tillåtet
191 starttillstånd, följt av ett \verb!u!, sedan markerar operatorn
192 \verb!u+! att en eller flera \verb!u! är tillåtna. Meningen avslutas
193 med \verb?!?, vilket markerar sluttillståndet. % Se sektion TODO för
194 mer info om regexp syntax.
196 % REGEXP-MANUAL:
197 % Står på sidan 848 i Norvig.
199 Ett reguljärt uttryck består enkelt nog av text som ska matchas. Om
200 man vill matcha texten ''hej'' i en textsträng ''hoppsanhejsan'' så
201 blir det reguljära uttrycket helt enkelt bara ''hej'' och ''hej'':et i
202 ''hoppsanhejsan'' matchas. Däremot är det mer sällan man använder
203 reguljära uttryck för sådana enkla matchningar. Man vill i stället
204 använda dem till att matcha \textbf{generella mönster}. Ett exempel på
205 ett mönster skulle kunna vara en e-postadress på formen
206 \verb!<användarnamn>@<subdomän>.<domän>!, där \verb!<användarnamn>!
207 kan innehålla (i detta exempel) alla siffror, alla små och stora
208 bokstäver (från A till Z), understreck, punkt, procenttecken,
209 bindestreck och plus.
211 I stället för att behöva skriva ett textmönster för varje e-postadress
212 som är möjlig att konstruera (i praktiken oräkneligt antal
213 variationer) kan man använda sig av speciella ''texthändelser'' för
214 att beskriva till exempel början\slash slutet av ett ord och
215 början\slash slutet av en hel sträng. Man kan också definiera
216 teckenklasser som man vill inkludera i sitt uttryck, till exempel alla
217 stora bokstäver, alla små bokstäver, siffror, eller till och med
218 vilken godtycklig kombination av tecken som helst. Här nedanför visas
219 en kort tabell med några texthändelser och deras motsvarande reguljära
220 uttryck.
222 \begin{center}
223 \begin{footnotesize}
224 \begin{tabular}{|c|p{4cm}|l|l|l|}
225 \hline
226 \textbf{regex-uttryck} & \textbf{Texthändelse} & \textbf{Exempel} & \textbf{Matchar} \\ \hline
228 \verb!\b! & Början eller slutet på ett ord & \verb!\b!text\verb!\b! & ''ord1 \textbf{text} ord3'' \\ \hline
230 \verb!^! & Början av en textsträng & \verb!^!text & ''\textbf{text} i början'' \\ \hline
232 \verb!$! & Slutet av en textsträng & \verb!lutet$! & ''text i s\textbf{lutet}'' \\ \hline
234 \verb![A-Za-z0-9]! & Definierar klass med tecknen A till Z, a
235 till z och 0 till 9. & \verb![abc0-9]! & ''\textbf{b}r\textbf{a} text med \textbf{23} te\textbf{c}ken'' \\
237 \hline
239 \verb!.! (punkt) & Står för vilket tecken som helst. & \verb!^.! & ''\textbf{t}ext'' \\ \hline
240 \end{tabular}
241 \end{footnotesize}
242 \end{center}
244 Om man vill matcha en e-postadress i löpande text skulle man alltså
245 vilja använda sig av \verb!\b! runt uttrycket för att markera att det
246 som finns runt omkring adressen måste vara ordavgränsare av något
247 slag, dvs. någon typ av blanktecken. Vill man däremot kontrollera
248 indata från till exempel ett formulärfält där det är meningen att en
249 användare ska ange enbart en e-postadress är det däremot önskvärt att
250 omsluta uttrycket med \verb!^! i början och \verb!$! i slutet för att
251 markera att hela strängen måste \textbf{börja och sluta med} adressen.
253 Låt oss definiera en teckenklass med alla siffror, dvs
254 ''\verb![0-9]!'' och använda det i ett reguljärt uttryck, till exempel
255 ''\verb!\b$[0-9]!''. Om vi sedan försöker matcha strängen ''\$10000''
256 med det mönstret kommer vi endast matcha följande (fet stil)
257 ''\textbf{\$1}0000''. Detta beror på att teckenklassen vi definierat
258 matchar bara \textit{det första} tecknet som platsar i
259 klassen. Självklart skulle vi vilja kunna matcha flera tecken i en och
260 samma teckenklass utan att behöva definiera en likadan klass för hela
261 det antalet tecken vi vill matcha. Därför har man definierat något som
262 kallas kvantifierare som gör att man kan bestämma hur många gånger man
263 vill matcha en specifik klass, ett mönster eller bara ett tecken (så
264 kallade ''tokens''). Nedanstående tabell beskriver olika
265 kvantifierare.
267 \begin{center}
268 \begin{footnotesize}
269 \begin{tabular}{|c|p{4cm}|l|p{4cm}|}
270 \hline
271 \textbf{kvantifierare} & \textbf{Beskrivning} & \textbf{Exempel} & \textbf{Matchar} \\ \hline
273 \verb!?! & Matchar föregående uttryck noll eller en gång. &
274 colou\verb!?!r & ''\textbf{colour}'' och ''\textbf{color}'' \\ \hline
276 \verb!+! & Matchar föregående uttryck en eller fler gånger. &
277 Mu\verb:+:! & ''\textbf{Mu!}'', ''\textbf{Muu!}'',
278 ''\textbf{Muuu!}'', \ldots \\ \hline
280 \verb!*! & Matchar föregående uttryck noll eller flera gånger &
281 10\verb!*! & ''\textbf{1}'', ''\textbf{10}'', ''\textbf{100}'',
282 \ldots \\ \hline
284 \verb!{!$n$\verb!,!$m$\verb!}! & Matchar föregående uttryck
285 minst $n$ gånger och som mest $m$ gånger. &
286 \verb!^!1\verb![!0\verb!]{!1,5\verb!}! & ''\textbf{10}'',
287 ''\textbf{100}'', ''\textbf{1000}'', ''\textbf{10000}'' och
288 ''\textbf{100000}'' men inte ''1'' och inte ''1000000'' (6
289 nollor eller mer).\\ \hline
290 \end{tabular}
291 \end{footnotesize}
292 \end{center}
294 Nu kan vi beskriva många olika variationer av mönster genom olika
295 texthändelser och kvantifierare, men vad händer om man vill inkludera
296 till exempel ett frågetecken i sitt mönster? Då måste man ''komma
297 runt'' (escape) frågetecknets regexp-betydelse för att komma åt dess
298 textuella värde. Detta görs vanligtvis med bakåtvänt snedstreck
299 (\textbackslash). Till exempel måste vi i vårt e-post\-adress\-mönster
300 matcha en punkt (i domännamnet), som vi måste uttrycka som
301 ''\verb!\.!''.
303 Nu har vi tillräckligt stor kunskap för att uttrycka ett reguljärt
304 uttryck som matchar en generell e-post\-adress. Vi börjar med att
305 beskriva \verb!<användarnamn>!. Användarnamnet kunde som sagt var
306 innehålla små och stora bokstäver (från A till Z), siffror, punkt,
307 understreck, procenttecken, plustecken och bindestreck. Vi uttrycker
308 detta som
310 \begin{verbatim}
311 \b[A-Za-z0-9._%+-]+
312 \end{verbatim}
314 där det sista plustecknet som sagt innebär att alla de tecken som den
315 definierade tecken\-klassen innefattar måste matchas minst en
316 gång. Plustecknet inom tecken\-klass\-definitionen tolkas som ett
317 ''textplus'' och inte som ett ''regex-plus''. Vi lägger också till
318 ordavgränsare som gör att uttrycket bara matchar användarnamnet i
319 början av ett nytt ord (dvs. själva e-post\-adressen) och inte matchar
320 ett användarnamn när det kommer direkt efter ett icke tillåtet
321 användarnamnstecken. Hade vi glömt ordavgränsaren hade följade
322 användarnamn matchats:
323 \\ ''\copyright\&\texttrademark\textexclamdown\textbf{sven.svensson}@host.doman''
324 vilket vi inte vill eftersom de icke tillåtna tecknen inte bör finnas
325 före användarnamnet.
327 Vi uttrycker sedan domännamnet som
329 \begin{verbatim}
330 [A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
331 \end{verbatim}
333 där plustecknet betyder precis samma sak som i uttrycket för
334 användarnamnet och ''\verb!\.!'' står för punktens textuella
335 värde. Sedan finns det ett krav på det som står efter punkten i
336 domännamnet, nämligen att denna ''token'' måste bestå av minst 2 och
337 som mest 4 tecken, därav kvantifieraren \verb!{!2\verb!,!4\verb!}!.
338 \verb!\b! i slutet av uttrycket innebär att det måste finnas en
339 ordavgränsare efter domännamnet.
341 Sätter vi nu samman dessa uttryck med ett snabel-a i mitten får vi ett
342 uttryck för en generell e-post\-adress \textbf{i löptext}. Vill vi
343 definiera ett uttryck för att undersöka om totala textmängden består
344 av endast en e-post\-adress kan vi ersätta \verb!\b! i början med
345 \verb!^! och i slutet med \verb!$! (till exempel om vi vill
346 kontrollera ett formulärfält på en webbsida)
347 \cite{regexinfo:website}. De två olika uttrycken ser ut som följer:
349 \begin{verbatim}
350 \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
351 \end{verbatim}
355 \begin{verbatim}
356 ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$
357 \end{verbatim}
359 % Olika sätt att matcha e-mail adresser.
360 % \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b
361 % ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$
362 % http://www.regular-expressions.info/email.html
364 \section{Resultat}
365 % innehållande sammanställning/analys av eventuell testdata,
366 % implementering av algoritmer osv.
368 % TODO - resultat, användningsområden kopplade till AI.
369 % TODO @anton - Kolla upp och skriv om ELIZA, regexp memory.
370 \subsection{Applikationer av Reguljära uttryck}
371 Följande sektioner berör olika användningsområden för Reguljära
372 uttryck inom Artificiell intelligens.
374 \subsubsection{ELIZA}
375 Mer avancerade former av Reguljära uttryck kan använda sig av
376 minnesfunktioner för att spara tidigare matchningar. I
377 programmeringssråket Perl kan man göra ersättningar på formen:
378 \begin{verbatim}
379 s/hej/hejsan/
380 \end{verbatim}
382 Här ersätts alla \verb!hej! med \verb!hejsan!. För att spara träffar i
383 sökningen och ersätta med samma ord i ersättningssträngen använder man
384 grupper inom parenteser \verb!()!. Den sträng som en grupp matchar kan
385 sedan refereras till, \verb!\1! representerar innehållet i första
386 gruppen.
388 \begin{verbatim}
389 s/jag heter (\w+)/på dig \1, trevligt att höras/
390 \end{verbatim}
392 Ovanstående Reguljärt uttryck skulle ersätta ''Hej jag heter Anton''
393 med ''Hej på dig Anton, trevligt att höras''. Denna typ av Reguljära
394 ersättningar utgör grunden för implementationen av Chatroboten ELIZA,
395 som utvecklades av Joseph Weizenbaum, se \cite{speech}. Här följer en
396 kort konversation med Emacs implementering av ELIZA:
398 \begin{itemize}
399 \item[-] Hello my name is Anton
400 \item[-] \textbf{ELIZA:} How do you do? What brings you to see me?
401 \item[-] I need help with some Artificial Intelligence questions
402 \item[-] \textbf{ELIZA:} Why do you say you need help with some
403 artificial intelligence questions?
404 \item[-] I'm writing an essay about Regular Expressions
405 \item[-] \textbf{ELIZA:}Is it because of your plans that you say you
406 are writing an essay about regular expressions?
407 \item[-] yes
408 \item[-] \textbf{ELIZA:} I see... Well, what makes you believe this is so?
409 \end{itemize}
411 Ovanstående exempel vittar om att denna typ av chatrobot har en
412 relativt fast ram med frågor och svar att följa. Det tar inte lång tid
413 för en mänsklig användare att förstå att det inte är en mänsklig
414 motpart man kommunicerar med. ELIZA är implementerad för att svara på
415 frågor som rör psykoterapi--så fort man lämnar det bekanta ämnet blir
416 följdfrågorna ologiska ur ett mänskligt perspektiv.
418 Emacs implementation av ELIZA har en mängd hårdkodade svar. Följande
419 kodsnutt visar svaren som kan fås av indata som innehåller vissa
420 nyckelord gällade död:
422 \begin{footnotesize}
423 \begin{verbatim}
424 (setq deathlst
425 '((this is not a healthy way of thinking \.)
426 ((doc$ bother) you\, too\, may die someday \?)
427 (i am worried by your obsession with this topic!)
428 (did you watch a lot of crime and violence on television as a child \?))
430 \end{verbatim}
431 \end{footnotesize}
433 Även mängder med vanliga ord sparas för att på ett bättre sätt kunna
434 tolka indata, exempelvis vanliga synonymer, pronomen, verb och förkortningar:
436 \begin{footnotesize}
437 \begin{verbatim}
438 (setq replist
439 (wanna . (want to))
440 (gimme . (give me))
441 (gotta . (have to))
442 (gonna . (going to))
443 (never . (not ever))
444 ...)
445 \end{verbatim}
446 \end{footnotesize}
448 \subsubsection{Tolkning av indata}
449 Det finns en mängd användbara Reguljära uttryck för att tolka och på
450 ett vettigt sätt behandla indata som ett datorsystem får från
451 användare. Det kan gälla exempelvis verifiering av e-postadresser,
452 datum, person- och telefonnummer och så vidare. Detta är användbart
453 vid all typ av indata från användare, och i hög grad aktuellt när det
454 gäller forumlär på Internet.
456 Till exempel kan man istället för att kräva att användare ska skriva
457 för- och efternamn i separata rutor använda Reguljära uttryck för att
458 försöka tolka vad som är vad. Samma sak gäller adresser och
459 telefonnummer. Det kan vara intressant att ha information och ett
460 telefonnummers riktnummer och landskod, utan att för den sakens skull
461 kräva att en användare ska behöva specificera allt sådant manuellt.
462 Följer man bara vanliga konventioner för hur telefonnummer skrivs kan
463 man skapa ett Reguljärt uttryck för att fånga upp all denna
464 information ur en enda textsträng. All sådan här tolkning av indata är
465 väldigt bra ur användarsynpunkt, ''Don't make me click'', som Aza
466 Raskin \cite{raskin:website} säger i en presentation om
467 användarvänlighet på webbsidor.
469 %@TODO fixa url löpande
470 Ett annat bra exempel på hur Reguljära uttryck kan underlätta
471 inmatning av data finns implementerat i den webbaserade
472 kalendertjänsten från
473 Google \begin{footnotesize}{http://google.com/}{calendar/}\end{footnotesize}. För
474 att skapa en ny händelse i kalendern kan användaren klicka på aktuell
475 dag och skriva till exempel ''Äta mat hos mamma kl 10-12''. Detta
476 genererar en händelse med rubrik ''Äta mat hos mamma'' och placeras
477 med start kl 10 och slut kl 12 i kalendern. Ett Reguljärt uttryck för
478 detta skulle kunna vara att matcha de första siffrorna efter
479 \verb!(kl|klockan)!, dessa borde vara starttimme för händelsen. Följs
480 dessa siffror av \verb!.! eller \verb!:! utan mellanslag efter skulle
481 nästa två siffror kunna representera minuter, nästa siffror,
482 eventuellt efter ett bindestreck, kan representera sluttid. På detta
483 sätt kan man med hjälp av Reguljära uttryck representera naturligt
484 språk för datorn. Vidare skulle extra nyckelord kunna läggas in, till
485 exempel \verb!hos!, \verb!på! eller \verb!i! för att markera att det
486 som följer är en plats, eller \verb!med! för att markera att följande
487 text innehåller information om deltagare i händelsen.
489 \subsubsection{Datahämtning}
490 Reguljära uttryck kan användas för att hämta och tolka information ur
491 en större mängd data. Ett trivialt exempel är till exempel att försöka
492 svara på frågan, ''Vad är det för väder i Umeå idag?'' baserat på
493 innehållet från sidan:
495 \begin{verbatim}
496 http://www.tfe.umu.se/weather/1440/900/10/sv-SE/now.htm
497 \end{verbatim}
499 Html-taggen som visar den aktuella temperaturen i Umeå har följande
500 utseende:
501 \begin{verbatim}
502 <td class="tempfont" ... >0,7 &deg;C</td>
503 \end{verbatim}
505 Det som skiljer denna tagg från de andra på sidan är attributet
506 \verb!class="tempfont"!. Den aktuella temperaturen visas mellan
507 \verb!<td ...>! och \verb!</td>!, det innebär att det i detta exempel
508 skulle vara $0,7\,^{\circ}\mathrm{C}$ dagen sidan hämtades. Följande
509 Reguljära uttryck matchar den strängen som innehåller temperatur i sin
510 första grupp, dvs uttrycket inom \verb!()!, som senare kan refereras
511 till med \verb!\1!:
513 \begin{verbatim}
514 <td class="tempfont.+?>([0-9]+,[0-9]+)
515 \end{verbatim}
517 Med denna information kan man sedan förenkla och säga att bra väder
518 gäller för alla $temperaturer \geq 15$ och dåligt väder gäller för
519 $temperaturer < 15$. Detta Reguljära uttryck är mycket specifikt och
520 enbart användbart på denna specifika sida så länge temperaturen
521 inkapslas exakt av den HTML-taggen och eventuella attribut.
523 \section{Diskussion}
524 % av resultatet, koppling till tidigare studier.
526 \section{Slutsats}
529 %. Använd minst två referenser utöver kursboken.
530 \bibliographystyle{alpha}
531 \bibliography{books}
533 \end{document}