O błędach w polskich liczbach mnogich w środowisku graficznym MATE

13 marca 2017 roku opublikowana została nowa wersja 1.18 środowiska graficznego MATE. Jedną z ostanich poprawek była aktualizacja tłumaczeń dostarczanych przez Transifex. Zwykle jest to dobra wiadomość, ale tym razem w przypadku języka polskiego okazała się małą katastrofą, bo zostały zmienione (niepotrzebnie) zasady obsługi liczb mnogich.

Reguły liczb mnogich

Jak pewnie wszyscy wiemy, zasady obsługi liczb mnogich w języku polskim (podobnie jak w wielu innych językach słowiańskich) są nieco bardziej skomplikowane niż w językach zachodnioeuropejskich, np. w angielskim. Liczebniki główne łączą się z trzema różnymi formami rzeczownika:

  • 1 – liczba pojedyncza – to oczywiste i język polski nie różni się tu od innych języków indoeuropejskich.
  • 2, 3, 4 i wszystkie liczby kończące się na 2, 3, 4 oprócz 12, 13, 14 (np.: 22, 23, 24, 32, 33, 34 itd.) – mianownik liczby mnogiej. Ta grupa liczb jest określana przez niektóre narzędzia do internacjonalizacji jako niewiele (ang. few).
  • Pozostałe liczby (od 5 wzwyż oprócz liczb wymienionych powyżej) – dopełniacz liczby mnogiej. Ta grupa jest czasami określana jako wiele (ang. many).

Obsługa liczb mnogich w pakiecie gettext jest poprawna i kompletna. Jedyne, co musimy zrobić, to podać poprawne dla danego języka reguły liczb mnogich w nagłówku właściwego pliku *.po. To zadanie powinno być wykonane jednorazowo, te same reguły powinny być używane we wszystkich tłumaczeniach na ten sam język, ponieważ zasady gramatyki nie zmieniają się często; właściwie możemy spokojnie założyć, że nie zmieniają się nigdy. Zwykle w języku polskim używamy następującej reguły:

"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"

To wyrażenie nie jest proste, ale też nie jest bardzo skomplikowane. Jest dokładnie takie, jakie musi być, żeby opisać wymagania języka polskiego.

Nadchodzi katastrofa

13 marca poprawka aktualizuąca tłumaczenia dostarczane przez Transifex zmieniła zasady konstruowania liczb mnogich w języku polskim. Nowa formuła jest następująca:

"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>=14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"

To dopiero jest skomplikowane, prawda? Przyjrzyjmy się co jest nie tak z tym wyrażeniem:

  • stwierdza, że język polski wymaga 4 form do poprawnej obsługi liczb mnogich, co oczywiście jest nieprawdą;
  • jest niepotrzebnie skomplikowane: jeśli pierwsza część mówi, że wyrażenie z liczbą n==1 należy do grupy 0, nie ma potrzeby sprawdzać w dalszej części, że n!=1;
  • złożoność wyrażenia nie tylko grozi błędami, ale faktycznie do nich prowadzi: druga grupa obejmuje wszystkie liczby kończące się na 2, 3, 4 (poprawnie) oprócz 12 i 13 (błąd – 14 też powinno być wyłączone z tej grupy);
  • wynik 3 jest nieosiągalny, co jest słuszne, ale wprowadza tłumaczy w błąd.

Jako że MATE to duży projekt, składający się z wielu aplikacji (np. menedżer plików Caja, edytor tekstu Pluma itp.), ten sam problem dotyczy każdej aplikacji, wchodzącej w skład projektu.

Ciężkie do naprawienia

Błąd został zgłoszony programistom MATE tak szybko, jak to możliwe. Ci jednak odpowiedzieli, że źródłem błędu jest Transifex: nie ma sensu poprawiać go w kodzie źródłowym MATE, bo następna aktualizacja tłumaczeń zamaże poprawkę.

Niestety, zgłaszanie błędu Transifeksowi nie jest proste. Serwis ten nie ma Bugzilli ani żadnego innego systemu obsługi błędów. Mimo to paru osobom udało się skontaktować z zespołem Transifeksa. W odpowiedzi usłyszeli, że Transifex skopiował zasady dotyczące liczb mnogich z bazy danych CLDR, która wymienia 4 formy liczb występujące w języku polskim, chociaż jednocześnie przyznali, że zaliczenie liczby 14 do grupy niewiele było ich błędem i poprawili to po swojej stronie. W miarę jak projekt MATE będzie aktualizował tłumaczenia pobierając je z Transifeksa, kolejne aplikacje będą poprawnie obsługiwać liczbę 14. Część z nich została już niedawno zaktualizowana, poprawka jest częścią wersji deweloperskiej 1.19.

Co na ten temat mówi CLDR

Przyjrzyjmy się co na temat liczb mnogich w języku polskim mówi baza CLDR. Faktycznie, podaje ona 4 grupy i wspomina o tajemniczym parametrze v, który ma coś wspólnego z ułamkami, bo przykłady użycia zawierają właśnie formę ułamkową (1,5 miesiąca). Jednak pakiet gettext obsługuje tylko liczby całkowite, dlatego przypadki ułamkowe powinniśmy odrzucić całkowicie.

Trudno jest znaleźć dokumentację opisującą co to jest ten parametr v, ale jak już uda nam się ją znaleźć, możemy przeczytać, że oznacza on ilość widocznych cyfr po przecinku, z zerami na końcu (ang. number of visible fraction digits in n, with trailing zeros), przy czym n jest po prostu liczbą, która ma określać liczbę rzeczownika (pojedynczą lub mnogą).

Inne języki

Również w innych językach CLDR podaje oddzielne formy dla liczb ułamkowych: czeskim, manx, rosyjskim, słowackim i ukraińskim. Z kolei w niektórych innych językach (bośniackim, chorwackim, filipińskim, dolno- i górnołużyckim, macedońskim) reguły są jeszcze bardziej skomplikowane: liczby ułamkowe łączą się z różnymi formami, normalnie przeznaczonymi dla różnych grup liczb całkowitych.

Cała ta sytuacja powinna być ostrzeżeniem dla innych języków, że ich reguły w tłumaczeniach obsługiwanych przez Transifex także mogą być błędne. Jednak po dokładniejszym zbadaniu kodu źródłowego projektu MATE nie znaleziono żadnych zmian w zasadach liczb mnogich w innych językach.

Wnioski

Okazuje się, że automatyczne kopiowanie reguł dotyczących liczb mnogich z CLDR nie jest dobrym pomysłem.

Tłumacze i koordynatorzy zespołów tłumaczy powinni się upewnić, że ich reguły liczb mnogich są nadal poprawne.

Transifex i inne platformy zarządzania tłumaczeniami nie powinny kopiować reguł dotyczących liczb mnogich z CLDR bez ich dokładnej analizy. Najlepiej skonsultować się z zespołami tłumaczy i korzystać z już istniejących reguł.

CLDR powinien uprościć opis reguł dotyczących liczb mnogich i ułatwić dostęp do ich dokumentacji.