Wyszukiwarka drzew analizy ze Składnicy Frazowej

##### Wyszukiwarka

Poniżej znajdują się podstawowe instrukje korzystania z aplikacji. Strona ta pozwala na wyszukiwanie lasów, drzew, poddrzew czy pojedynczych węzłów spełniających zadane warunki wewnątrz korpusu lasów analizy składniowej w projekcie Składnica Frazowa. Korpus składa się z wyników analizy kilkunastu tysięcy zdań języka polskiego, gdzie wszystkie lasy razem zawierają ponad milion węzłów (jednostek składniowych na różnych poziomach).

Wyszukiwanie odbywa się przez wpisanie zapytania w polu na górze, i wysłanie zapytania przyciskiem „Szukaj”. Zapytania należy formułować w specjalnym języku, który pozwala wyrazić różne typy wymagań odnośnie szukanego zbioru. Język ten opisany jest poniżej; przejdź od razu do następnej sekcji aby wypróbować działanie wyszukiwarki.

Po chwili od wysłania zapytania serwer zwróci wyniki wyszukiwania, które będziemy mogli przeglądać w wygodnej formie. Czas potrzebny na otrzymanie wyniku jest oczywiście zależny od samego zapytania i może wahać się od ułamka sekundy do trzydziestu sekund. Zależność ta jest trudna do odgadnięcia ze względu na różne stopnie trudności sprawdzenia zachodzenia relacji odpowiadających operatorom języka, (nie)zależności między nimi i istnienie lub nieistnienie indeksów dla danego atrybutu czy zbioru atrybutów po stronie serwera. Serwer zwraca za każdym razem do 20 wyników, traktując jako jeden wynik zdanie, którego las analizy zawiera conajmniej jeden podzbiór węzłów pasujący do zapytania. Dla każdego znalezionego zdania podawane są wszystkie takie zbiory, przy czym może być ich bardzo wiele. Interfejs przeglądarki pozwala poruszać się po liście wszystkich pasujących zdań przechodząc do kolejnych lub poprzednich 20 wyników wyszukiwania. Jeśli serwer nie jest w stanie odpowiedzieć na zapytanie w przeciągu 30 sekund, przerywa wyszukiwanie i zwraca informację o tym fakcie.

Przy przeglądaniu wyników widoczna jest również liczba wszystkich zdań pasujących do zapytania. Jeśli ocenimy, że jest ona zbyt duża, prawdopodobnie wygodniej będzie przeformułować nasze zapytanie uściślając je tak, aby interesujące nas wyniki mieściły się na pierwszej stronie, zamiast przeglądać całą listę analizując struktury zdań samemu. Szukanie igły w stogu siana jest ostatecznie głównym zadaniem wyszukiwarki.

Jeśli nasze zapytania zajmują serwerowi zbyt długo, również warto spróbować je przeformułować.

Kolejność zwracanych wyników nie jest zdefiniowana.

Należy zauważyć, że korpus zawiera wszystkie drzewa analizy pasujące do pewnego słownika i pewnej gramatyki, a więc zdania poprawne gramatycznie i potencjalnie niepoprawne logicznie. Oprócz tego dla każdego zdania zawiera informację o tym, czy wśród podanych drzew znajduje się struktura poprawna logicznie, i w tych przypadkach również wskazuje na dokładnie jedną z takich struktur. Wyszukiwarka wykorzystuje tą informację aby opcjonalnie ograniczyć wyszukiwanie do drzew poprawnych, lub (w przeciwnym wypadku) oznaczyć wyniki niezawierające poprawnej struktury (a zawierającej tylko struktury niepoprawne) czerwonym znakiem X przy wyświetlaniu listy wyników.

##### Język zapytań

Kryteria wyszukiwania podawane są specjalnym językiem, jak w wyszukiwarkach internetowych. Język ten pozwala zadawać całkiem skomplikowane warunki odnoszące się do atrybutów węzłów w lasach analizy i relacji pomiędzy węzłami w jednym drzewie lub lesie. Kosztem tego jest mało intuicyjna składnia języka, co wymaga od jego użytkownika zapoznania się z opisem tej składni.

Struktura oparta jest na języku TIGERSearch, z projektu TIGER, który używany jest przez inną wyszukiwarkę drzew w treebankach. Kompatybilność z TIGERSearch nie została sprawdzona, natomiast w niniejszej wyszukiwarce świadomie wprowadzono kilka modyfikacji w następujących celach:

- przystosowanie języka do wyszukiwania w pełnych lasach analizy, a więc strukturach mogących zawierać wiele drzew i częściową informację o logicznej poprawności drzew -- zobacz szczegółowe informacje w opisie projektu Składnica Frazowa. TIGERSearch zaprojektowano do wyszukiwania w korpusach pojedynczych drzew analizy.
- wzbogacenie zbiorów dostępnych operatorów o nowe przydatne relacje i dodanie uproszczonej składni dla niektórych częstych zapytań.

Wierzchołkami lasów analizy w korpusie są węzły reprezentujące jednostki składniowe. Węzły nieterminalne posiadają listy węzłów potomnych odpowiadające różnym interpretacjom danej jednostki przez podział na jednostki niższego poziomu. Oprócz tego węzeł nieterminalny ma swoją kategorię składniową i zbiór atrybutów. Lista atrybutów i dozwolonych wartości zależy od kategorii jednostki.

Najprostsze zapytanie będzie odnosiło się do pojedynczego węzła, a więc wyszuka wszystkie węzły posiadające określone właściwości. Wyrażenie sprawdzające zachodzenie pewnej własności może składać się w najprostszym przypadku z porównania pewnego atrybutu węzła z podaną wartością:

    category = "zdanie"

    category != "zdanie"

Dla uproszczenia atrybuty składniowe, kategoria i kilka innych własności węzła traktowane są w ten sam sposób. Po lewej stronie operatora porównania wartości podajemy nazwę prównywanego atrubytu, po prawej specyfikację interesujących nas wartości.

Najważniejsze atrybuty wierzchołków to:

- „cat” lub „category” - kategoria składniowa nieterminala
- „osoba”, „czas”, „ink”, „neg”, „liczba”, „klasa”, „stopień”, „aspekt”, „tryb” itd. - atrybuty składniowe nieterminala. Ich obecność jest zależna od kategorii wyrażenia.
- „orth” - odcinek tekstu reprezentowany przez terminal (forma oryginalna wyrazu)
- „base” - forma podstawowa wyrazu reprezentowanego przez terminal
- „tag” - etykieta terminala zawierająca część mowy i ewentualne atrybuty składniowe

I rzadziej używane: „id” lub „nid”, „treeid”, „depth”, „children”, „rules”, „f”, „from”, „to”, „terminal”, „sel”.

Zamiast podawać konkretny ciąg znaków w cudzysłowie możemy zdefiniować zbiór pożądanych wartości używając wyrażeń regularnych ograniczonych znakami "/" lub łącząc kilka zbiorów operatorami koniunkcji "&", alternatywy "|". Obsługa wyrażeń regularnych jest w dużej mierze zgodna ze standardami POSIX, ale pasujący podciąg musi być równy całości porównywanego ciągu, a więc tak, jakby podane wyrażenie zaczynało się od ^ i kończyło $.

    orth = /.*ąc/

    category = "zdanie" | "wypowiedzenie" | /p.*/

    base = /.*ć/ & /b.*/

Można też podać dopełnienie zbioru i uściślać definicje za pomocą nawiasów.

    category = ((!"zdanie") & (!"wypowiedzenie"))

    category = (!("zdanie" | "wypowiedzenie"))

Atrybuty „terminal” i „sel” mają wartości binarne ("dany węzeł jest terminalny" i "dany węzeł należy do drzewa wybranego jako poprawna interpretacja zdania"), a więc można ich używać jako predykatów, bez użycia operatora porównania.

Predykaty łączyć można operatorami logicznymi & i |, negować i grupować nawiasami:

    category = "zdanie" & sel & !(aspekt = "nd")

Wartość porównywanego atrybutu można przypisać zmiennej, tak aby porównać ją z wartością innego atrybutu, tego samego lub innego wierzchołka w zapytaniu. Składnia deklaracji zmiennej wygląda następująco:

    atrybut = #zmienna: zbiórwartości

Następnie deklarując inny zbiór wartości możemy użyć ciągu

    #zmienna

, który będzie odpowiadał wartości naszego atrybutu. W następujący sposób wymagamy aby base i orth miały identyczną wartość:

    base = #podstawowa: /.*szny/ & orth = #podstawowa

Jest to jeden z trzech typów zmiennych dostępnych w języku TIGERSearch.

Mając już wyrażenie określające interesujące nas własności wierzchołka, umieszczamy je w nawiasach kwadratowych aby uzyskać zapytanie w języku TIGERSearch:

    [ category = "zdanie" ]

Do takiego zapytania pasują wszystkie wierzchołki o zadanej kategorii składniowej i należące do drzewa wybranego jako poprawne, a więc tak, jakby w specyfikacji wierzchołka był predykat

    sel

. Wynikami zapytania będą zbiory składające się z jednego wierzchołka.

Aby zapytać o wszystkie wierzchołki, również te nienależące do wybranego drzewa w lesie, musimy użyć podwójnych nawiasów:

    [[ category = "zdanie" ]]

Poprzednie zapytanie było równoznaczne z

    [[ category = "zdanie" & sel ]]

Nawiasy mogą być puste ([] lub [[]]) co będzie oznaczało dowolny wierzchołek.

Również specyfikacje wierzchołków możemy łączyć operatorami i nawiasami w bardziej skomplikowane wyrażenia, które będą wybierały z korpusu lasy posiadające węzły o konkretnych właściwościach. Wynikami takich zapytań będą zbiory tylu węzłów, ile wyspecyfikowano w zapytaniu. Zapytanie o N węzłów może więc wyprodukować aż M^N wyników dla jednego lasu o M wierzchołkach.

Uwaga: negacja wierzchołka wybiera las posiadający wierzchołek niepasujący do zadanego kryterium, nie zaś las niezawierający wierzchołka pasującego do kryterium.

Zmienne zdefiniowane wewnątrz specyfikacji jednego wierzchołka mogą być użyte poza nią. Oprócz zmiennych odnoszących się do konkretnych wartości (ciągów znaków), możemy zmiennej przypisać cały predykat. Pozwala to na zdefiniowanie predykatu w jednym miejscu zapytania i wykorzystaniu go w specyfikacjach kilku wierzchołków. Nie zwiększa jednak mocy wyrażeń języka. Składnia definicji oraż użycia takich zmiennych jest podobna jak w pierwszym przypadku, z tym, że deklaracja poprzedza cały predykat, a nie zbiór wartości atrybutu.

##### Relacje wierzchołków

Ważnym elementem języka zapytań są relacje na wierzchołkach, dzięki którym możemy wyszukać specyficzne struktury składniowe. Zdefiniowane zostały następujące relacje. Ich argumentami są specyfikacje wierzchołków (poniżej A, B, C..).

Relacja | Zapis |
--- | --- | ---
bezpośredni nadrzędnik | A > B | A jest rodzicem B w pewnym drzewie
nadrzędnik | A >* B | B należy do pewnego poddrzewa A (B != A)
nadrzędnik z etykietą | A >R B | w pewnym drzewie A jest rodzicem B, który wyprowadzono regułą R
nadrzędnik | A >N B | B należy do pewnego poddrzewa A, ścieżka A-B ma długość N
nadrzędnik | A >M,N B | B należy do pewnego poddrzewa A, ścieżka A-B ma długość między M i N
bezpośrednie poprzedzanie | A . B | A poprzedza B (inaczej fraza B zaczyna się tam gdzie kończy się A)
poprzedzanie | A .* B | B występuje po A
poprzedzanie | A .N B | B zaczyna się N wyrazów od końca A
poprzedzanie | A .M,N B | B zaczyna się między M a N wyrazów od końca A
lewy terminal | A >@l B | B jest terminalem w pewnym poddrzewie A i żaden inny terminal go nie poprzedza
prawy terminal | A >@r B | B jest terminalem w pewnym poddrzewie A i nie poprzedza żadnego innego terminala
centralny terminal | A >@c B | B jest terminalem w pewnym poddrzewie A i istnieje ścieżka z A do B prowadząca gałęziami głównymi
rodzeństwo | A $ B | A i B mają w pewnym drzewie wspólnego rodzica
rodzeństwo i poprzedzanie | A $.* B | A i B mają w pewnym drzewie wspólnego rodzica i A występuje przed B
korzeń | root(A) | A jest korzeniem lasu
pokrewieństwo | same_tree(A, B) | istnieje drzewo zawierające A i B

Tak jak specyfikacja wierzchołka, relacja może występować na najniższym poziomie wyrażenia i kilka relacji może być połączonych operatorami w większe wyrażenie.

Te z powyższych operatorów, które zapisane są infiksowo można również stosować dla więcej niż dwóch węzłów stosując zapis:

    A r B r C

gdzie r jest operatorem, przykładowo

    A > B > C

Efekt takiego wyrażenia jest taki jak A > B & D > C, gdzie B i D są tym samym węzłem. W związku z tym wynik wyszukiwania zawiera tylko trzy węzły.

Inna, bardziej uniwersalna konstrukcja takiego zapytania wykorzystuje trzeci rodzaj zmiennych, takich, którym przypisany jest wierzchołek. Tym razem deklaracja zmiennej poprzedza specyfikację węzła, a sama zmienna może zostać użyta w relacjach z innymi węzłami. Powyższe zapytanie przyjmuje wtedy postać:

    A > #b: B & #b > C

Bardziej kompletny opis języka zapytań TIGERSearch znajduje się w instrukcji do wyszukiwarki TIGERSearch (HTML, PDF, rozdział III), a jego pełna formalna specyfikacja dostępna jest w:

- König, Esther and Lezius, Wolfgang (2003): The TIGER language - Chapter VII - Appendix A - Description Language for Syntax Graphs. Formal Definition. Technical report, IMS, University of Stuttgart.