Skip to main content

litex/stmt/
parameter_def.rs

1use crate::prelude::*;
2use std::collections::HashMap;
3use std::fmt;
4
5#[derive(Clone)]
6pub enum ParamType {
7    Set(Set),
8    NonemptySet(NonemptySet),
9    FiniteSet(FiniteSet),
10    Obj(Obj),
11    Struct(StructObj),
12}
13
14/// Full parameter list with types, e.g. `a, b T, c E` as a sequence of [`ParamGroupWithParamType`].
15#[derive(Clone)]
16pub struct ParamDefWithType {
17    pub groups: Vec<ParamGroupWithParamType>,
18}
19
20impl ParamDefWithType {
21    pub fn new(groups: Vec<ParamGroupWithParamType>) -> Self {
22        ParamDefWithType { groups }
23    }
24
25    pub fn len(&self) -> usize {
26        self.groups.len()
27    }
28
29    pub fn is_empty(&self) -> bool {
30        self.groups.is_empty()
31    }
32
33    pub fn iter(&self) -> std::slice::Iter<'_, ParamGroupWithParamType> {
34        self.groups.iter()
35    }
36
37    pub fn as_slice(&self) -> &[ParamGroupWithParamType] {
38        self.groups.as_slice()
39    }
40
41    pub fn number_of_params(&self) -> usize {
42        let mut total_param_count: usize = 0;
43        for p in self.groups.iter() {
44            total_param_count += p.params.len();
45        }
46        total_param_count
47    }
48
49    pub fn collect_param_names(&self) -> Vec<String> {
50        let mut names: Vec<String> = Vec::with_capacity(self.number_of_params());
51        for def in self.groups.iter() {
52            for name in def.param_names().iter() {
53                names.push(name.clone());
54            }
55        }
56        names
57    }
58
59    pub fn collect_param_names_with_types(&self) -> Vec<(String, ParamType)> {
60        let mut out: Vec<(String, ParamType)> = Vec::with_capacity(self.number_of_params());
61        for def in self.groups.iter() {
62            for name in def.param_names().iter() {
63                out.push((name.clone(), def.param_type.clone()));
64            }
65        }
66        out
67    }
68
69    pub fn flat_instantiated_types_for_args(
70        &self,
71        instantiated_types: &[ParamType],
72    ) -> Vec<ParamType> {
73        let mut result = Vec::with_capacity(self.number_of_params());
74        for (param_def, param_type) in self.groups.iter().zip(instantiated_types.iter()) {
75            for _ in param_def.params.iter() {
76                result.push(param_type.clone());
77            }
78        }
79        result
80    }
81
82    pub fn param_def_params_to_arg_map(
83        &self,
84        arg_map: &HashMap<String, Obj>,
85    ) -> Option<HashMap<String, Obj>> {
86        let param_names = self.collect_param_names();
87        let mut result = HashMap::new();
88        for param_name in param_names.iter() {
89            let objs_option = arg_map.get(param_name);
90            let objs = match objs_option {
91                Some(v) => v,
92                None => return None,
93            };
94            result.insert(param_name.clone(), objs.clone());
95        }
96        Some(result)
97    }
98
99    pub fn param_defs_and_args_to_param_to_arg_map(&self, args: &[Obj]) -> HashMap<String, Obj> {
100        let param_names = self.collect_param_names();
101        if param_names.len() != args.len() {
102            unreachable!();
103        }
104
105        let mut result: HashMap<String, Obj> = HashMap::new();
106        let mut index = 0;
107        while index < param_names.len() {
108            let param_name = &param_names[index];
109            let arg = &args[index];
110            result.insert(param_name.clone(), arg.clone());
111            index += 1;
112        }
113        result
114    }
115}
116
117impl fmt::Display for ParamDefWithType {
118    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119        write!(f, "{}", vec_to_string_join_by_comma(&self.groups))
120    }
121}
122
123impl From<Vec<ParamGroupWithParamType>> for ParamDefWithType {
124    fn from(groups: Vec<ParamGroupWithParamType>) -> Self {
125        ParamDefWithType::new(groups)
126    }
127}
128
129#[derive(Clone)]
130pub struct ParamGroupWithSet {
131    pub params: Vec<String>,
132    pub set: Obj,
133}
134
135#[derive(Clone)]
136pub struct ParamGroupWithParamType {
137    pub params: Vec<String>,
138    pub param_type: ParamType,
139}
140
141#[derive(Clone)]
142pub struct Set {}
143
144#[derive(Clone)]
145pub struct NonemptySet {}
146
147#[derive(Clone)]
148pub struct FiniteSet {}
149
150impl Set {
151    pub fn new() -> Self {
152        Set {}
153    }
154}
155
156impl NonemptySet {
157    pub fn new() -> Self {
158        NonemptySet {}
159    }
160}
161
162impl FiniteSet {
163    pub fn new() -> Self {
164        FiniteSet {}
165    }
166}
167
168impl fmt::Display for ParamType {
169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170        match self {
171            ParamType::Set(set) => write!(f, "{}", set.to_string()),
172            ParamType::NonemptySet(nonempty_set) => write!(f, "{}", nonempty_set.to_string()),
173            ParamType::FiniteSet(finite_set) => write!(f, "{}", finite_set.to_string()),
174            ParamType::Obj(obj) => write!(f, "{}", obj),
175            ParamType::Struct(struct_ty) => write!(f, "{}", struct_ty),
176        }
177    }
178}
179
180impl fmt::Display for Set {
181    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182        write!(f, "{}", SET)
183    }
184}
185
186impl fmt::Display for NonemptySet {
187    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188        write!(f, "{}", NONEMPTY_SET)
189    }
190}
191
192impl fmt::Display for FiniteSet {
193    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
194        write!(f, "{}", FINITE_SET)
195    }
196}
197
198impl fmt::Display for ParamGroupWithSet {
199    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200        write!(
201            f,
202            "{} {}",
203            comma_separated_stored_fn_params_as_user_source(&self.params),
204            self.set
205        )
206    }
207}
208
209impl fmt::Display for ParamGroupWithParamType {
210    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211        write!(
212            f,
213            "{} {}",
214            vec_to_string_join_by_comma(&self.params),
215            self.param_type
216        )
217    }
218}
219
220impl ParamGroupWithParamType {
221    pub fn new(params: Vec<String>, param_type: ParamType) -> Self {
222        ParamGroupWithParamType { params, param_type }
223    }
224
225    pub fn param_names(&self) -> &Vec<String> {
226        &self.params
227    }
228}
229
230impl ParamGroupWithSet {
231    pub fn new(params: Vec<String>, set: Obj) -> Self {
232        ParamGroupWithSet { params, set }
233    }
234
235    pub fn facts(&self) -> Vec<Fact> {
236        let mut facts = Vec::with_capacity(self.params.len());
237        for name in self.params.iter() {
238            let fact =
239                InFact::new(name.clone().into(), self.set.clone(), default_line_file()).into();
240            facts.push(fact);
241        }
242        facts
243    }
244
245    // Example: given fn(x R, y Q), we want to verify x = 1, y = 2 can be used as argument to this function. This function returns the facts that 1 $in R, 2 $in Q.
246    // 与 [`ParamGroupWithParamType`] 不同:此处每个参数必须属于**事先确定**的集合(不能用 `set` / `nonempty_set` / `finite_set` 等语法糖),且该集合不能依赖更早的参数。例如 `x R, y f(x)` 不允许。
247    pub fn facts_for_args_satisfy_param_def_with_set_vec(
248        runtime: &Runtime,
249        param_defs: &Vec<ParamGroupWithSet>,
250        args: &Vec<Obj>,
251    ) -> Result<Vec<AtomicFact>, RuntimeError> {
252        let instantiated_param_sets =
253            runtime.inst_param_def_with_set_one_by_one(param_defs, args)?;
254        let flat_param_sets =
255            Self::flat_instantiated_param_sets_for_args(param_defs, &instantiated_param_sets);
256        let mut facts = Vec::with_capacity(args.len());
257        for (arg, param_set) in args.iter().zip(flat_param_sets.iter()) {
258            facts.push(InFact::new(arg.clone(), param_set.clone(), default_line_file()).into());
259        }
260        Ok(facts)
261    }
262
263    fn flat_instantiated_param_sets_for_args(
264        param_defs: &Vec<ParamGroupWithSet>,
265        instantiated_param_sets: &Vec<Obj>,
266    ) -> Vec<Obj> {
267        let mut result = Vec::with_capacity(Self::number_of_params(param_defs));
268        for (param_def, param_set) in param_defs.iter().zip(instantiated_param_sets.iter()) {
269            for _ in param_def.params.iter() {
270                result.push(param_set.clone());
271            }
272        }
273        result
274    }
275
276    pub fn param_names(&self) -> &Vec<String> {
277        &self.params
278    }
279
280    pub fn collect_param_names(param_defs: &Vec<ParamGroupWithSet>) -> Vec<String> {
281        let mut names: Vec<String> = Vec::with_capacity(Self::number_of_params(param_defs));
282        for def in param_defs.iter() {
283            for name in def.param_names().iter() {
284                names.push(name.clone());
285            }
286        }
287        names
288    }
289
290    pub fn number_of_params(param_defs: &Vec<ParamGroupWithSet>) -> usize {
291        let mut total_param_count: usize = 0;
292        for p in param_defs.iter() {
293            total_param_count += p.params.len();
294        }
295        return total_param_count;
296    }
297
298    pub fn param_defs_and_args_to_param_to_arg_map(
299        param_defs: &Vec<ParamGroupWithSet>,
300        args: &Vec<Obj>,
301    ) -> HashMap<String, Obj> {
302        let param_names = Self::collect_param_names(param_defs);
303        if param_names.len() != args.len() {
304            unreachable!();
305        }
306
307        let mut result: HashMap<String, Obj> = HashMap::new();
308        let mut index = 0;
309        while index < param_names.len() {
310            let param_name = &param_names[index];
311            let arg = &args[index];
312            result.insert(param_name.clone(), arg.clone());
313            index += 1;
314        }
315        result
316    }
317}