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 Restrictive(FnSet),
12 Obj(Obj),
13}
14
15#[derive(Clone)]
17pub struct ParamDefWithType {
18 pub groups: Vec<ParamGroupWithParamType>,
19}
20
21impl ParamDefWithType {
22 pub fn new(groups: Vec<ParamGroupWithParamType>) -> Self {
23 ParamDefWithType { groups }
24 }
25
26 pub fn len(&self) -> usize {
27 self.groups.len()
28 }
29
30 pub fn is_empty(&self) -> bool {
31 self.groups.is_empty()
32 }
33
34 pub fn iter(&self) -> std::slice::Iter<'_, ParamGroupWithParamType> {
35 self.groups.iter()
36 }
37
38 pub fn as_slice(&self) -> &[ParamGroupWithParamType] {
39 self.groups.as_slice()
40 }
41
42 pub fn number_of_params(&self) -> usize {
43 let mut total_param_count: usize = 0;
44 for p in self.groups.iter() {
45 total_param_count += p.params.len();
46 }
47 total_param_count
48 }
49
50 pub fn collect_param_names(&self) -> Vec<String> {
51 let mut names: Vec<String> = Vec::with_capacity(self.number_of_params());
52 for def in self.groups.iter() {
53 for name in def.param_names().iter() {
54 names.push(name.clone());
55 }
56 }
57 names
58 }
59
60 pub fn collect_param_names_with_types(&self) -> Vec<(String, ParamType)> {
61 let mut out: Vec<(String, ParamType)> = Vec::with_capacity(self.number_of_params());
62 for def in self.groups.iter() {
63 for name in def.param_names().iter() {
64 out.push((name.clone(), def.param_type.clone()));
65 }
66 }
67 out
68 }
69
70 pub fn flat_instantiated_types_for_args(
71 &self,
72 instantiated_types: &[ParamType],
73 ) -> Vec<ParamType> {
74 let mut result = Vec::with_capacity(self.number_of_params());
75 for (param_def, param_type) in self.groups.iter().zip(instantiated_types.iter()) {
76 for _ in param_def.params.iter() {
77 result.push(param_type.clone());
78 }
79 }
80 result
81 }
82
83 pub fn param_def_params_to_arg_map(
84 &self,
85 arg_map: &HashMap<String, Obj>,
86 ) -> Option<HashMap<String, Obj>> {
87 let param_names = self.collect_param_names();
88 let mut result = HashMap::new();
89 for param_name in param_names.iter() {
90 let objs_option = arg_map.get(param_name);
91 let objs = match objs_option {
92 Some(v) => v,
93 None => return None,
94 };
95 result.insert(param_name.clone(), objs.clone());
96 }
97 Some(result)
98 }
99
100 pub fn param_defs_and_args_to_param_to_arg_map(&self, args: &[Obj]) -> HashMap<String, Obj> {
101 let param_names = self.collect_param_names();
102 if param_names.len() != args.len() {
103 unreachable!();
104 }
105
106 let mut result: HashMap<String, Obj> = HashMap::new();
107 let mut index = 0;
108 while index < param_names.len() {
109 let param_name = ¶m_names[index];
110 let arg = &args[index];
111 result.insert(param_name.clone(), arg.clone());
112 index += 1;
113 }
114 result
115 }
116}
117
118impl fmt::Display for ParamDefWithType {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 write!(f, "{}", vec_to_string_join_by_comma(&self.groups))
121 }
122}
123
124impl From<Vec<ParamGroupWithParamType>> for ParamDefWithType {
125 fn from(groups: Vec<ParamGroupWithParamType>) -> Self {
126 ParamDefWithType::new(groups)
127 }
128}
129
130#[derive(Clone)]
131pub struct ParamGroupWithSet {
132 pub params: Vec<String>,
133 pub set: Obj,
134}
135
136#[derive(Clone)]
137pub struct ParamGroupWithParamType {
138 pub params: Vec<String>,
139 pub param_type: ParamType,
140}
141
142#[derive(Clone)]
143pub struct Set {}
144
145#[derive(Clone)]
146pub struct NonemptySet {}
147
148#[derive(Clone)]
149pub struct FiniteSet {}
150
151impl Set {
152 pub fn new() -> Self {
153 Set {}
154 }
155}
156
157impl NonemptySet {
158 pub fn new() -> Self {
159 NonemptySet {}
160 }
161}
162
163impl FiniteSet {
164 pub fn new() -> Self {
165 FiniteSet {}
166 }
167}
168
169impl fmt::Display for ParamType {
170 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 match self {
172 ParamType::Set(set) => write!(f, "{}", set.to_string()),
173 ParamType::NonemptySet(nonempty_set) => write!(f, "{}", nonempty_set.to_string()),
174 ParamType::FiniteSet(finite_set) => write!(f, "{}", finite_set.to_string()),
175 ParamType::Restrictive(fn_set) => {
176 write!(f, "{} {}{}{}", RESTRICTIVE, LEFT_BRACE, fn_set, RIGHT_BRACE)
177 }
178 ParamType::Obj(obj) => write!(f, "{}", obj),
179 }
180 }
181}
182
183impl fmt::Display for Set {
184 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185 write!(f, "{}", SET)
186 }
187}
188
189impl fmt::Display for NonemptySet {
190 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191 write!(f, "{}", NONEMPTY_SET)
192 }
193}
194
195impl fmt::Display for FiniteSet {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 write!(f, "{}", FINITE_SET)
198 }
199}
200
201impl fmt::Display for ParamGroupWithSet {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 write!(
204 f,
205 "{} {}",
206 comma_separated_stored_fn_params_as_user_source(&self.params),
207 self.set
208 )
209 }
210}
211
212impl fmt::Display for ParamGroupWithParamType {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 write!(
215 f,
216 "{} {}",
217 vec_to_string_join_by_comma(&self.params),
218 self.param_type
219 )
220 }
221}
222
223impl ParamGroupWithParamType {
224 pub fn new(params: Vec<String>, param_type: ParamType) -> Self {
225 ParamGroupWithParamType { params, param_type }
226 }
227
228 pub fn param_names(&self) -> &Vec<String> {
229 &self.params
230 }
231}
232
233impl ParamGroupWithSet {
234 pub fn new(params: Vec<String>, set: Obj) -> Self {
235 ParamGroupWithSet { params, set }
236 }
237
238 pub fn facts_for_binding_scope(&self, binding_scope: ParamObjType) -> Vec<Fact> {
240 let mut facts = Vec::with_capacity(self.params.len());
241 for name in self.params.iter() {
242 let fact = InFact::new(
243 obj_for_bound_param_in_scope(name.clone(), binding_scope),
244 self.set.clone(),
245 default_line_file(),
246 )
247 .into();
248 facts.push(fact);
249 }
250 facts
251 }
252
253 pub fn facts(&self) -> Vec<Fact> {
254 self.facts_for_binding_scope(ParamObjType::FnSet)
255 }
256
257 pub fn facts_for_args_satisfy_param_def_with_set_vec(
260 runtime: &Runtime,
261 param_defs: &Vec<ParamGroupWithSet>,
262 args: &Vec<Obj>,
263 param_obj_type: ParamObjType,
264 ) -> Result<Vec<AtomicFact>, RuntimeError> {
265 let instantiated_param_sets =
266 runtime.inst_param_def_with_set_one_by_one(param_defs, args, param_obj_type)?;
267 let flat_param_sets =
268 Self::flat_instantiated_param_sets_for_args(param_defs, &instantiated_param_sets);
269 let mut facts = Vec::with_capacity(args.len());
270 for (arg, param_set) in args.iter().zip(flat_param_sets.iter()) {
271 facts.push(InFact::new(arg.clone(), param_set.clone(), default_line_file()).into());
272 }
273 Ok(facts)
274 }
275
276 fn flat_instantiated_param_sets_for_args(
277 param_defs: &Vec<ParamGroupWithSet>,
278 instantiated_param_sets: &Vec<Obj>,
279 ) -> Vec<Obj> {
280 let mut result = Vec::with_capacity(Self::number_of_params(param_defs));
281 for (param_def, param_set) in param_defs.iter().zip(instantiated_param_sets.iter()) {
282 for _ in param_def.params.iter() {
283 result.push(param_set.clone());
284 }
285 }
286 result
287 }
288
289 pub fn param_names(&self) -> &Vec<String> {
290 &self.params
291 }
292
293 pub fn collect_param_names(param_defs: &Vec<ParamGroupWithSet>) -> Vec<String> {
294 let mut names: Vec<String> = Vec::with_capacity(Self::number_of_params(param_defs));
295 for def in param_defs.iter() {
296 for name in def.param_names().iter() {
297 names.push(name.clone());
298 }
299 }
300 names
301 }
302
303 pub fn number_of_params(param_defs: &Vec<ParamGroupWithSet>) -> usize {
304 let mut total_param_count: usize = 0;
305 for p in param_defs.iter() {
306 total_param_count += p.params.len();
307 }
308 return total_param_count;
309 }
310
311 pub fn param_defs_and_args_to_param_to_arg_map(
312 param_defs: &Vec<ParamGroupWithSet>,
313 args: &Vec<Obj>,
314 ) -> HashMap<String, Obj> {
315 let param_names = Self::collect_param_names(param_defs);
316 if param_names.len() != args.len() {
317 unreachable!();
318 }
319
320 let mut result: HashMap<String, Obj> = HashMap::new();
321 let mut index = 0;
322 while index < param_names.len() {
323 let param_name = ¶m_names[index];
324 let arg = &args[index];
325 result.insert(param_name.clone(), arg.clone());
326 index += 1;
327 }
328 result
329 }
330}