Zakręcone polskie ogonki

Twórcy komputerów nie mieli ogonków w alfabecie.

To wiele wyjaśnia. To bardzo utrudnia tym, którzy mają ogonki, czyli większości ludzkości. W alfabecie polskim jest i tak stosunkowo prosto, bo mamy niewiele ogonków. Chociaż sobie oczywiście utrudniliśmy życie, niepotrzebnie tworząc za dużo stron kodowych. Utrudnił nam też Microsoft, bo w jego produktach są dwie strony kodowe używające polskich znaków: stara, jaszcze z MS-DOS’a cp852 – ciągle używana, nie wiadomo po co, chyba żeby utrudnić, w poleceniach konsoli i windows1250 – używana w dokumentach i programach działających w Windowsach. Tu leży mój problem: Postgres na Windows umie użyć prawidłowo tylko strony kodowej 1250. Co prawda powołując bazę danych można zdefiniować jej inny standard kodowania, np. obecnie najchętniej stosowany utf-8, ale cóż z tego, skoro wprowadzane znaki mogą być kodowane tylko w win1250? Ta sama baza uruchomiona pod Linuxem będzie zachowywała się o wiele lepiej dzięki temu, że Linux ma możliwość powoływania i przełączania pomiędzy różnymi lokalizacjami: można utworzyć lokalizację pl_PL.iso-8859-2 (zgodną z Polską Normą) lub lokalizację pl_PL.utf-8 (zgodną ze współczesnymi standardami) i do tego dostosować kodowanie znaków w bazie danych. Niestety pod Windows istnieje tylko jedna słuszna strona kodowa, niezgodna z czymkolwiek innym. Mam więc do wyboru:

  • pozostać przy Windowsach, Postgresie i stronie 1250
  • przejść na Linuxa, wtedy mogę w Postgresie zastosować kodowanie utf-8
  • pozostać przy Windowsach i szukać jakiejś innej bazy danych, która umie porozumieć się z aplikacją kodując znaki w utf-8
  • szukać jeszcze innych rozwiązań

Czego sobie i Państwu życzę.

Obrazki nie mają nic wspólnego z treścią.

Powoli do aplikacji

Pewien szkielet aplikacji już poczyniłem. Kod źródłowy jest na GitHubie. Oczywiście ta aplikacja nic szczególnego jeszcze nie robi: wyświetla pole tekstowe, w które można coś wpisać i przycisk ‚Tłumacz’, który można kliknąć. Po kliknięciu pod spodem wyświetla się jakiś napis. Szczytne założenie jest takie, że po wpisaniu tekstu angielskiego i kliknięciu wyświetli się jego polskie tłumaczenie.

Oczywiście trzeba pracę podzielić na jakieś etapy. Wymyśliłem sobie, żeby najpierw zająć się rzeczownikami. Trzeba zaimplementować tablice deklinacyjne wspomniane poprzednio i wprowadzić do bazy danych przynajmniej po kilka rzeczowników z każdej grupy. Już to będzie niezłą zabawą. Trzeba też wymyślić, jak rzeczowniki mają być trzymane w bazie danych. Jeden z problemów polega na tym, że jeden rzeczownik angielski najczęściej można przetłumaczyć na kilka rzeczowników polskich i jak tu wybrać ten właściwy? Tu jest jeden z pogrzebanych psów. W każdym razie pomysł mam taki, że słowo angielskie otrzymuje swój numer, również rzeczownik polski ma swój numer. Utworzę tablicę pośrednią łączącą rzeczowniki i tam wpiszę wszystkie połączenia. Jak z tego skorzystać, to już jest inna bajka.

Obrazki nie mają nic wspólnego z treścią.

Zmaganie

Zmagam się ze sobą. Pomysł uruchomienia tego bloga i napisania aplikacji tłumaczącej powstał w czasie, kiedy miałem dobry nastrój, byłem pełen energii, optymizmu, wiary w siebie i swoje umiejętności. Teraz nadszedł czas Wielkiego Postu, czas modlitwy, wyrzeczeń, rekolekcji, katechez, refleksji nad swoim życiem i nad pomysłami na jego wypełnienie. O ile poprzednio zajmowało mnie to bardzo, o tyle teraz przestałem trochę myśleć o superautomatycznym tłumaczu, a zająłem się innymi, zapewne ważniejszymi, sprawami. Ciągle jednak chcę zrealizować mój zamiar, nie jest on chyba taki całkiem głupi, tyle że obecnie mam pewien zastój w tej kwestii. Mam nadzieję, że nie mi się całkiem nie odmieni i nie zrezygnuję.

Porażka

Miałem trochę czasu w weekend, więc chciałem przestać teoretyzować, a zacząć coś pisać. Może nie jest to zbyt poprawne metodologicznie, bo według tej najbardziej klasycznej teorii najpierw trzeba przeprowadzić analizę, potem wykonać projekt techniczny, a samą robotę kodowania zostawić na koniec. Tak się buduje domy, samochody i inne tego typu wytwory. Niektórzy tak budują oprogramowanie i nawet ma to swoją namaszczoną metodologię. Jednak z psychologicznego punktu widzenia takie podejście jest całkowicie niepoprawne. Normalny człowiek chce jak najszybciej widzieć jakiś efekt, niekoniecznie finalny, ale program robiący cokolwiek, który można będzie potem rozwijać i poprawiać. Zwykle takie podejście prowadzi do powstawania konstrukcji obarczonych wieloma grzechami wieku dziecięcego, które potem trzeba poważnie zmieniać, przebudowywać, ulepszać filozofię i ogólnie mnóstwo potem z tym zachodu, bo realizatorzy uczą się na błędach, których nie popełniliby, gdyby przeprowadzili porządną analizę i sprawdzili, które koncepcje mają ręce i nogi, a które są ślepymi zaułkami, gdzie najlepiej byłoby w ogóle nie zaczynać. Czasem okazuje się, że taki zaułek jest całkiem sporą ulicą i wiele pary poszło w ten gwizdek. Ale praktyka rewolucyjna, jak to mawiali w dawnych czasach, wskazuje na co innego: lepiej zrobić dzisiaj coś, co działa i daje jakieś wyniki, niż martwić się na zapas, że te wyniki są mizerne i trzeba będzie dużą część przebudować od podstaw.

W każdym razie nie udało mi się. Nie dałem rady uruchomić nawet najprostszej aplikacji, choć byłem blisko. Prawie cały czas i energię zmarnowałem na szukanie rozwiązań błędów z serii Serwer potrzebował zbyt wiele czasu na odpowiedź albo Połączenie zostało odrzucone. Porażka.

Trzeba zacząć od początku

Początek jest taki, że mam tekst angielski na wejściu. Dość łatwo można go podzielić na słowa, ale w tym momencie łatwość się kończy. W przeciwieństwie do języka polskiego, w angielskim to samo słowo może być zarówno czasownikiem, rzeczownikiem, przymiotnikiem, a w niektórych przypadkach również przysłówkiem. Czyli najpierw trzeba stwierdzić, z jaką częścią mowy mamy do czynienia, to już jest prawie połowa sukcesu, bo dalsze postępowanie dla polskich słów silnie zależy od tego ustalenia. Weźmy przykład z bloga mojego ulubionego programisty:

That’s the natural evolution of things and that’s how you can build this complex software.

Czyli: to jest naturalna ewolucja rzeczy i [to jest] jak [ty] możesz zbudować to skomplikowane oprogramowanie.

Podmiot i orzeczenie na początku – specjalnie dobrałem taki przykład, ale chwilowo tego się trzymam, potem:

the – samo w sobie po polsku nic nie znaczy, ale wskazuje, że następny będzie rzeczownik lub przymiotnik z rzeczownikiem; w naszym przykładzie natural może być tylko przymiotnikiem lub przysłówkiem, więc rzeczownikiem jest evolution

of – też samo w sobie nic nie znaczy, ale wskazuje podobnie, że następny rzeczownik lub zestaw przymiotnik-rzeczownik będzie w dopełniaczu

and – podobnie jak w polskim rozdziela dwa zdania równorzędne, czyli cała zabawa zaczyna się od nowa, czyli podmiot i orzeczenie, tutaj w jednym podwójnym słowie i tu uwaga: od how zaczyna się następne zdanie. To dlatego bezpośrednie tłumaczenie brzmi tak nienaturalnie, bo w języku polskim nie ma takiej konstrukcji. Ten problem trzeba jakoś rozwiązać, wtedy jakość tłumaczenia będzie o wiele lepsza.

Dalsza część przykładowego zdania jest w miarę łatwa. Jedynym problemem jest niewypisywanie oczywistych, powtarzających się słów i zaimków wyrażających podmiot, których w polskim zwykle się nie mówi, bo wskazuje na nie forma czasownika i konstrukcja zdania.

Strona techniczna

Stronę techniczną tłumaczeń postanowiłem zrealizować w Javie. Na pewno nie dlatego, że jestem mistrzem tego języka. W tej chwili nawet trudno mówić o języku, raczej jest jest to ogromy zbiór bibliotek, standardów, technologii, wzorców projektowych, środowisk wszelakiego typu i wielu innych pomysłów, jak choćby nowych języków programowania. Samych trzyliterowych skrótów oczywistych dla wtajemniczonych jest co najmniej kilkanaście i w dodatku nie wszystkie zaczynają się na J, a są jeszcze skróty czteroliterowe i dłuższe oraz przeróżne nazwy własne. Trzeba po prostu coś wybrać, bo argumentów o wyższości javowej Wielkanocy nad Bożym Narodzeniem znajdzie się co niemiara. Wybrałem jako podstawowy framework, czyli szkielet, czy też może szablon albo kontener – Springa. Zbiera wiele pozytywnych opinii i wydaje się być odpowiednim zarówno dla małych projektów, jak i zaawansowanych systemów. Jako interfejs webowy wymyśliłem sobie technologię JSF (JavaServer Faces). JSF nie jest bezpośrednio związane ze Springiem, ale powala tworzyć strony za pomocą zestandaryzowanych tagów, co mi bardzo odpowiada, zwłaszcza, że interfejs mojej aplikacji nie będzie zbyt wymyślny i nie na nim będę się koncentrował. A to, że Spring bardzo ładnie współpracuje z JSF, już przećwiczyłem. Jako bazę danych wybrałem Postgresa, żeby nie faworyzować rozwiązań komercyjnych. Znowu: moja znajomość Postgresa jest o wiele mniejsza niż Oracle’a, ale chodzi mi właśnie o korzystanie z możliwie najbardziej niezależnego oprogramowania.

Ciągle o programiście

  • I’m a programmer – jestem programistą
  • You’re a programmer – jesteś programistą
  • He is a programmer – on jest programistą
  • We’re programmers – Google: Jesteśmy programistów
  • You are programmers – jesteście programistami
  • They are programmers – są programistami (również programistkami, zależnie od wcześniejszego kontekstu)

Co za bogactwo możliwości. Chyba można wstępnie założyć, że zdanie oznajmujące w angielskim zaczyna się od pary podmiot-orzeczenie. W każdym razie to by bardzo pomogło. Tu jednak mamy inny problem: złączeń podmiotu z orzeczeniem, jeśli podmiot jest wyrażony zaimkiem. Może zresztą to nie jest jakiś wielki problem: wystarczy zapamiętać kilka takich złączeń i tłumaczyć je bezpośrednio. W każdym razie rzeczownik po być jest zawsze w narzędniku, więc tylko trzeba jakoś przetransponować tablice deklinacyjne. Według tabeli deklinacyjnej programista jest odmieniany jak artysta, czyli jego deklinacja jest oznaczona jako 36 m1. W zasadzie dla rzeczowników wystarczy zaimplementować tę tabelkę i problem rozwiązany. Po prostu w bazie danych trzeba trzymać dla każdego rzeczownika określenie jego deklinacji, zgadywać z kontekstu zdania liczbę i przypadek (np. I’m talking about the programmer), robić odpowiednie złączenie z ewentualną modyfikacją tematu (programista – programiście) i już. Można jeszcze trzymać w bazie, obok deklinacji, modyfikator tematu, to już będzie super prosto.

To było na zgryźliwie.

Infrastruktura

Zacząłem myśleć o technicznej stronie tłumaczenia. Wymyśliłem sobie, że dobrze by było udostępnić aplikację tłumaczącą w internecie, tak żeby każdy mógł łatwo wpisać jakiś tekst angielski i uzyskać polskie tłumaczenie. No z tym polskim, to może trochę przesadziłem, zwłaszcza w początkowej fazie. Głównie chodzi mi o to, że jak program jest publicznie dostępny, to po pierwsze daje silniejszą motywację do jego rozwoju, a po drugie pozwala uzyskać znaczną liczbę materiału do przemyśleń i wnoszenia poprawek. Zawsze użytkownik myśli inaczej niż deweloper, ma inne potrzeby i oczekiwania, co pozwala dostosować aplikację do rzeczywistych warunków używania.

Powstaje problem gdzie i jak udostępnić aplikację. Można uruchomić własny serwer i udostępnić w sieci. Takie rozwiązanie ma dla mnie jednak szereg wad. Po pierwsze potrzebny jest serwer. Najtańsze rozwiązanie serwerowe, czyli komputer, który ma serwerową płytę główną, serwerowy procesor i pamięć ECC (Error Correction Code) oraz serwerowe dyski, to koszt rzędu 10 tysięcy złotych. Poza tym taki serwer trzeba gdzieś postawić i zasilać, przecież nie postawię go w dużym pokoju… Po drugie musiałbym mieć łącze internetowe ze stałym adresem IP (Internet Protocol). Same kłopoty. Rozwiązaniem alternatywnym jest udostępnienie aplikacji na jakimś serwerze publicznym, jak to się obecnie ładnie mówi – w chmurze. Istnieje kilku dostawców takich rozwiązań, ale każde z nich jest trochę inne: ma inne warunki techniczne korzystania, inną infrastrukturę, inne warunki opłat, poza tym trzeba opanować pewną wiedzę związaną z publikowaniem aplikacji, dla każdego dostawcy inną. Muszę mieć na to trochę czasu do zastanowienia, wypróbowania i podjęcia decyzji. Na pewno o tym napiszę.

Gramatyka

Zajrzałem na stronę o gramatyce języka polskiego napisanej przez Grzegorza Jagodzińskiego. Wiedza tam zawarta niewątpliwie musi być podstawą programu tłumaczącego. Właśnie taki jest cel tego bloga i projektu: żeby tłumaczenie było przynajmniej gramatycznie poprawne. Będę bardzo zadowolony, jeśli chociaż w jakimś stopniu osiągnę ten cel zamiar.

Generalnie mamy dziesięć tradycyjnych polskich części mowy, o takich mnie uczyli w szkole: rzeczowniki, przymiotniki, liczebniki, zaimki, czasowniki, przysłówki, przyimki, spójniki, wykrzykniki i partykuły. Tego będę się trzymał, przynajmniej na początku, tworząc klasy i algorytmy. Spróbuję dla wyrazów angielskich określić, jaką polską częścią mowy jest dany wyraz i postąpić dalej według schematu dla tej części mowy: znaleźć czas, osobę i tryb dla czasownika, liczbę i przypadek dla rzeczownika, przymiotnika, zaimka czy liczebnika, albo stopień stopniowania dla przysłówka czy przymiotnika. Oczywiście będzie z tym sporo zabawy, być może najciekawszej, bo tu aż roi się od wyjątków, nieregularności, odmienności i pokrętności. Wystarczy spojrzeć na tabelkę z nietradycyjną klasyfikacją części mowy, żeby znaleźć tam np. predykatyw albo partykułę wątpiącą, czy też modulant afektujący.

Magia wyrazów

Bardzo podoba mi się rozróżnienie na słowa i wyrazy z poprzedniego wpisu. Słowa mogą być w prosty sposób wydzielone z wprowadzonego tekstu i tu zaczyna się pierwsza zasadnicza część tłumaczenia – przekształcanie w wyrazy. W języku polskim jest to chyba trochę prostsze do przeprowadzenia, bo przeważająca część wyrazów jest jednosłowna. Jako wyjątki przychodzą mi do głowy czasowniki zwrotne (ubierać się), czas przyszły (będę pisał) i tryb przypuszczający form bezosobowych (zostało by) – też czasowniki. W angielskim jest z tym trochę gorzej. Można naliczyć co najmniej kilka grup wyrazów, które są wielosłowne, na przykład bezokoliczniki (to make), rzeczowniki (a word, the word), czasowniki złożone (to wake up), czasy czasowników (I have been), odmiana rzeczowników (wielka mi odmiana – jeden dodatkowy przypadek, np. of the singleton). Pewnie można by wymienić jeszcze parę innych, ale już te wymagają napisania dość inteligentnego analizatora.

Doszedłem chyba w końcu do sedna sprawy. Zadanie sprowadza się do stworzenia słownika, który przekształca wyrazy angielskie w odpowiednie wyrazy polskie. Niestety owa odpowiedniość jest najtrudniejsza do zrealizowania w automatyczny sposób. Zresztą ludzie też mają z tym problemy, chociaż nikt za bardzo nie chce się przyznać do tego, że tłumacząc z angielskiego zazwyczaj kaleczy polską mowę, bo to po prostu nie jest łatwe. Dlatego nie stawiam sobie zadania stworzenia prawdziwego tłumacza angielsko-polskiego, a jedynie translatorka, który zachowuje poprawność polskiej gramatyki, co jest i tak dużym wyzwaniem.

Oczywiście pozostaje kwestia bazy danych – zbiornicy słów i wyrazów. Nie mam zamiaru zbytnio zaprzątać sobie tym głowy. Oczywiście jakaś baza danych jest potrzebna, ale dla potrzeb tego projektu wystarczy, aby liczyła sobie kilkaset wyrazów angielskich i ich polskich odpowiedników. Taką bazę można sporządzić ręcznie pisząc odpowiednią aplikację. To podejście pozwoli mi też przyjrzeć się każdemu wyrazowi, wyszukać wyjątki, przypadki szczególne, szukać rozwiązań, uogólnień itd.