Skip to main content

chai/contexts/
mod.rs

1use crate::{
2    config::{安排, 广义码位, 决策生成器规则, 变量规则, 安排描述},
3    optimizers::决策,
4    元素, 错误,
5};
6use indexmap::IndexMap;
7use regex::Regex;
8use rustc_hash::{FxHashMap, FxHashSet};
9use std::collections::VecDeque;
10pub mod default;
11
12pub trait 上下文 {
13    type 决策: 决策;
14
15    fn 序列化(&self, 决策: &Self::决策) -> String;
16}
17
18#[derive(Debug, Clone)]
19pub struct 条件<T> {
20    pub 元素: 元素,
21    pub 谓词: bool,
22    pub 值: T,
23}
24
25#[derive(Debug, Clone)]
26pub struct 条件安排<T> {
27    pub 安排: T,
28    pub 分数: f64,
29    pub 条件: Vec<条件<T>>,
30}
31
32pub fn 合并初始决策(
33    原始决策空间: &mut IndexMap<String, Vec<安排描述>>,
34    原始决策: &mut IndexMap<String, 安排>,
35) {
36    for 元素名称 in 原始决策.keys() {
37        if !原始决策空间.contains_key(元素名称) {
38            原始决策空间.insert(元素名称.clone(), vec![]);
39        }
40    }
41    // 移除多余元素
42    for 元素名称 in 原始决策空间.keys() {
43        if !原始决策.contains_key(元素名称) {
44            原始决策.insert(元素名称.clone(), 安排::Unused(()));
45        }
46    }
47    // 确保每个元素的当前决策都在决策空间中
48    for (元素名称, 原始安排列表) in 原始决策空间.iter_mut() {
49        let 原始安排 = 原始决策[元素名称].clone();
50        if !原始安排列表.iter().any(|x| &x.value == &原始安排) {
51            原始安排列表.insert(
52                0,
53                安排描述 {
54                    value: 原始安排,
55                    score: 0.0,
56                    condition: None,
57                },
58            );
59        }
60    }
61}
62
63pub fn 展开变量(
64    原始决策空间: &mut IndexMap<String, Vec<安排描述>>,
65    原始变量映射: &IndexMap<String, 变量规则>,
66) {
67    for (_, 原始安排列表) in 原始决策空间.iter_mut() {
68        let mut 队列 = VecDeque::from(原始安排列表.clone());
69        原始安排列表.clear();
70        while let Some(原始安排) = 队列.pop_front() {
71            let mut 是否展开 = false;
72            if let 安排::Advanced(keys) = &原始安排.value {
73                for (序号, 映射键) in keys.iter().enumerate() {
74                    if let 广义码位::Variable {
75                        variable: generator,
76                    } = 映射键
77                    {
78                        let 变量取值列表 = 原始变量映射.get(generator).unwrap();
79                        for 变量取值 in &变量取值列表.keys {
80                            let mut 新映射键列表 = keys.clone();
81                            新映射键列表[序号] = 广义码位::Ascii(*变量取值);
82                            let 新原始安排 = 安排描述 {
83                                value: 安排::Advanced(新映射键列表),
84                                score: 原始安排.score,
85                                condition: 原始安排.condition.clone(),
86                            };
87                            队列.push_back(新原始安排);
88                        }
89                        是否展开 = true;
90                        break;
91                    }
92                }
93            }
94            if !是否展开 {
95                原始安排列表.push(原始安排);
96            }
97        }
98    }
99}
100
101pub fn 拓扑排序(
102    原始决策空间: &IndexMap<String, Vec<安排描述>>,
103) -> Result<(Vec<String>, FxHashMap<String, Vec<String>>), 错误> {
104    // 构造入度表
105    let mut 入度 = FxHashMap::default();
106    let mut 元素图 = FxHashMap::default();
107    for 元素名称 in 原始决策空间.keys() {
108        入度.insert(元素名称.clone(), 0);
109        元素图.insert(元素名称.clone(), vec![]);
110    }
111    for (元素名称, 原始安排列表) in 原始决策空间 {
112        let mut 依赖 = FxHashSet::default();
113        for 原始安排 in 原始安排列表 {
114            if let 安排::Advanced(keys) = &原始安排.value {
115                for k in keys {
116                    if let 广义码位::Reference { element, .. } = k {
117                        依赖.insert(element.clone());
118                    }
119                }
120            } else if let 安排::Grouped { element } = &原始安排.value {
121                依赖.insert(element.clone());
122            }
123            if let Some(条件列表) = &原始安排.condition {
124                for 条件 in 条件列表 {
125                    依赖.insert(条件.element.clone());
126                }
127            }
128        }
129        for 依赖元素 in &依赖 {
130            元素图.get_mut(依赖元素).map(|v| {
131                v.push(元素名称.clone());
132                *入度.get_mut(元素名称).unwrap() += 1;
133            });
134        }
135    }
136
137    // 拓扑排序
138    let mut 队列 = VecDeque::new();
139    for (元素名称, d) in &入度 {
140        if *d == 0 {
141            队列.push_back(元素名称.clone());
142        }
143    }
144
145    let mut 排序后元素名称 = Vec::new();
146    while let Some(u) = 队列.pop_front() {
147        排序后元素名称.push(u.clone());
148        for v in &元素图[&u] {
149            let deg = 入度.get_mut(v).unwrap();
150            *deg -= 1;
151            if *deg == 0 {
152                队列.push_back(v.clone());
153            }
154        }
155    }
156
157    // 检测环
158    if 排序后元素名称.len() != 原始决策空间.len() {
159        let remaining: Vec<_> = 入度
160            .into_iter()
161            .filter(|(_, deg)| *deg > 0)
162            .map(|(k, _)| k)
163            .collect();
164        return Err(format!("检测到依赖环,无法进行拓扑排序,剩余节点:{:?}", remaining).into());
165    }
166
167    Ok((排序后元素名称, 元素图))
168}
169
170pub fn 应用生成器(
171    原始决策空间: &mut IndexMap<String, Vec<安排描述>>,
172    原始生成器列表: &Vec<决策生成器规则>,
173) {
174    for 生成器 in 原始生成器列表 {
175        let regex = Regex::new(&生成器.regex).unwrap();
176        for (元素名称, 原始安排列表) in 原始决策空间.iter_mut() {
177            if !regex.is_match(元素名称) {
178                continue;
179            }
180            if let 安排::Advanced(keys) = &生成器.value.value {
181                let mut values = FxHashSet::default();
182                for 现有安排 in 原始安排列表.iter() {
183                    if matches!(&现有安排.value, 安排::Basic(_) | 安排::Advanced(_)) {
184                        let 现有键 = &现有安排.value.normalize();
185                        let mut valid = true;
186                        let 合成 = keys
187                            .iter()
188                            .enumerate()
189                            .map(|(i, x)| {
190                                let k = &现有键[i];
191                                // 引用不能被替换为变量
192                                if matches!(k, 广义码位::Reference { .. }) {
193                                    if matches!(x, 广义码位::Variable { .. }) {
194                                        valid = false;
195                                    }
196                                }
197                                if let 广义码位::Placeholder(_) = x {
198                                    k.clone()
199                                } else {
200                                    x.clone()
201                                }
202                            })
203                            .collect();
204                        if !valid {
205                            continue;
206                        }
207                        values.insert(合成);
208                    }
209                }
210                for value in values {
211                    let 新原始安排 = 安排描述 {
212                        value: 安排::Advanced(value),
213                        score: 生成器.value.score,
214                        condition: 生成器.value.condition.clone(),
215                    };
216                    原始安排列表.push(新原始安排);
217                }
218            } else {
219                原始安排列表.push(生成器.value.clone());
220            }
221        }
222    }
223}