fix(reader): prevent false phrasal verb detection for noun collocations and improve literary translation accuracy

This commit is contained in:
Antigravity committed 2026-10-06 22:58:33 +03:00
1 parent 63e0c6fc07
commit e371cdd4e5
4 files changed
+224 -33

No files matched your search

+42 -25
View File
@@ -46,7 +46,14 @@ IRREGULARS = {
PRONOUNS_AND_OBJECTS = {
"it", "him", "her", "them", "us", "me", "you", "this", "that", "these", "those",
"things", "something", "everything", "anything", "all", "back", "away"
"things", "something", "everything", "anything", "all"
}
PHRASAL_PARTICLES = {
"about", "across", "ahead", "along", "apart", "around", "round", "aside",
"at", "away", "back", "by", "down", "for", "forth", "forward", "in",
"into", "off", "on", "onto", "out", "over", "past", "round", "through",
"to", "together", "under", "up", "upon", "with"
}
# Curated high-frequency English phrasal verbs (CEFR A2-B2) with clean translations
@@ -326,20 +333,26 @@ def detect_phrasal_verb(
}
break
# Check offline dictionary
row = execute_query(
"SELECT term, translation FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
(cand,),
)
if row:
match_result = {
"term": row[0],
"raw": raw_match,
"translation": row[1],
"separable": False,
"matched_words": tokens[start : start + span_len],
}
break
# Check offline dictionary only for genuine phrasal verbs:
# 1. Candidate must end with a known particle (e.g. 'turn on', 'come up with')
# 2. pos in offline_dictionary must explicitly be a verb / verb phrase
cand_words = cand.split()
if len(cand_words) >= 2 and cand_words[-1] in PHRASAL_PARTICLES:
row = execute_query(
"SELECT term, translation, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
(cand,),
)
if row:
pos_val = (row[2] or "").lower()
if "verb" in pos_val:
match_result = {
"term": row[0],
"raw": raw_match,
"translation": row[1],
"separable": False,
"matched_words": tokens[start : start + span_len],
}
break
if match_result:
break
if match_result:
@@ -352,8 +365,10 @@ def detect_phrasal_verb(
if lower_tokens[v_idx + 1] in PRONOUNS_AND_OBJECTS:
p_idx = v_idx + 2
if idx in (v_idx, p_idx):
v_lemmas = lemmatize_word(lower_tokens[v_idx])
particle = lower_tokens[p_idx]
if particle not in PHRASAL_PARTICLES:
continue
v_lemmas = lemmatize_word(lower_tokens[v_idx])
raw_match = " ".join(tokens[v_idx : p_idx + 1])
for v in v_lemmas:
cand = f"{v} {particle}"
@@ -367,18 +382,20 @@ def detect_phrasal_verb(
}
break
row = execute_query(
"SELECT term, translation FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
"SELECT term, translation, pos FROM offline_dictionary WHERE term = ? COLLATE NOCASE",
(cand,),
)
if row:
match_result = {
"term": row[0],
"raw": raw_match,
"translation": row[1],
"separable": True,
"matched_words": [tokens[v_idx], tokens[p_idx]],
}
break
pos_val = (row[2] or "").lower()
if "verb" in pos_val:
match_result = {
"term": row[0],
"raw": raw_match,
"translation": row[1],
"separable": True,
"matched_words": [tokens[v_idx], tokens[p_idx]],
}
break
if match_result:
break
if match_result: