在完整音节后敲反引号,接着的字母筛这个音节上的字:第一码大小写均可, 紧跟的大写字母是第二码,之后可以接着打,一个输入里可以有多段。开关 helpcode.shuangpin_mid_sentence_helpcode 默认关闭。 约束在整句解码时生效,而不是解完再筛: - Google 解码器在 add_char_qwerty 里送 extend_mtrx_nd 之前按约束过滤词条, 锁住的字带着上下文重新整句解码;约束变化时整段重解,不污染增量搜索。 - kenlm 词格建图时按约束筛边,受约束的跨度不截断地查词库;神经重排只在 词格 n-best 里挑,自动满足约束。 - 普通词条、云和 AI 候选按同一规则收尾校验;满足不了就不出整句。 反引号段在请求里换成手动分隔符,原串留给宿主回读与预编辑显示;选词推进 时剩余音节上的约束随原串保留。输入形状规则放在 contracts/mid_sentence_helpcode.h, TSF、Server、引擎共用,新增 Worker opcode MidSentenceHelpcodeChanged = 28。 googlepinyinime-rev 已与上游解绑,AGENTS 与 UPSTREAM.md 同步说明。
58 lines
2.1 KiB
C++
58 lines
2.1 KiB
C++
#pragma once
|
|
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// 句中辅助码(双拼):在一个完整音节后面敲反引号,接着的字母筛这个音节上的字。
|
|
//
|
|
// ulpb`x 第二个音节「鹤」位置上的字,辅助码第一码必须是 x
|
|
// ulpb`xY 同上,第二码必须是 y(第二码要用大写才参与筛选)
|
|
// ulpb`xihfa 约束留在第二个音节上,后面照常往下打
|
|
//
|
|
// 一个输入串里可以有多段。约束在整句解码时就生效(kenlm 词格建图筛边、Google 解码器
|
|
// 建格子筛字),而不是解完再筛,所以被锁住的字会带着上下文重新整句打分。
|
|
struct SyllableHelpcode
|
|
{
|
|
// 受约束的音节,按去掉反引号段之后的双拼切分计,0 起。
|
|
std::size_t syllable = 0;
|
|
// 第一码,小写字母。
|
|
char first = 0;
|
|
// 第二码,小写字母;0 表示没有第二码,只按第一码筛。
|
|
char second = 0;
|
|
|
|
bool operator==(const SyllableHelpcode &other) const
|
|
{
|
|
return syllable == other.syllable && first == other.first && second == other.second;
|
|
}
|
|
bool operator!=(const SyllableHelpcode &other) const
|
|
{
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
|
|
using SyllableHelpcodes = std::vector<SyllableHelpcode>;
|
|
|
|
// 辅助码表里查到的码(如 "ek")是否满足这一条约束。
|
|
inline bool syllable_helpcode_matches(const SyllableHelpcode &helpcode, const std::string &code)
|
|
{
|
|
if (code.empty() || code[0] != helpcode.first)
|
|
return false;
|
|
return helpcode.second == 0 || (code.size() > 1 && code[1] == helpcode.second);
|
|
}
|
|
|
|
// 缓存键用的签名:同一串拼音带不同约束,候选不同,不能共用缓存。
|
|
inline std::string syllable_helpcodes_signature(const SyllableHelpcodes &helpcodes)
|
|
{
|
|
std::string signature;
|
|
for (const auto &helpcode : helpcodes)
|
|
{
|
|
signature += '`';
|
|
signature += std::to_string(helpcode.syllable);
|
|
signature += helpcode.first;
|
|
if (helpcode.second != 0)
|
|
signature += helpcode.second;
|
|
}
|
|
return signature;
|
|
}
|