Skip to content

Commit

Permalink
[uk] token agrement rule improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
arysin committed May 28, 2019
1 parent 26fe3e5 commit 7583dd2
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 26 deletions.
Expand Up @@ -295,22 +295,22 @@ public static boolean isException(AnalyzedTokenReadings[] tokens, int i,
return true;
}

// моїх маму й сестер
// протягом минулих травня – липня
if( i < tokens.length - 2
&& PosTagHelper.hasPosTag(adjAnalyzedTokenReadings, "adj:p:.*")
&& forwardConjFind(tokens, i+1, 2)
&& hasOverlapIgnoreGender(masterInflections, slaveInflections, "p", null) ) {
&& tokens[i+1].getToken().matches("[\u2014\u2013-]")
&& PosTagHelper.hasPosTag(tokens[i+2], "(adj|noun).*")
//TODO: hasOverlapIgnoreGender(masterInflections, tokens[i+2])
&& hasOverlapIgnoreGender(masterInflections, slaveInflections) ) {
logException();
return true;
}

// протягом минулих травня – липня
// моїх маму й сестер
if( i < tokens.length - 2
&& PosTagHelper.hasPosTag(adjAnalyzedTokenReadings, "adj:p:.*")
&& tokens[i+1].getToken().matches("[\u2014\u2013-]")
&& PosTagHelper.hasPosTag(tokens[i+2], "(adj|noun).*")
//TODO: hasOverlapIgnoreGender(masterInflections, tokens[i+2])
&& hasOverlapIgnoreGender(masterInflections, slaveInflections) ) {
&& forwardConjFind(tokens, i+1, 2)
&& hasOverlapIgnoreGender(masterInflections, slaveInflections, "p", null) ) {
logException();
return true;
}
Expand All @@ -329,7 +329,18 @@ && hasOverlapIgnoreGender(masterInflections, slaveInflections) ) {
// навчальної та середньої шкіл
if( i > 2
&& PosTagHelper.hasPosTag(tokens[i], "noun:.*:p:.*")
&& reverseConjFind(tokens, i-2, 3)
&& (reverseConjFind(tokens, i-2, 3) || reverseConjAdvFind(tokens, i-2, 3))
&& hasOverlapIgnoreGender(masterInflections, slaveInflections, null, "p")
&& LemmaHelper.reverseSearch(tokens, i-3, 100, null, Pattern.compile("adj.*")) ) {
logException();
return true;
}

// Большого та Маріїнського театрів
// Пляжі 3, 4 і 5-ї категорій
if( i > 2
&& PosTagHelper.hasPosTag(tokens[i], "noun:.*:p:.*")
&& (reverseConjFind2(tokens, i-2, 3) )
&& hasOverlapIgnoreGender(masterInflections, slaveInflections, null, "p") ) {
logException();
return true;
Expand All @@ -340,13 +351,27 @@ && hasOverlapIgnoreGender(masterInflections, slaveInflections, null, "p") ) {
&& PosTagHelper.hasPosTag(tokens[i], "noun:.*:p:.*")
&& PosTagHelper.hasPosTag(tokens[i-1], "adj:.*")
&& PosTagHelper.hasPosTag(tokens[i-2], "prep.*")
&& LemmaHelper.hasLemma(tokens[i-3], Arrays.asList("ні", "ані"))
&& LemmaHelper.hasLemma(tokens[i-3], Arrays.asList("ні", "ані", "хоч", "що", "як"))
&& tokens[i-4].getToken().equals(",")
&& hasOverlapIgnoreGender(masterInflections, slaveInflections) ) {
logException();
return true;
}

// на проурядову і, умовно кажучи, пропрезидентську частини
if( i > 7
&& PosTagHelper.hasPosTag(tokens[i], "noun:.*:p:.*")
&& PosTagHelper.hasPosTag(tokens[i-1], "adj:.*")
&& tokens[i-2].getToken().equals(",")
&& ( (tokens[i-4].getToken().equals(",") && CONJ_FOR_PLURAL_WITH_COMMA.contains(tokens[i-5].getToken().toLowerCase())
&& ! PosTagHelper.hasPosTagPart(tokens[i-3], "verb"))
|| (tokens[i-5].getToken().equals(",") && CONJ_FOR_PLURAL_WITH_COMMA.contains(tokens[i-6].getToken().toLowerCase())
&& ! PosTagHelper.hasPosTagPart(tokens[i-3], "verb")&& ! PosTagHelper.hasPosTagPart(tokens[i-4], "verb")) )
&& hasOverlapIgnoreGender(masterInflections, slaveInflections) ) {
logException();
return true;
}

// коринфський з іонійським ордери
if( i > 2
&& PosTagHelper.hasPosTag(tokens[i], "noun:.*:p:.*")
Expand Down Expand Up @@ -898,10 +923,8 @@ && caseGovernmentMatches(tokens[i-2].getReadings(), masterInflections) ) {


private static boolean genderMatches(List<InflectionHelper.Inflection> masterInflections, List<InflectionHelper.Inflection> slaveInflections, String masterCaseFilter, String slaveCaseFilter) {
// System.err.println("master " + masterInflections + " / " + slaveInflections);
for (InflectionHelper.Inflection masterInflection : masterInflections) {
for (InflectionHelper.Inflection slaveInflection : slaveInflections) {
// System.err.println("matching gender " + masterInflection.gender + " = " + slaveInflection.gender );
if( (masterCaseFilter == null || masterInflection._case.equals(masterCaseFilter))
&& (slaveCaseFilter == null || slaveInflection._case.equals(slaveCaseFilter))
&& slaveInflection.gender.equals(masterInflection.gender) )
Expand All @@ -911,15 +934,52 @@ private static boolean genderMatches(List<InflectionHelper.Inflection> masterInf
return false;
}

private static boolean reverseConjAdvFind(AnalyzedTokenReadings[] tokens, int pos, int depth) {
for(int i=pos; i>pos-depth && i>=2; i--) {

if( CONJ_FOR_PLURAL_WITH_COMMA.contains(tokens[i].getToken().toLowerCase())
&& (PosTagHelper.hasPosTag(tokens[i-1], "adv(?!p).*")
|| PosTagHelper.hasPosTag(tokens[i+1], "(adv(?!p)|part).*")) ) {
return true;
}

if( PosTagHelper.hasPosTagPart(tokens[i], "verb") )
return false;
}

return false;
}

private static boolean reverseConjFind(AnalyzedTokenReadings[] tokens, int pos, int depth) {
for(int i=pos; i>pos-depth && i>=1; i--) {

if( CONJ_FOR_PLURAL_WITH_COMMA.contains(tokens[i].getToken().toLowerCase()) ) {

if( i < 2
|| (! PosTagHelper.hasPosTag(tokens[i-1], Pattern.compile("(adj|conj:coord).*|number"))
&& (! tokens[i-1].hasPosTag("number") || ! PosTagHelper.hasPosTag(tokens[i], Pattern.compile("adj.*?&numr.*"))) // 1, 2 та 3-й
|| (! PosTagHelper.hasPosTag(tokens[i-1], Pattern.compile("(adj|conj:coord).*")) ) )

return false;

return true;
}

if( i >= 1
&& ! PosTagHelper.hasPosTag(tokens[i-1], Pattern.compile("(adj|conj:coord|num|prep|adv(?!p)).*"))
&& ! tokens[i-1].getToken().equals(",")
)
return false;
}

return false;
}

private static boolean reverseConjFind2(AnalyzedTokenReadings[] tokens, int pos, int depth) {
for(int i=pos; i>pos-depth && i>=1; i--) {

if( CONJ_FOR_PLURAL_WITH_COMMA.contains(tokens[i].getToken().toLowerCase()) ) {

if( i < 2
|| ( (! tokens[i-1].hasPosTag("number") || ! PosTagHelper.hasPosTag(tokens[i+1], Pattern.compile("adj.*?&numr.*"))) // 1, 2 та 3-й
&& ! tokens[i-1].getToken().equals(",") )
&& ! tokens[i-1].getToken().matches(".*[–-]") // дво- і тривимірний формати
&& ! tokens[i-1].getToken().matches("[)»”]") // 1-й (...) та 2-й ряди
Expand All @@ -932,7 +992,7 @@ private static boolean reverseConjFind(AnalyzedTokenReadings[] tokens, int pos,
}

if( i >= 1
&& ! PosTagHelper.hasPosTag(tokens[i-1], Pattern.compile("(adj|conj:coord|num|prep).*"))
&& ! PosTagHelper.hasPosTag(tokens[i-1], Pattern.compile("(adj|conj:coord|num|prep|adv(?!p)).*"))
&& ! tokens[i-1].getToken().equals(",")
)
return false;
Expand Down
Expand Up @@ -722,7 +722,7 @@ public void testExceptionsPlural() throws IOException {
assertEmptyMatch("зазначені ім'я, прізвище та місто");
assertEmptyMatch("Житомирська, Кіровоградська області");
assertEmptyMatch("ані судова, ані правоохоронна системи");
assertEmptyMatch("а також курдську частини");
assertEmptyMatch("шиїтську та сунітську, а також курдську частини");
assertEmptyMatch("Чорного і Азовського морів");
assertEmptyMatch("називає й традиційні корупцію, «відкати», хабарі");
assertEmptyMatch("державні Ощадбанк, «Укргазбанк»");
Expand All @@ -742,6 +742,8 @@ public void testExceptionsPlural() throws IOException {
assertEmptyMatch("сміттєпереробного і/або сміттєспалювального заводів");
assertEmptyMatch("130-те (мінус вісім позицій порівняно з 2009-м) та 145-те місця");
assertEmptyMatch("ні у методологічному, ні у практичному аспектах.");
assertEmptyMatch("Хоч в англомовній, хоч в україномовній версіях");

// unknown words
assertEmptyMatch("Большого та Маріїнського театрів");
assertEmptyMatch("Пляжі 3, 4 і 5-ї категорій.");
Expand All @@ -755,7 +757,7 @@ public void testExceptionsPlural() throws IOException {

// multiple adj + noun:.*:p
assertEmptyMatch("символізують творчий, оберігальний та руйнівний аспекти Вищої Сили");
assertEmptyMatch("так і на центральному рівнях");
assertEmptyMatch("на місцевому, так і на центральному рівнях");
assertEmptyMatch("передався повоєнним Відню та Парижу");

// "long" plural
Expand All @@ -766,21 +768,54 @@ public void testExceptionsPlural() throws IOException {
}

@Test
public void testExceptionsPlural2() throws IOException {
public void testExceptionsPluralConjAdv() throws IOException {

assertEmptyMatch("уражені штаб ІДІЛ, а також збройний завод.");

assertEmptyMatch("в соціальному, а згодом і в економічному аспектах");
assertEmptyMatch("до апеляційного, а відтак і до конституційного судів");
assertEmptyMatch("У переносному та навіть у прямому сенсах слова");
assertEmptyMatch("в Чернівецькій і частково у Закарпатській областях");
assertEmptyMatch("парламентської, а згодом і президентської кампаній");
assertEmptyMatch("на західноєвропейському, а потім і на американському ринках");
//TODO:
// assertEmptyMatch("уражені штаб ІДІЛ, а з іншого боку збройний завод.");
// assertEmptyMatch("в соціальному, а згодом і в економічному аспектах");
// assertEmptyMatch("парламентської, а згодом і президентської кампаній");
// assertEmptyMatch("навчався в реальному, потім у землемірному училищах");
// assertEmptyMatch("на західноєвропейському, а потім і на американському ринках");
// assertEmptyMatch("У переносному та навіть у прямому сенсах слова");
// assertEmptyMatch("в Чернівецькій і частково у Закарпатській областях");
// assertEmptyMatch("Дохідна, а за нею й видаткова частини держбюджету");
assertEmptyMatch("навчався в реальному, потім у землемірному училищах");

assertHasError("для того, щоб пожвавити культурне середовища села");

// assertEmptyMatch("канонізованих царя Давида, і князя Володимира"); // unnecessary comma
}

@Test
public void testExceptionsInsertPhrase() throws IOException {
assertEmptyMatch("трагедію російського й, особливо, українського народів");
assertEmptyMatch("Китай і, певною мірою, Росія зуміли поставити");

assertHasError("що, однак, не змінюють загальної картин");

//TODO: here single gender for plural would help, but we don't have that in POS tag
// alternatively we could try to use synthesizer to guess singular gender
// assertHasError("історичне рішення, доки у виборчий кампанії");
// assertHasError("На останньому відрізку, вже на український землі");
// assertHasError("почувався в ньому не гірше, ніж у парламентський президії");
// assertHasError("у сільському господарстві (як, зокрема, сербська компанії «МК груп»)");
assertHasError("про те, що в різних міста");
assertHasError("Він додав, що у комунальних підприємства");
assertHasError("наставник сказав, що на світовий першості");
assertHasError("Аль-Каїда, і чи не найстрашніше терористичний об’єднання");
assertHasError("буде очікувати, коли нова редакції");
assertHasError("вважає Порошенко, одночасно закликаючи європейську коаліції");
assertHasError("пішли вперед, хай і міліметровим кроками");
assertHasError("Словом, у проблематиці подвійного громадянств");
assertHasError("Правоохоронцями, зокрема, проведена масштабна операції");
assertHasError("Він так і не прийняв односторонню капітуляції");
assertHasError("Так, наприклад, косівським аматорами");
assertHasError("Якщо третина чи навіть половинна населення");
assertHasError("Думаю, це фейковий вкидання");
assertHasError("Сьогодні, наприклад, часта машинобудування");
}

@Test
// we ignore all pronouns now but this may be useful in the future
public void testPronouns() throws IOException {
Expand Down

0 comments on commit 7583dd2

Please sign in to comment.