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#[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 = ¶m_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 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 = ¶m_names[index];
311 let arg = &args[index];
312 result.insert(param_name.clone(), arg.clone());
313 index += 1;
314 }
315 result
316 }
317}