FL 6: Definite Clause Grammars (kap. 7) Teori Introducerar kontextfria grammatikor och några besläktade begrepp Introducerar definite clause - grammatikor, Prologs sätt att jobba med kontextfria grammatikor (och andra grammatikor likaså)
Kontextfria grammatikor Prolog erbjuder en speciell notation för att definiera grammatikor med, nämligen DCG:or eller definite clausegrammatikor Så vad är en grammatik? Vi ska besvara frågan genom att diskutera kontextfria grammatikor CFG:or är en mycket kraftig mekanism som kan hantera de flesta aspekter av syntaxen hos naturliga språk (ex. svenska/finska)
Ett exempel på en CFG s np vp np det n vp v np vp v det the det a n man n woman v shoots
Ingredienserna av en grammatik Pilsymbolen används för att definiera reglerna Symbolerna s, np, vp, det, n, v heter icke-terminala symboler De kursiverade symbolerna är de terminala symbolerna: the, a, man, woman, shoots s np vp np det n vp v np vp v det the det a n man n woman v shoots
En liten bit lingvistik De icke-terminala symbolerna i denna grammatik har en traditionell mening i lingvistik: np: noun phrase (nominalfras) vp: verb phrase (verbfras) det: determiner (determinerare) n: noun (substantiv) v: verb (verb) s: sentence (mening, i vissa fall sats)
Mera lingvistik I en lingvistisk grammatik motsvarar de icke-terminala symbolerna oftast grammatikaliska kategorier I en lingvistisk grammatik kallas de terminala symbolerna lexikala enheter, eller helt enkelt ord (en datavetare skulle kalla dem alfabetet)
Kontextfria regler Exempelgrammatiken består av nio kontextfria regler En kontextfri regel består av: En ensam icke-terminal symbol följd av följd av en ändlig sekvens av terminala eller icke-terminala symboler s np vp np det n vp v np vp v det the det a n man n woman v shoots
Vad täcker grammatiken? Betrakta följande sträng: the woman shoots a man Är denna sträng grammatikalisk enligt vår grammatik? Och om den är det, vilken syntaktisk struktur har den?
Syntaktisk struktur s vp np np det n v det n the woman shoots a man s np vp np det n vp v np vp v det the det a n man n woman v shoots
Parse trees (syntaxträd) Träd som representerar den syntaktiska strukturen av en sträng kallas ofta syntaxträd (parse trees) Syntaxträd är viktiga: De ger oss information om strängen De ger oss information om struktur
Grammatikaliska strängar Om vi får en sträng av ord och en grammatik, och det visar sig att vi kan konstruera ett syntaxträd, säger vi att strängen är grammatikalisk (med avseende på den givna grammatiken) Ex., the man shoots är grammatikalisk Om vi inte kan konstruera ett syntaxträd är den givna strängen ogrammatikalisk (igen med avseende på den givna grammatiken) Ex. a shoots woman är ogrammatikalisk
Genererat språk Språk som genereras av en grammatik består av alla de strängar som grammatiken klassificerar som grammatikaliska T. ex. a woman shoots a man a man shoots hör till språket som genereras av vår lilla exempelgrammatik
Igenkännare/Recogniser En kontextfri igenkännare (recogniser) är ett program som korrekt informerar oss om en sträng hör eller inte hör till det språk som genereras av en kontextfri grammatik Med andra ord är en igenkännare/ recogniser ett program som korrekt klassificerar strängar i grammatikaliska och ogrammatikaliska
Information om struktur Men varken i lingvistik eller datavetenskap är vi enbart intresserade av ifall en sträng är grammatikalisk eller ej Vi vill också veta varför den är grammatikalisk: vi vill veta dess struktur Syntaxträdet ger oss denna struktur
Analysprogram/Parser En kontextfri parser avgör korrekt ifall en sträng hör till det språk som genereras av en kontextfri grammatik Och det berättar oss också vad dess struktur är Alltså: En recogniser säger bara ja eller nej En parser ger oss också syntaxträdet
Kontextfritt språk Vi vet vad en kontextfri grammatik är, men vad är ett kontextfritt språk? Helt enkelt: ett kontextfritt språk är ett språk som kan genereras av en kontextfri grammatik Vissa mänskliga språk är kontextfria, vissa andra är inte det Engelska och italienska är antagligen kontextfria Holländska och Schweiz-tyska är inte kontextfria
Teori vs. praktik Detta om teorin, men hur jobbar vi med kontextfria grammatikor i Prolog? Anta att vi får en kontextfri grammatik Hur ska vi skriva en recogniser för den? Hur ska vi skriva en parser för den? Under denna föreläsning ska vi lära oss att definiera en igenkännare/ recogniser
CFG-igenkänning i Prolog Vi ska använda listor för att representera strängar [a,woman,shoots,a,man] Regeln s np vp kan tänkas som en konkatenering av en np-lista med en vp-lista så att resultatet blir en s-lista Vi vet hur vi kan konkatenera listor i Prolog: mha append/3 Så nu gäller det att implementera detta i Prolog
CFG-igenkänning mha append/3 s(c) :- np(a), vp(b), append(a,b,c). np(c) :- det(a), n(b), append(a,b,c). vp(c) :- v(a), np(b), append(a,b,c). vp(c) :- v(c). det([the]). det([a]). n([man]). n([woman]). v([shoots]).
CFG-igenkänning mha append/3?- s([the,woman,shoots,a,man]). yes?- s(c) :- np(a), vp(b), append(a,b,c). np(c) :- det(a), n(b), append(a,b,c). vp(c) :- v(a), np(b), append(a,b,c). vp(c) :- v(c). det([the]). det([a]). n([man]). n([woman]). v([shoots]).
CFG-igenkänning mha append/3?- s(s). s(c) :- np(a), vp(b), append(a,b,c). np(c) :- det(a), n(b), append(a,b,c). vp(c) :- v(a), np(b), append(a,b,c). vp(c) :- v(c). det([the]). det([a]). n([man]). n([woman]). v([shoots]). S = [the,man,shoots,the,man]; S = [the,man,shoots,the,woman]; S = [the,woman,shoots,a,man]
CFG-igenkänning mha append/3?- s(s). S = [the, man, shoots, the, man] ; S = [the, man, shoots, the, woman] ; S = [the, man, shoots, a, man] ; S = [the, man, shoots, a, woman] ; S = [the, man, shoots] ; S = [the, woman, shoots, the, man] ; S = [the, woman, shoots, the, woman] ; S = [the, woman, shoots, a, man] ; S = [the, woman, shoots, a, woman] ; S = [the, woman, shoots] ; S = [a, man, shoots, the, man] ; S = [a, man, shoots, the, woman] ; S = [a, man, shoots, a, man] ; S = [a, man, shoots, a, woman] ; S = [a, man, shoots] ; S = [a, woman, shoots, the, man] ; S = [a, woman, shoots, the, woman] ; S = [a, woman, shoots, a, man] ; S = [a, woman, shoots, a, woman] ; S = [a, woman, shoots]. host-001:~ soini$ more CFG.pl s(c) :- np(a), vp(b), append(a,b,c). np(c) :- det(a), n(b), vp(c) :- v(a), append(a,b,c). np(b), vp(c) :- v(c). det([the]). det([a]). n([man]). n([woman]). v([shoots]). append(a,b,c).
CFG-igenkänning mha append/3 s(c) :- np(a), vp(b), append(a,b,c). np(c) :- det(a), n(b), append(a,b,c). vp(c) :- v(a), np(b), append(a,b,c). vp(c) :- v(c). det([the]). det([a]). n([man]). n([woman]). v([shoots]).?- np([the,woman]). yes?- np(x). X = [the,man]; X = [the,woman]
CFG-igenkänning mha append/3?- np(x). X = [the, man] ; X = [the, woman] ; X = [a, man] ; X = [a, woman].?- trace. true.
CFG-igenkänning mha append/3 [trace]?- np(x). Call: (6) np(_g1563)? creep Call: (7) det(_g1634)? creep Exit: (7) det([the])? creep Call: (7) n(_g1637)? creep Exit: (7) n([man])? creep Call: (7) lists:append([the], [man], _G1563)? creep Exit: (7) lists:append([the], [man], [the, man])? creep Exit: (6) np([the, man])? creep X = [the, man] ; Redo: (7) n(_g1637)? creep Exit: (7) n([woman])? creep Call: (7) lists:append([the], [woman], _G1563)? creep Exit: (7) lists:append([the], [woman], [the, woman])? creep Exit: (6) np([the, woman])? creep X = [the, woman] ;
CFG-igenkänning mha append/3 Redo: (7) det(_g1634)? creep Exit: (7) det([a])? creep Call: (7) n(_g1637)? creep Exit: (7) n([man])? creep Call: (7) lists:append([a], [man], _G1563)? creep Exit: (7) lists:append([a], [man], [a, man])? creep Exit: (6) np([a, man])? creep X = [a, man] ; Redo: (7) n(_g1637)? creep Exit: (7) n([woman])? creep Call: (7) lists:append([a], [woman], _G1563)? creep Exit: (7) lists:append([a], [woman], [a, woman])? creep Exit: (6) np([a, woman])? creep X = [a, woman]. [trace]?- notrace.
Problem med denna igenkännare Den använder sig inte av inputsträngen för att styra sökprocessen Mål som np(a) och vp(b) anropas med oinstantierade variabler Att flytta append/3-målen framåt i regeln är inte en speciellt bra lösning --- det bara senarelägger problemet --- det kommer att uppstå massor av anrop till append/3 med oinstantierade variabler
Differenslistor En mera effektiv implementation kan åstadkommas mha differenslistor Det här är en sofistikerad Prolog-teknik för att representera och bearbeta listor Exempel: [a,b,c]-[ ] [a,b,c,d]-[d] [a,b,c T]-T är lista [a,b,c] är lista [a,b,c] är lista [a,b,c] X-X är den tomma listan [ ]
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). En sats s består av en lista A minus en lista C så att första delen av denna A är en np, och resten av strängen kallar vi för B.
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). B-delen i sin tur ska representera en vp, och det som finns kvar av strängen kallar vi C.
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). Om vi vill att satsen har strukturen s np, vp ska resten C vara [].
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). np(a-c):- det(a-b), n(b-c). En nominalfras np består av en determinerare och ett substantiv (noun). Om np:n representeras som en differenslista A-C, ska A:s början vara determineraren.
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). np(a-c):- det(a-b), n(b-c). När vi plockar bort determineraren, har vi B-delen kvar. Den ska gå att matcha mot ett substantiv, n. C, det som återstår, ska i detta fall vara [].
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). np(a-c):- det(a-b), n(b-c). vp(a-c):- v(a-b), np(b-c). Verbfrasen vp analyseras på samma sätt: om vp:n representeras av differenslistan A-C, ska början av A gå att matcha mot ett verb v.
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). np(a-c):- det(a-b), n(b-c). vp(a-c):- v(a-b), np(b-c). Det som återstår listan B-C ska gå att matcha mot en np. Resten C ska enligt denna regel bli [].
CFG-igenkänning mha differenslistor s(a-c):- np(a-b), vp(b-c). np(a-c):- det(a-b), n(b-c). vp(a-c):- v(a-b), np(b-c). vp(a-c):- v(a-c). Vår lilla grammatik tillåter också en annan form av vp, verbet ensamt (för intransitiva verb). Då ska hela A-C gå att matcha mot detta v.
CFG-igenkänning mha differenslistor det([the W]-W). det([a W]-W). n([man W]-W). n([woman W]-W). v([shoots W]-W). Lexikonet representeras likaså med differenslistor; varje enskilt ord är en lista [ordet W]-W
CFG-igenkänning mha differenslistor s(a-c) :- np(a-b), vp(b-c). np(a-c) :- det(a-b), n(b-c). vp(a-c) :- v(a-b), np(b-c). vp(a-c) :- v(a-c). det([the W]-W). det([a W]-W). n([man W]-W). n([woman W]-W). v([shoots W]-W).?- s(s-[ ]). S = [the,man,shoots,the,man]; S = [the,man,shoots,a,man];.
CFG-igenkänning mha differenslistor?- s(s-[]). S = [the, man, shoots, the, man] ; S = [the, man, shoots, the, woman] ; S = [the, man, shoots, a, man] ; S = [the, man, shoots, a, woman] ; S = [the, man, shoots] ; S = [the, woman, shoots, the, man] ; S = [the, woman, shoots, the, woman] ; S = [the, woman, shoots, a, man] ; S = [the, woman, shoots, a, woman] ; S = [the, woman, shoots] ; S = [a, man, shoots, the, man] ; S = [a, man, shoots, the, woman] ; S = [a, man, shoots, a, man] ; S = [a, man, shoots, a, woman] ; S = [a, man, shoots] ; S = [a, woman, shoots, the, man] ; S = [a, woman, shoots, the, woman] ; S = [a, woman, shoots, a, man] ; S = [a, woman, shoots, a, woman] ; S = [a, woman, shoots].
Sammandrag så här långt... Igenkännaren som använder sig av differenslistor är mycket mera effektiv än den som använder sig av append/3 Den är tyvärr inte lika lätt att förstå rent intuitivt, och det kan vara mödosamt att hålla reda på alla de variabler som representerar de olika differenslistorna. Vi skulle gärna ha en igenkännare som var lika enkel som den första och lika effektiv som den andra. Detta är möjligt mha DCG:or
Definite Clause-Grammatikor Vad är DCG:or? Helt enkelt en användarvänlig notation att skriva grammatikor med som gömmer de underliggande differenslistvariablerna Tre exempel följer...
DCG:or: första exemplet s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots].
DCG:or: första exemplet s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots].?- s([a,man,shoots,a,woman],[ ]). yes?-
DCG:or: första exemplet s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots].?- s(s,[]). S = [the, man, shoots, the, man] ; S = [the, man, shoots, the, woman] ; S = [the, man, shoots, a, man] ; S = [the, man, shoots, a, woman] ; S = [the, man, shoots] ; S = [the, woman, shoots, the, man] ; S = [the, woman, shoots, the, woman] ; S = [the, woman, shoots, a, man] ; S = [the, woman, shoots, a, woman] ; S = [the, woman, shoots] ; S = [a, man, shoots, the, man] ; S = [a, man, shoots, the, woman] ; S = [a, man, shoots, a, man] ; S = [a, man, shoots, a, woman] ; S = [a, man, shoots] ; S = [a, woman, shoots, the, man] ; S = [a, woman, shoots, the, woman] ; S = [a, woman, shoots, a, man] ; S = [a, woman, shoots, a, woman] ; S = [a, woman, shoots].
DCG:or: andra exemplet s --> s, conj, s. s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots]. conj --> [and]. conj --> [or]. conj --> [but]. Vi har tillagt en rekursiv regel i grammatiken... Vilka och hur många meningar kommer den här grammatiken att generera? Vad gör Prolog med denna DCG?
DCG:or: andra exemplet s --> s, conj, s. s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots]. conj --> [and]. conj --> [or]. conj --> [but].?- s([the, woman, shoots, and, the, woman, shoots], S). ERROR: Out of local stack Exception: (1,763,388) s([the, woman, shoots, and, the, woman, shoots], _G1555)? Unknown option (h for help) Exception: (1,763,388) s([the, woman, shoots, and, the, woman, shoots], _G1555)? Unknown option (h for help) Exception: (1,763,388) s([the, woman, shoots, and, the, woman, shoots], _G1555)? alternatives [1,763,388] s([the, woman, shoots, and, the, woman, shoots], _G1569) [1,763,387] s([the, woman, shoots, and, the, woman, shoots], _G1569) [1,763,386] s([the, woman, shoots, and, the, woman, shoots], _G1569) [1,763,385] s([the, woman, shoots, and, the, woman, shoots], _G1569) [1,763,384] s([the, woman, shoots, and, the, woman, shoots], _G1569)...
DCG utan vänsterrekursiva regler s --> simple_s, conj, s. s --> simple_s. simple_s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots]. conj --> [and]. conj --> [or]. conj --> [but].?- s([a, woman, shoots, and, a, woman, shoots], []). true ; false. Did anybody call for a doctor??
DCG utan vänsterrekursiva regler s --> simple_s. s --> simple_s, conj, s. simple_s --> np, vp. np --> det, n. vp --> v, np. vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots]. conj --> [and]. conj --> [or]. conj --> [but].?- s(s, []). S = [the, man, shoots, the, man] ; S = [the, man, shoots, the, woman] ; S = [the, man, shoots, a, man] ; S = [the, man, shoots, a, woman] ; S = [the, man, shoots] ; S = [the, woman, shoots, the, man] ;... S = [a, woman, shoots, a, woman] ; S = [a, woman, shoots] ; S = [the, man, shoots, the, man, and, the, man, shoots...] ; S = [the, man, shoots, the, man, and, the, man, shoots...] ; S = [the, man, shoots, the, man, and, the, man, shoots...] ; S = [the, man, shoots, the, man, and, the, man, shoots...] Action (h for help)? abort % Execution Aborted
DCG:or är inte magi! Lärdom: DCG:or är en bekväm notation, men du kan inte skriva arbiträra kontextfria grammatikor som DCG:or och köra dem utan problem DCG:or är vanliga Prolog-regler men maskerade Så var på din vakt mot vänsterrekursion! Ett flertal av reglerna måste få vara rekursiva, så de (försöker) generera oändliga strängar
DCG:or är inte magi! host-001:~ soini$ more DCG4.pl s --> simple_s. s --> simple_s, conj, s. % ej vansterrekursiv simple_s --> np, vp. % grundstrukturen for en sats np --> det, n. vp --> v, np. % transitiva verb vp --> v. det --> [the]. det --> [a]. n --> [man]. n --> [woman]. v --> [shoots]. conj --> [and]. conj --> [or]. conj --> [but]. % intransitiva verb
DCG:or är inte magi! host-001:~ soini$ swipl -s DCG4.pl % /Users/soini/DCG4.pl compiled 0.00 sec, 23 clauses?- listing. s(a, B) :- simple_s(a, B). s(a, D) :- simple_s(a, B), conj(b, C), s(c, D). simple_s(a, C) :- np(a, B), vp(b, C). conj([and A], A). conj([or A], A). conj([but A], A). np(a, C) :- det(a, B), n(b, C). vp(a, C) :- v(a, B), np(b, C). vp(a, B) :- v(a, B). det([the A], A). det([a A], A). n([man A], A). n([woman A], A). v([shoots A], A). true. Den interna representationen är normal Prologkod med differenslistor.
DCG:or: tredje exempel Vi ska definiera en DCG för ett formellt språk Ett formellt språk är helt enkelt en mängd av strängar Formella språk är objekt som datavetare och matematiker definierar och studerar Naturliga språk är språk som (normalt) används av människor för att kommunicera Vi ska definiera språket a n b n
DCG:or: tredje exempel Vi ska definiera det formella språket a n b n?- s([a,a,a,b,b,b],[ ]). yes?- s([a,a,a,a,b,b,b],[ ]). no s --> []. s --> l,s,r. l --> [a]. r --> [b].
DCG:or: tredje exempel Vi ska definiera det formella språket a n b n?- s(x,[ ]). X = [ ]; X = [a,b]; X = [a,a,b,b]; X = [a,a,a,b,b,b]. s --> []. s --> l,s,r. l --> [a]. r --> [b].
Sammandrag Vi har diskuterat vad grammatikor och kontextfria grammatikor är Vi har introducerat Prolog-tekniken differenslista Vi har visat att differenslistor kan användas för att beskriva grammatikor Definite Clause-grammatikor (DCG) är en användarvänlig Prolog-notation för programmering mha differenslistor