Skip to content
This repository has been archived by the owner on Feb 25, 2023. It is now read-only.

Deinflector optimization #238

Merged
merged 2 commits into from
Oct 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 48 additions & 25 deletions ext/bg/js/deinflector.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
17 changes: 3 additions & 14 deletions ext/bg/js/translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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 = [];

Expand Down
Loading