Merge pull request #238 from toasted-nutbread/deinflector-optimization

Deinflector optimization
This commit is contained in:
Alex Yatskov 2019-10-05 19:49:54 -07:00 committed by GitHub
commit 14a5e3ce20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 141 additions and 112 deletions

View File

@ -19,51 +19,74 @@
class Deinflector {
constructor(reasons) {
this.reasons = reasons;
this.reasons = Deinflector.normalizeReasons(reasons);
}
deinflect(source) {
const results = [{
source,
term: source,
rules: [],
rules: 0,
definitions: [],
reasons: []
}];
for (let i = 0; i < results.length; ++i) {
const entry = results[i];
for (const reason in this.reasons) {
for (const variant of this.reasons[reason]) {
let accept = entry.rules.length === 0;
if (!accept) {
for (const rule of entry.rules) {
if (variant.rulesIn.includes(rule)) {
accept = true;
break;
}
}
}
if (!accept || !entry.term.endsWith(variant.kanaIn)) {
continue;
}
const term = entry.term.slice(0, -variant.kanaIn.length) + variant.kanaOut;
if (term.length === 0) {
const {rules, term, reasons} = results[i];
for (const [reason, variants] of this.reasons) {
for (const [kanaIn, kanaOut, rulesIn, rulesOut] of variants) {
if (
(rules !== 0 && (rules & rulesIn) === 0) ||
!term.endsWith(kanaIn) ||
(term.length - kanaIn.length + kanaOut.length) <= 0
) {
continue;
}
results.push({
source,
term,
rules: variant.rulesOut,
term: term.slice(0, -kanaIn.length) + kanaOut,
rules: rulesOut,
definitions: [],
reasons: [reason, ...entry.reasons]
reasons: [reason, ...reasons]
});
}
}
}
return results;
}
static normalizeReasons(reasons) {
const normalizedReasons = [];
for (const reason in reasons) {
const variants = [];
for (const {kanaIn, kanaOut, rulesIn, rulesOut} of reasons[reason]) {
variants.push([
kanaIn,
kanaOut,
Deinflector.rulesToRuleFlags(rulesIn),
Deinflector.rulesToRuleFlags(rulesOut)
]);
}
normalizedReasons.push([reason, variants]);
}
return normalizedReasons;
}
static rulesToRuleFlags(rules) {
const ruleTypes = Deinflector.ruleTypes;
let value = 0;
for (const rule of rules) {
value |= ruleTypes[rule];
}
return value;
}
}
Deinflector.ruleTypes = {
'v1': 0b0000001, // Verb ichidan
'v5': 0b0000010, // Verb godan
'vs': 0b0000100, // Verb suru
'vk': 0b0001000, // Verb kuru
'adj-i': 0b0010000, // Adjective i
'iru': 0b0100000, // Intermediate -iru endings for progressive or perfect tense
};

View File

@ -238,8 +238,10 @@ class Translator {
const definitions = await this.database.findTermsBulk(uniqueDeinflectionTerms, titles);
for (const definition of definitions) {
const definitionRules = Deinflector.rulesToRuleFlags(definition.rules);
for (const deinflection of uniqueDeinflectionArrays[definition.index]) {
if (Translator.definitionContainsAnyRule(definition, deinflection.rules)) {
const deinflectionRules = deinflection.rules;
if (deinflectionRules === 0 || (definitionRules & deinflectionRules) !== 0) {
deinflection.definitions.push(definition);
}
}
@ -248,19 +250,6 @@ class Translator {
return deinflections.filter(e => e.definitions.length > 0);
}
static definitionContainsAnyRule(definition, rules) {
if (rules.length === 0) {
return true;
}
const definitionRules = definition.rules;
for (const rule of rules) {
if (definitionRules.includes(rule)) {
return true;
}
}
return false;
}
getDeinflections(text) {
const deinflections = [];

View File

@ -1492,16 +1492,6 @@
"rulesOut": [
"v5"
]
},
{
"kanaIn": "で",
"kanaOut": "",
"rulesIn": [
"iru"
],
"rulesOut": [
"neg-de"
]
}
],
"-zu": [
@ -2233,8 +2223,7 @@
"kanaIn": "ない",
"kanaOut": "る",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v1",
@ -2245,8 +2234,7 @@
"kanaIn": "かない",
"kanaOut": "く",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2256,8 +2244,7 @@
"kanaIn": "がない",
"kanaOut": "ぐ",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2267,8 +2254,7 @@
"kanaIn": "くない",
"kanaOut": "い",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"adj-i"
@ -2278,8 +2264,7 @@
"kanaIn": "こない",
"kanaOut": "くる",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"vk"
@ -2289,8 +2274,7 @@
"kanaIn": "さない",
"kanaOut": "す",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2300,8 +2284,7 @@
"kanaIn": "しない",
"kanaOut": "する",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"vs"
@ -2311,8 +2294,7 @@
"kanaIn": "たない",
"kanaOut": "つ",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2322,8 +2304,7 @@
"kanaIn": "なない",
"kanaOut": "ぬ",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2333,8 +2314,7 @@
"kanaIn": "ばない",
"kanaOut": "ぶ",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2344,8 +2324,7 @@
"kanaIn": "まない",
"kanaOut": "む",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2355,8 +2334,7 @@
"kanaIn": "らない",
"kanaOut": "る",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -2366,8 +2344,7 @@
"kanaIn": "わない",
"kanaOut": "う",
"rulesIn": [
"adj-i",
"neg-de"
"adj-i"
],
"rulesOut": [
"v5"
@ -3681,8 +3658,8 @@
],
"progressive or perfect": [
{
"kanaIn": "いる",
"kanaOut": "",
"kanaIn": "いる",
"kanaOut": "",
"rulesIn": [
"v1"
],
@ -3691,8 +3668,8 @@
]
},
{
"kanaIn": "る",
"kanaOut": "",
"kanaIn": "ておる",
"kanaOut": "",
"rulesIn": [
"v1"
],
@ -3701,14 +3678,54 @@
]
},
{
"kanaIn": "る",
"kanaOut": "",
"kanaIn": "る",
"kanaOut": "",
"rulesIn": [
"v1"
],
"rulesOut": [
"iru"
]
},
{
"kanaIn": "でいる",
"kanaOut": "で",
"rulesIn": [
"v1"
],
"rulesOut": [
"iru"
]
},
{
"kanaIn": "でおる",
"kanaOut": "で",
"rulesIn": [
"v1"
],
"rulesOut": [
"iru"
]
},
{
"kanaIn": "とる",
"kanaOut": "て",
"rulesIn": [
"v1"
],
"rulesOut": [
"iru"
]
},
{
"kanaIn": "ないでいる",
"kanaOut": "ない",
"rulesIn": [
"v1"
],
"rulesOut": [
"adj-i"
]
}
]
}