1use crate::config::{基本信息, 安排, 安排描述, 广义码位, 简码模式, 简码规则, 配置};
4use crate::contexts::{
5 上下文, 合并初始决策, 展开变量, 应用生成器, 拓扑排序, 条件, 条件安排, 补充存在性条件
6};
7use crate::encoders::default::简码数量;
8use crate::interfaces::默认输入;
9use crate::optimizers::决策;
10use crate::{
11 formatted_local_now, 元素, 元素图, 原始当量信息, 原始键位分布信息, 可编码对象, 最大元素数量, 最大按键组合长度, 最大词长, 棱镜, 码表项, 编码, 编码信息, 键
12};
13use crate::{最大元素编码长度, 错误};
14use indexmap::IndexMap;
15use regex::Regex;
16use rustc_hash::FxHashMap;
17use serde_yaml::to_string;
18
19#[derive(Debug, Clone)]
21pub struct 默认上下文 {
22 pub 配置: 配置,
23 pub 词列表: Vec<可编码对象>,
24 pub 键位分布信息: 原始键位分布信息,
25 pub 当量信息: 原始当量信息,
26 pub 初始决策: 默认决策,
27 pub 决策空间: 默认决策空间,
28 pub 棱镜: 棱镜,
29 pub 选择键: Vec<键>,
30 pub 元素图: 元素图,
31 pub 保存原始决策空间: IndexMap<String, Vec<安排描述>>,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq)]
35pub enum 默认安排 {
36 键位([(元素, usize); 最大元素编码长度]),
37 归并(元素),
38 未选取,
39}
40
41impl 默认安排 {
42 pub fn from(原始安排: &安排, 棱镜: &棱镜, 元素: &String) -> Result<Self, 错误> {
43 match 原始安排 {
44 安排::Basic(_) | 安排::Advanced(_) => {
45 let 归一化映射值 = 原始安排.normalize();
46 let mut 安排 = [(0, 0); 最大元素编码长度];
47 for (序号, 映射键) in 归一化映射值.iter().enumerate() {
48 if let 广义码位::Ascii(x) = 映射键 {
49 if let Some(键) = 棱镜.键转数字.get(x) {
50 安排[序号] = (*键 as usize, 0);
51 } else {
52 return Err(
53 format!("元素 {元素} 的编码中的字符 {x} 并不在字母表中").into()
54 );
55 }
56 } else if let 广义码位::Reference { element, index } = 映射键 {
57 if let Some(元素编号) = 棱镜.元素转数字.get(element) {
58 安排[序号] = (*元素编号, *index);
59 } else {
60 return Err(format!(
61 "元素 {元素} 的编码中的引用元素 {element} 并不存在"
62 )
63 .into());
64 }
65 } else {
66 return Err(format!("元素 {元素} 的编码格式不正确").into());
67 }
68 }
69 Ok(默认安排::键位(安排))
70 }
71 安排::Grouped { element } => {
72 if let Some(元素编号) = 棱镜.元素转数字.get(element) {
73 Ok(默认安排::归并(*元素编号))
74 } else {
75 Err(format!("元素 {元素} 的编码中的引用元素 {element} 并不存在").into())
76 }
77 }
78 安排::Unused(_) => Ok(默认安排::未选取),
79 }
80 }
81
82 pub fn to(&self, 棱镜: &棱镜) -> 安排 {
83 match self {
84 默认安排::归并(引用元素) => 安排::Grouped {
85 element: 棱镜.数字转元素[引用元素].clone(),
86 },
87 默认安排::键位(取值) => {
88 let mut 列表 = vec![];
89 for (元素, 位置) in 取值 {
90 if *元素 == 0 {
91 break;
92 } else if 棱镜.数字转键.contains_key(&(*元素 as u64)) {
93 let 键 = 棱镜.数字转键[&(*元素 as u64)];
94 列表.push(广义码位::Ascii(键));
95 } else {
96 let 元素名称 = 棱镜.数字转元素[元素].clone();
97 列表.push(广义码位::Reference {
98 element: 元素名称,
99 index: *位置,
100 });
101 }
102 }
103 if 列表.iter().all(|x| matches!(x, 广义码位::Ascii(_))) {
104 安排::Basic(
105 列表
106 .iter()
107 .map(|x| match x {
108 广义码位::Ascii(c) => *c,
109 _ => unreachable!(),
110 })
111 .collect(),
112 )
113 } else {
114 安排::Advanced(列表)
115 }
116 }
117 默认安排::未选取 => 安排::Unused(()),
118 }
119 }
120}
121
122type 默认条件安排 = 条件安排<默认安排>;
123
124#[derive(Debug, Clone)]
125pub struct 默认决策 {
126 pub 元素: Vec<默认安排>,
127}
128
129impl 默认决策 {
130 pub fn 允许(&self, 条件安排: &默认条件安排) -> bool {
131 for 条件 in &条件安排.条件 {
132 if 条件.谓词 != (self.元素[条件.元素] == 条件.值) {
133 return false;
134 }
135 }
136 return true;
137 }
138}
139
140#[derive(Debug, Clone)]
141pub struct 默认决策变化 {
142 pub 增加元素: Vec<元素>,
143 pub 减少元素: Vec<元素>,
144 pub 移动元素: Vec<元素>,
145}
146
147impl 默认决策变化 {
148 pub fn 新建(
149 增加元素: Vec<元素>, 减少元素: Vec<元素>, 移动元素: Vec<元素>
150 ) -> Self {
151 Self {
152 增加元素,
153 减少元素,
154 移动元素,
155 }
156 }
157
158 pub fn 不变() -> Self {
159 Self::新建(vec![], vec![], vec![])
160 }
161}
162
163impl 决策 for 默认决策 {
164 type 变化 = 默认决策变化;
165 fn 除法(旧变化: &Self::变化, 新变化: &Self::变化) -> Self::变化 {
166 let mut res = 默认决策变化 {
167 增加元素: 旧变化.减少元素.clone(),
168 减少元素: 旧变化.增加元素.clone(),
169 移动元素: 旧变化.移动元素.clone(),
170 };
171 for 元素 in &新变化.增加元素 {
172 res.增加元素.push(*元素);
173 }
174 for 元素 in &新变化.减少元素 {
175 res.减少元素.push(*元素);
176 }
177 for 元素 in &新变化.移动元素 {
178 res.移动元素.push(*元素);
179 }
180 res
181 }
182}
183
184#[derive(Debug, Clone)]
185pub struct 默认决策空间 {
186 pub 元素: Vec<Vec<默认条件安排>>,
187}
188
189impl 上下文 for 默认上下文 {
190 type 决策 = 默认决策;
191 fn 序列化(&self, 决策: &Self::决策) -> String {
192 let mut 新配置 = self.配置.clone();
193 let mut info = 新配置.info.clone().unwrap_or(基本信息 {
194 name: None,
195 description: None,
196 version: None,
197 author: None,
198 });
199 info.version = Some(formatted_local_now());
200 新配置.info = Some(info);
201 let mut mapping = IndexMap::new();
202 for (i, 安排) in 决策.元素.iter().enumerate() {
203 if i < self.棱镜.进制 as usize {
204 continue;
205 }
206 let 元素名称 = self.棱镜.数字转元素[&i].clone();
207 let mapped = 安排.to(&self.棱镜);
208 if mapped != 安排::Unused(()) {
209 mapping.insert(元素名称, mapped);
210 }
211 }
212 新配置.form.mapping = mapping;
213 新配置.form.mapping_space = Some(self.保存原始决策空间.clone());
214 to_string(&新配置).unwrap()
215 }
216}
217
218impl 默认上下文 {
219 pub fn 新建(输入: 默认输入) -> Result<Self, 错误> {
220 let (初始决策, 决策空间, 元素图, 选择键, 棱镜, 保存原始决策空间) =
221 Self::构建棱镜和初始决策(&输入.配置)?;
222 let 最大码长 = 输入.配置.encoder.max_length;
223 let 词列表 = 棱镜.预处理词列表(输入.词列表, 最大码长)?;
224 Ok(Self {
225 配置: 输入.配置,
226 词列表,
227 键位分布信息: 输入.原始键位分布信息.clone(),
228 当量信息: 输入.原始当量信息.clone(),
229 初始决策,
230 棱镜,
231 选择键,
232 决策空间,
233 元素图,
234 保存原始决策空间,
235 })
236 }
237
238 pub fn 构建棱镜和初始决策(
239 配置: &配置,
240 ) -> Result<(默认决策, 默认决策空间, 元素图, Vec<键>, 棱镜, IndexMap<String, Vec<安排描述>>), 错误> {
241 let mut 原始决策 = 配置.form.mapping.clone();
243 let mut 原始决策空间 = 配置.form.mapping_space.clone().unwrap_or_default();
244 let 原始变量映射 = 配置.form.mapping_variables.clone().unwrap_or_default();
245 let 原始生成器列表 = 配置.form.mapping_generators.clone().unwrap_or_default();
246 合并初始决策(&mut 原始决策空间, &mut 原始决策);
248 let 保存原始决策空间 = 原始决策空间.clone();
250 应用生成器(&mut 原始决策空间, &原始生成器列表);
252 展开变量(&mut 原始决策空间, &原始变量映射);
254 补充存在性条件(&mut 原始决策空间);
256 let (排序后元素名称, 原始元素图) = 拓扑排序(&原始决策空间)?;
258
259 let mut 键转数字: FxHashMap<char, 键> = FxHashMap::default();
261 let mut 数字转键: FxHashMap<键, char> = FxHashMap::default();
262 let mut 元素转数字: FxHashMap<String, 元素> = FxHashMap::default();
263 let mut 数字转元素: FxHashMap<元素, String> = FxHashMap::default();
264 let 原始选择键 = 配置.encoder.select_keys.clone().unwrap_or(vec!['_']);
265 if 原始选择键.is_empty() {
266 return Err("选择键不能为空!".into());
267 }
268 for 键 in 配置.form.alphabet.chars().chain(原始选择键.iter().cloned()) {
269 if 键转数字.contains_key(&键) {
270 return Err("编码键有重复!".into());
271 };
272 let 键编号 = 键转数字.len() + 1;
273 键转数字.insert(键, 键编号 as 键);
274 数字转键.insert(键编号 as 键, 键);
275 元素转数字.insert(键.to_string(), 键编号);
276 数字转元素.insert(键编号, 键.to_string());
277 }
278 let 进制 = 键转数字.len() as 键 + 1;
279 let 选择键 = 原始选择键.iter().map(|k| 键转数字[k]).collect();
280 for 元素名称 in &排序后元素名称 {
281 let 元素编号 = 元素转数字.len() + 1;
282 元素转数字.insert(元素名称.clone(), 元素编号);
283 数字转元素.insert(元素编号, 元素名称.clone());
284 }
285 let mut 棱镜 = 棱镜 {
286 键转数字,
287 数字转键,
288 元素转数字,
289 数字转元素,
290 进制,
291 可选元素位图索引: FxHashMap::default(),
292 };
293
294 let (初始决策, 决策空间, 元素图) = Self::构建初始决策和决策空间(
296 &棱镜,
297 &排序后元素名称,
298 &原始决策,
299 &原始决策空间,
300 &原始元素图,
301 )?;
302
303 for (元素编号, 安排列表) in 决策空间.元素.iter().enumerate() {
305 if 安排列表.iter().any(|ca| ca.安排 == 默认安排::未选取) {
306 let 位图索引 = 棱镜.可选元素位图索引.len();
307 棱镜.可选元素位图索引.insert(元素编号, 位图索引);
308 }
309 }
310 if 棱镜.可选元素位图索引.len() > 最大元素数量 {
311 return Err(format!(
312 "可选元素数量 {} 超过了最大可选元素数量 {}",
313 棱镜.可选元素位图索引.len(),
314 最大元素数量
315 )
316 .into());
317 }
318
319 Ok((初始决策, 决策空间, 元素图, 选择键, 棱镜, 保存原始决策空间))
320 }
321
322 pub fn 构建初始决策和决策空间(
323 棱镜: &棱镜,
324 排序后元素名称: &Vec<String>,
325 原始决策: &IndexMap<String, 安排>,
326 原始决策空间: &IndexMap<String, Vec<安排描述>>,
327 原始元素图: &FxHashMap<String, Vec<String>>,
328 ) -> Result<(默认决策, 默认决策空间, 元素图), 错误> {
329 let mut 初始决策 = 默认决策 { 元素: vec![] };
331 let mut 决策空间 = 默认决策空间 { 元素: vec![] };
332 let mut 元素图: FxHashMap<元素, Vec<_>> = FxHashMap::default();
333 for k in 0..棱镜.进制 {
334 let 安排 = 默认安排::键位([(k as usize, 0), (0, 0), (0, 0), (0, 0)]);
335 let 条件安排 = 默认条件安排 {
336 安排: 安排.clone(),
337 条件: vec![],
338 分数: 0.0,
339 };
340 初始决策.元素.push(安排);
341 决策空间.元素.push(vec![条件安排]);
342 }
343 for 元素名称 in 排序后元素名称 {
344 let 原始安排 = &原始决策[元素名称];
345 let mut 安排列表 = vec![];
346 let 原始安排列表 = 原始决策空间[元素名称].clone();
347 let 编号 = 棱镜.元素转数字[元素名称];
348 let 安排 = 默认安排::from(原始安排, &棱镜, 元素名称)?;
349 for 其余原始安排 in &原始安排列表 {
350 let mut 条件列表 = vec![];
351 for c in 其余原始安排.condition.clone().unwrap_or_default() {
352 if let Some(条件元素) = 棱镜.元素转数字.get(&c.element) {
353 条件列表.push(条件 {
354 元素: *条件元素,
355 谓词: c.op == "是",
356 值: 默认安排::from(&c.value, &棱镜, &c.element)?,
357 });
358 }
359 }
360 let 条件字根安排 = 默认条件安排 {
361 安排: 默认安排::from(&其余原始安排.value, &棱镜, 元素名称)?,
362 条件: 条件列表,
363 分数: 其余原始安排.score,
364 };
365 安排列表.push(条件字根安排);
366 }
367 初始决策.元素.push(安排);
368 决策空间.元素.push(安排列表);
369 let 下游 = 原始元素图.get(元素名称).unwrap();
370 let 下游编号: Vec<_> = 下游.iter().map(|x| 棱镜.元素转数字[x]).collect();
371 元素图.insert(编号, 下游编号);
372 }
373 Ok((初始决策, 决策空间, 元素图))
374 }
375
376 pub fn 生成码表(&self, 编码结果: &[编码信息]) -> Vec<码表项> {
377 let mut 码表: Vec<(usize, 码表项)> = Vec::new();
378 let 转编码 = |code: 编码| self.棱镜.数字转编码(code).iter().collect();
379 for (序号, 可编码对象) in self.词列表.iter().enumerate() {
380 let 码表项 = 码表项 {
381 词: 可编码对象.词.clone(),
382 全码: 转编码(编码结果[序号].全码.原始编码),
383 全码排名: 编码结果[序号].全码.原始编码候选位置,
384 简码: 转编码(编码结果[序号].简码.原始编码),
385 简码排名: 编码结果[序号].简码.原始编码候选位置,
386 };
387 码表.push((可编码对象.原始顺序, 码表项));
388 }
389 码表.sort_by_key(|x| x.0);
390 码表.into_iter().map(|x| x.1).collect()
391 }
392
393 pub fn 预处理自动上屏(&self) -> Result<Vec<bool>, 错误> {
396 let mut result: Vec<bool> = vec![];
397 let encoder = &self.配置.encoder;
398 let mut re: Option<Regex> = None;
399 if let Some(pattern) = &encoder.auto_select_pattern {
400 let re_or_error = Regex::new(pattern);
401 if let Ok(regex) = re_or_error {
402 re = Some(regex);
403 } else {
404 return Err(format!("正则表达式 {pattern} 无法解析").into());
405 }
406 }
407 for code in 0..self.线性表长度() {
408 let chars = self.棱镜.数字转编码(code as u64);
409 let string: String = chars.iter().collect();
410 let is_matched = if let Some(re) = &re {
411 re.is_match(&string)
412 } else if let Some(length) = encoder.auto_select_length {
413 chars.len() >= length
414 } else {
415 true
416 };
417 let is_max_length = chars.len() == encoder.max_length;
418 result.push(is_matched || is_max_length);
419 }
420 Ok(result)
421 }
422
423 pub fn 预处理简码规则(
424 &self,
425 schemes: &Vec<简码模式>,
426 ) -> Result<Vec<简码数量>, 错误> {
427 let mut compiled_schemes = Vec::new();
428 for scheme in schemes {
429 let prefix = scheme.prefix;
430 let count = scheme.count.unwrap_or(1);
431 let select_keys = if let Some(keys) = &scheme.select_keys {
432 let mut transformed_keys = Vec::new();
433 for key in keys {
434 let transformed_key = self
435 .棱镜
436 .键转数字
437 .get(key)
438 .ok_or(format!("简码的选择键 {key} 不在全局选择键中"))?;
439 transformed_keys.push(*transformed_key);
440 }
441 transformed_keys
442 } else {
443 self.选择键.clone()
444 };
445 if count > select_keys.len() {
446 return Err("选重数量不能高于选择键数量".into());
447 }
448 compiled_schemes.push(简码数量 {
449 prefix,
450 select_keys: select_keys[..count].to_vec(),
451 });
452 }
453 Ok(compiled_schemes)
454 }
455
456 pub fn 预处理简码配置(
457 &self,
458 原始简码配置列表: Vec<简码规则>,
459 ) -> Result<[Vec<简码数量>; 最大词长], 错误> {
460 let mut short_code: [Vec<简码数量>; 最大词长] = Default::default();
461 for config in 原始简码配置列表 {
462 match config {
463 简码规则::Equal {
464 length_equal,
465 schemes,
466 } => {
467 short_code[length_equal - 1].extend(self.预处理简码规则(&schemes)?);
468 }
469 简码规则::Range {
470 length_in_range: (from, to),
471 schemes,
472 } => {
473 for length in from..=to {
474 short_code[length - 1].extend(self.预处理简码规则(&schemes)?);
475 }
476 }
477 }
478 }
479 Ok(short_code)
480 }
481
482 pub fn 线性表长度(&self) -> usize {
483 let 组合长度 = self.配置.encoder.max_length.min(最大按键组合长度);
484 self.棱镜.进制.pow(组合长度 as u32) as usize
485 }
486}