1use crate::prelude::*;
2use std::collections::HashMap;
3
4fn remove_param_names_from_param_to_arg_map(
5 param_to_arg_map: &HashMap<String, Obj>,
6 param_names: &Vec<String>,
7) -> HashMap<String, Obj> {
8 let mut filtered_param_to_arg_map = HashMap::new();
9 for (param_name, arg) in param_to_arg_map.iter() {
10 if !param_names.contains(param_name) {
11 filtered_param_to_arg_map.insert(param_name.clone(), arg.clone());
12 }
13 }
14 filtered_param_to_arg_map
15}
16
17impl Runtime {
18 pub fn inst_obj(
19 &self,
20 obj: &Obj,
21 param_to_arg_map: &HashMap<String, Obj>,
22 param_obj_type: ParamObjType,
23 ) -> Result<Obj, RuntimeError> {
24 match obj {
25 Obj::Atom(AtomObj::Identifier(inner)) => self.inst_identifier(inner, param_to_arg_map),
26 Obj::Atom(AtomObj::IdentifierWithMod(inner)) => {
27 self.inst_identifier_with_mod(inner, param_to_arg_map)
28 }
29 Obj::FnObj(inner) => self.inst_fn_obj(inner, param_to_arg_map, param_obj_type),
30 Obj::Number(inner) => self.inst_number(inner, param_to_arg_map, param_obj_type),
31 Obj::Add(inner) => self.inst_add(inner, param_to_arg_map, param_obj_type),
32 Obj::Sub(inner) => self.inst_sub(inner, param_to_arg_map, param_obj_type),
33 Obj::Mul(inner) => self.inst_mul(inner, param_to_arg_map, param_obj_type),
34 Obj::Div(inner) => self.inst_div(inner, param_to_arg_map, param_obj_type),
35 Obj::Mod(inner) => self.inst_mod(inner, param_to_arg_map, param_obj_type),
36 Obj::Pow(inner) => self.inst_pow(inner, param_to_arg_map, param_obj_type),
37 Obj::MatrixAdd(inner) => self.inst_matrix_add(inner, param_to_arg_map, param_obj_type),
38 Obj::MatrixSub(inner) => self.inst_matrix_sub(inner, param_to_arg_map, param_obj_type),
39 Obj::MatrixMul(inner) => self.inst_matrix_mul(inner, param_to_arg_map, param_obj_type),
40 Obj::MatrixScalarMul(inner) => {
41 self.inst_matrix_scalar_mul(inner, param_to_arg_map, param_obj_type)
42 }
43 Obj::MatrixPow(inner) => self.inst_matrix_pow(inner, param_to_arg_map, param_obj_type),
44 Obj::Abs(inner) => self.inst_abs(inner, param_to_arg_map, param_obj_type),
45 Obj::Log(inner) => self.inst_log(inner, param_to_arg_map, param_obj_type),
46 Obj::Max(inner) => self.inst_max(inner, param_to_arg_map, param_obj_type),
47 Obj::Min(inner) => self.inst_min(inner, param_to_arg_map, param_obj_type),
48 Obj::Union(inner) => self.inst_union(inner, param_to_arg_map, param_obj_type),
49 Obj::Intersect(inner) => self.inst_intersect(inner, param_to_arg_map, param_obj_type),
50 Obj::SetMinus(inner) => self.inst_set_minus(inner, param_to_arg_map, param_obj_type),
51 Obj::SetDiff(inner) => self.inst_set_diff(inner, param_to_arg_map, param_obj_type),
52 Obj::Cup(inner) => self.inst_cup(inner, param_to_arg_map, param_obj_type),
53 Obj::Cap(inner) => self.inst_cap(inner, param_to_arg_map, param_obj_type),
54 Obj::ListSet(inner) => self.inst_list_set(inner, param_to_arg_map, param_obj_type),
55 Obj::SetBuilder(inner) => {
56 self.inst_set_builder(inner, param_to_arg_map, param_obj_type)
57 }
58 Obj::FnSet(inner) => {
59 self.inst_fn_set_with_params(inner, param_to_arg_map, param_obj_type)
60 }
61 Obj::AnonymousFn(inner) => {
62 self.inst_anonymous_fn_with_params(inner, param_to_arg_map, param_obj_type)
63 }
64 Obj::StandardSet(standard_set) => self.inst_standard_set(standard_set),
65 Obj::Cart(inner) => self.inst_cart(inner, param_to_arg_map, param_obj_type),
66 Obj::CartDim(inner) => self.inst_cart_dim(inner, param_to_arg_map, param_obj_type),
67 Obj::Proj(inner) => self.inst_proj(inner, param_to_arg_map, param_obj_type),
68 Obj::TupleDim(inner) => self.inst_tuple_dim(inner, param_to_arg_map, param_obj_type),
69 Obj::Tuple(inner) => self.inst_tuple(inner, param_to_arg_map, param_obj_type),
70 Obj::Count(inner) => self.inst_count(inner, param_to_arg_map, param_obj_type),
71 Obj::Sum(inner) => self.inst_sum(inner, param_to_arg_map, param_obj_type),
72 Obj::Product(inner) => self.inst_product(inner, param_to_arg_map, param_obj_type),
73 Obj::Range(inner) => self.inst_range(inner, param_to_arg_map, param_obj_type),
74 Obj::ClosedRange(inner) => {
75 self.inst_closed_range(inner, param_to_arg_map, param_obj_type)
76 }
77 Obj::FiniteSeqSet(inner) => {
78 self.inst_finite_seq_set(inner, param_to_arg_map, param_obj_type)
79 }
80 Obj::SeqSet(inner) => self.inst_seq_set(inner, param_to_arg_map, param_obj_type),
81 Obj::FiniteSeqListObj(inner) => {
82 self.inst_finite_seq_list_obj(inner, param_to_arg_map, param_obj_type)
83 }
84 Obj::MatrixSet(inner) => self.inst_matrix_set(inner, param_to_arg_map, param_obj_type),
85 Obj::MatrixListObj(inner) => {
86 self.inst_matrix_list_obj(inner, param_to_arg_map, param_obj_type)
87 }
88 Obj::PowerSet(inner) => self.inst_power_set(inner, param_to_arg_map, param_obj_type),
89 Obj::Choose(inner) => self.inst_choose(inner, param_to_arg_map, param_obj_type),
90 Obj::ObjAtIndex(inner) => {
91 self.inst_obj_at_index(inner, param_to_arg_map, param_obj_type)
92 }
93 Obj::FamilyObj(family) => {
94 let mut params = Vec::with_capacity(family.params.len());
95 for p in family.params.iter() {
96 params.push(self.inst_obj(p, param_to_arg_map, param_obj_type)?);
97 }
98 Ok(FamilyObj::new(family.name.clone(), params).into())
99 }
100 Obj::Atom(AtomObj::Forall(p)) => {
101 if param_obj_type == ParamObjType::Forall {
102 if let Some(obj) = param_to_arg_map.get(&p.name) {
103 return Ok(obj.clone());
104 }
105 }
106 if param_obj_type == ParamObjType::FnSet {
109 if let Some(obj) = param_to_arg_map.get(&p.name) {
110 return Ok(obj.clone());
111 }
112 }
113 Ok(p.clone().into())
114 }
115 Obj::Atom(AtomObj::Def(p)) => {
116 if param_obj_type == ParamObjType::DefHeader {
117 if let Some(obj) = param_to_arg_map.get(&p.name) {
118 return Ok(obj.clone());
119 }
120 }
121 Ok(p.clone().into())
122 }
123 Obj::Atom(AtomObj::Exist(p)) => {
124 if param_obj_type == ParamObjType::Exist {
125 if let Some(obj) = param_to_arg_map.get(&p.name) {
126 return Ok(obj.clone());
127 }
128 }
129 Ok(p.clone().into())
130 }
131 Obj::Atom(AtomObj::SetBuilder(p)) => {
132 if param_obj_type == ParamObjType::SetBuilder {
133 if let Some(obj) = param_to_arg_map.get(&p.name) {
134 return Ok(obj.clone());
135 }
136 }
137 Ok(p.clone().into())
138 }
139 Obj::Atom(AtomObj::FnSet(p)) => {
140 if param_obj_type == ParamObjType::FnSet {
141 if let Some(obj) = param_to_arg_map.get(&p.name) {
142 return Ok(obj.clone());
143 }
144 }
145 Ok(p.clone().into())
146 }
147 Obj::Atom(AtomObj::Induc(p)) => {
148 if param_obj_type == ParamObjType::Induc || param_obj_type == ParamObjType::Forall {
149 if let Some(obj) = param_to_arg_map.get(&p.name) {
150 return Ok(obj.clone());
151 }
152 }
153 if param_obj_type == ParamObjType::FnSet {
154 if let Some(obj) = param_to_arg_map.get(&p.name) {
155 return Ok(obj.clone());
156 }
157 }
158 Ok(p.clone().into())
159 }
160 Obj::Atom(AtomObj::DefAlgo(p)) => {
161 if param_obj_type == ParamObjType::DefAlgo || param_obj_type == ParamObjType::Forall
162 {
163 if let Some(obj) = param_to_arg_map.get(&p.name) {
164 return Ok(obj.clone());
165 }
166 }
167 Ok(p.clone().into())
168 }
169 }
170 }
171
172 pub fn inst_identifier(
173 &self,
174 identifier: &Identifier,
175 param_to_arg_map: &HashMap<String, Obj>,
176 ) -> Result<Obj, RuntimeError> {
177 Ok(match param_to_arg_map.get(&identifier.name) {
178 Some(obj) => obj.clone(),
179 None => identifier.clone().into(),
180 })
181 }
182
183 pub fn inst_identifier_with_mod(
184 &self,
185 identifier_with_mod: &IdentifierWithMod,
186 param_to_arg_map: &HashMap<String, Obj>,
187 ) -> Result<Obj, RuntimeError> {
188 _ = param_to_arg_map;
189 Ok(identifier_with_mod.clone().into())
190 }
191
192 pub fn inst_fn_obj(
193 &self,
194 fn_obj: &FnObj,
195 param_to_arg_map: &HashMap<String, Obj>,
196 param_obj_type: ParamObjType,
197 ) -> Result<Obj, RuntimeError> {
198 let mut merged_body = Vec::with_capacity(fn_obj.body.len());
199 for obj_vec in fn_obj.body.iter() {
200 let mut new_obj_vec = Vec::with_capacity(obj_vec.len());
201 for obj in obj_vec.iter() {
202 new_obj_vec.push(Box::new(self.inst_obj(
203 obj,
204 param_to_arg_map,
205 param_obj_type,
206 )?));
207 }
208 merged_body.push(new_obj_vec);
209 }
210
211 let inst_head = self.inst_obj(
212 &(*fn_obj.head.clone()).into(),
213 param_to_arg_map,
214 param_obj_type,
215 )?;
216
217 let final_head: FnObjHead = match inst_head {
218 Obj::Atom(AtomObj::Identifier(x)) => FnObjHead::Identifier(x.clone()),
219 Obj::Atom(AtomObj::IdentifierWithMod(x)) => FnObjHead::IdentifierWithMod(x.clone()),
220 Obj::Atom(AtomObj::Forall(p)) => p.clone().into(),
221 Obj::Atom(AtomObj::Def(p)) => p.clone().into(),
222 Obj::Atom(AtomObj::Exist(p)) => p.clone().into(),
223 Obj::Atom(AtomObj::SetBuilder(p)) => p.clone().into(),
224 Obj::Atom(AtomObj::FnSet(p)) => p.clone().into(),
225 Obj::Atom(AtomObj::Induc(p)) => p.clone().into(),
226 Obj::Atom(AtomObj::DefAlgo(p)) => p.clone().into(),
227 Obj::AnonymousFn(a) => FnObjHead::AnonymousFnLiteral(Box::new(a)),
228 Obj::FnObj(x) => {
229 let merged_body_original = merged_body.clone();
230 merged_body = vec![];
231 merged_body.extend(x.body);
232 merged_body.extend(merged_body_original);
233 *x.head.clone()
234 }
235 _ => return Err(InstantiateRuntimeError(RuntimeErrorStruct::new_with_just_msg(format!("instantiate fn object: after substitution, head must be an atom, curried fn, or free-param binder, got {}", inst_head)))
236 .into()),
237 };
238
239 Ok(FnObj::new(final_head, merged_body).into())
240 }
241
242 pub fn inst_number(
243 &self,
244 number: &Number,
245 param_to_arg_map: &HashMap<String, Obj>,
246 param_obj_type: ParamObjType,
247 ) -> Result<Obj, RuntimeError> {
248 _ = param_to_arg_map;
249 _ = param_obj_type;
250 Ok(number.clone().into())
251 }
252
253 pub fn inst_add(
254 &self,
255 add: &Add,
256 param_to_arg_map: &HashMap<String, Obj>,
257 param_obj_type: ParamObjType,
258 ) -> Result<Obj, RuntimeError> {
259 let instantiated_left_obj = self.inst_obj(&add.left, param_to_arg_map, param_obj_type)?;
260 let instantiated_right_obj = self.inst_obj(&add.right, param_to_arg_map, param_obj_type)?;
261 Ok(Add::new(instantiated_left_obj, instantiated_right_obj).into())
262 }
263
264 pub fn inst_matrix_add(
265 &self,
266 ma: &MatrixAdd,
267 param_to_arg_map: &HashMap<String, Obj>,
268 param_obj_type: ParamObjType,
269 ) -> Result<Obj, RuntimeError> {
270 let instantiated_left_obj = self.inst_obj(&ma.left, param_to_arg_map, param_obj_type)?;
271 let instantiated_right_obj = self.inst_obj(&ma.right, param_to_arg_map, param_obj_type)?;
272 Ok(MatrixAdd::new(instantiated_left_obj, instantiated_right_obj).into())
273 }
274
275 pub fn inst_matrix_sub(
276 &self,
277 ms: &MatrixSub,
278 param_to_arg_map: &HashMap<String, Obj>,
279 param_obj_type: ParamObjType,
280 ) -> Result<Obj, RuntimeError> {
281 let l = self.inst_obj(&ms.left, param_to_arg_map, param_obj_type)?;
282 let r = self.inst_obj(&ms.right, param_to_arg_map, param_obj_type)?;
283 Ok(MatrixSub::new(l, r).into())
284 }
285
286 pub fn inst_matrix_mul(
287 &self,
288 mm: &MatrixMul,
289 param_to_arg_map: &HashMap<String, Obj>,
290 param_obj_type: ParamObjType,
291 ) -> Result<Obj, RuntimeError> {
292 let l = self.inst_obj(&mm.left, param_to_arg_map, param_obj_type)?;
293 let r = self.inst_obj(&mm.right, param_to_arg_map, param_obj_type)?;
294 Ok(MatrixMul::new(l, r).into())
295 }
296
297 pub fn inst_matrix_scalar_mul(
298 &self,
299 m: &MatrixScalarMul,
300 param_to_arg_map: &HashMap<String, Obj>,
301 param_obj_type: ParamObjType,
302 ) -> Result<Obj, RuntimeError> {
303 let s = self.inst_obj(&m.scalar, param_to_arg_map, param_obj_type)?;
304 let mat = self.inst_obj(&m.matrix, param_to_arg_map, param_obj_type)?;
305 Ok(MatrixScalarMul::new(s, mat).into())
306 }
307
308 pub fn inst_matrix_pow(
309 &self,
310 m: &MatrixPow,
311 param_to_arg_map: &HashMap<String, Obj>,
312 param_obj_type: ParamObjType,
313 ) -> Result<Obj, RuntimeError> {
314 let b = self.inst_obj(&m.base, param_to_arg_map, param_obj_type)?;
315 let e = self.inst_obj(&m.exponent, param_to_arg_map, param_obj_type)?;
316 Ok(MatrixPow::new(b, e).into())
317 }
318
319 pub fn inst_sub(
320 &self,
321 sub: &Sub,
322 param_to_arg_map: &HashMap<String, Obj>,
323 param_obj_type: ParamObjType,
324 ) -> Result<Obj, RuntimeError> {
325 let instantiated_left_obj = self.inst_obj(&sub.left, param_to_arg_map, param_obj_type)?;
326 let instantiated_right_obj = self.inst_obj(&sub.right, param_to_arg_map, param_obj_type)?;
327 Ok(Sub::new(instantiated_left_obj, instantiated_right_obj).into())
328 }
329
330 pub fn inst_mul(
331 &self,
332 mul: &Mul,
333 param_to_arg_map: &HashMap<String, Obj>,
334 param_obj_type: ParamObjType,
335 ) -> Result<Obj, RuntimeError> {
336 let instantiated_left_obj = self.inst_obj(&mul.left, param_to_arg_map, param_obj_type)?;
337 let instantiated_right_obj = self.inst_obj(&mul.right, param_to_arg_map, param_obj_type)?;
338 Ok(Mul::new(instantiated_left_obj, instantiated_right_obj).into())
339 }
340
341 pub fn inst_div(
342 &self,
343 div: &Div,
344 param_to_arg_map: &HashMap<String, Obj>,
345 param_obj_type: ParamObjType,
346 ) -> Result<Obj, RuntimeError> {
347 Ok(Div::new(
348 self.inst_obj(&div.left, param_to_arg_map, param_obj_type)?,
349 self.inst_obj(&div.right, param_to_arg_map, param_obj_type)?,
350 )
351 .into())
352 }
353
354 pub fn inst_mod(
355 &self,
356 mod_obj: &Mod,
357 param_to_arg_map: &HashMap<String, Obj>,
358 param_obj_type: ParamObjType,
359 ) -> Result<Obj, RuntimeError> {
360 let instantiated_left_obj =
361 self.inst_obj(&mod_obj.left, param_to_arg_map, param_obj_type)?;
362 let instantiated_right_obj =
363 self.inst_obj(&mod_obj.right, param_to_arg_map, param_obj_type)?;
364 Ok(Mod::new(instantiated_left_obj, instantiated_right_obj).into())
365 }
366
367 pub fn inst_pow(
368 &self,
369 pow: &Pow,
370 param_to_arg_map: &HashMap<String, Obj>,
371 param_obj_type: ParamObjType,
372 ) -> Result<Obj, RuntimeError> {
373 let instantiated_base_obj = self.inst_obj(&pow.base, param_to_arg_map, param_obj_type)?;
374 let instantiated_exponent_obj =
375 self.inst_obj(&pow.exponent, param_to_arg_map, param_obj_type)?;
376 Ok(Pow::new(instantiated_base_obj, instantiated_exponent_obj).into())
377 }
378
379 pub fn inst_abs(
380 &self,
381 abs: &Abs,
382 param_to_arg_map: &HashMap<String, Obj>,
383 param_obj_type: ParamObjType,
384 ) -> Result<Obj, RuntimeError> {
385 Ok(Abs::new(self.inst_obj(&abs.arg, param_to_arg_map, param_obj_type)?).into())
386 }
387
388 pub fn inst_log(
389 &self,
390 log: &Log,
391 param_to_arg_map: &HashMap<String, Obj>,
392 param_obj_type: ParamObjType,
393 ) -> Result<Obj, RuntimeError> {
394 Ok(Log::new(
395 self.inst_obj(&log.base, param_to_arg_map, param_obj_type)?,
396 self.inst_obj(&log.arg, param_to_arg_map, param_obj_type)?,
397 )
398 .into())
399 }
400
401 pub fn inst_max(
402 &self,
403 max: &Max,
404 param_to_arg_map: &HashMap<String, Obj>,
405 param_obj_type: ParamObjType,
406 ) -> Result<Obj, RuntimeError> {
407 Ok(Max::new(
408 self.inst_obj(&max.left, param_to_arg_map, param_obj_type)?,
409 self.inst_obj(&max.right, param_to_arg_map, param_obj_type)?,
410 )
411 .into())
412 }
413
414 pub fn inst_min(
415 &self,
416 min: &Min,
417 param_to_arg_map: &HashMap<String, Obj>,
418 param_obj_type: ParamObjType,
419 ) -> Result<Obj, RuntimeError> {
420 Ok(Min::new(
421 self.inst_obj(&min.left, param_to_arg_map, param_obj_type)?,
422 self.inst_obj(&min.right, param_to_arg_map, param_obj_type)?,
423 )
424 .into())
425 }
426
427 pub fn inst_union(
428 &self,
429 union: &Union,
430 param_to_arg_map: &HashMap<String, Obj>,
431 param_obj_type: ParamObjType,
432 ) -> Result<Obj, RuntimeError> {
433 Ok(Union::new(
434 self.inst_obj(&union.left, param_to_arg_map, param_obj_type)?,
435 self.inst_obj(&union.right, param_to_arg_map, param_obj_type)?,
436 )
437 .into())
438 }
439
440 pub fn inst_intersect(
441 &self,
442 intersect: &Intersect,
443 param_to_arg_map: &HashMap<String, Obj>,
444 param_obj_type: ParamObjType,
445 ) -> Result<Obj, RuntimeError> {
446 Ok(Intersect::new(
447 self.inst_obj(&intersect.left, param_to_arg_map, param_obj_type)?,
448 self.inst_obj(&intersect.right, param_to_arg_map, param_obj_type)?,
449 )
450 .into())
451 }
452
453 pub fn inst_set_minus(
454 &self,
455 set_minus: &SetMinus,
456 param_to_arg_map: &HashMap<String, Obj>,
457 param_obj_type: ParamObjType,
458 ) -> Result<Obj, RuntimeError> {
459 Ok(SetMinus::new(
460 self.inst_obj(&set_minus.left, param_to_arg_map, param_obj_type)?,
461 self.inst_obj(&set_minus.right, param_to_arg_map, param_obj_type)?,
462 )
463 .into())
464 }
465
466 pub fn inst_set_diff(
467 &self,
468 set_diff: &SetDiff,
469 param_to_arg_map: &HashMap<String, Obj>,
470 param_obj_type: ParamObjType,
471 ) -> Result<Obj, RuntimeError> {
472 Ok(SetDiff::new(
473 self.inst_obj(&set_diff.left, param_to_arg_map, param_obj_type)?,
474 self.inst_obj(&set_diff.right, param_to_arg_map, param_obj_type)?,
475 )
476 .into())
477 }
478
479 pub fn inst_cup(
480 &self,
481 cup: &Cup,
482 param_to_arg_map: &HashMap<String, Obj>,
483 param_obj_type: ParamObjType,
484 ) -> Result<Obj, RuntimeError> {
485 Ok(Cup::new(self.inst_obj(&cup.left, param_to_arg_map, param_obj_type)?).into())
486 }
487
488 pub fn inst_cap(
489 &self,
490 cap: &Cap,
491 param_to_arg_map: &HashMap<String, Obj>,
492 param_obj_type: ParamObjType,
493 ) -> Result<Obj, RuntimeError> {
494 Ok(Cap::new(self.inst_obj(&cap.left, param_to_arg_map, param_obj_type)?).into())
495 }
496
497 pub fn inst_power_set(
498 &self,
499 power_set: &PowerSet,
500 param_to_arg_map: &HashMap<String, Obj>,
501 param_obj_type: ParamObjType,
502 ) -> Result<Obj, RuntimeError> {
503 Ok(PowerSet::new(self.inst_obj(&power_set.set, param_to_arg_map, param_obj_type)?).into())
504 }
505
506 pub fn inst_list_set(
507 &self,
508 list_set: &ListSet,
509 param_to_arg_map: &HashMap<String, Obj>,
510 param_obj_type: ParamObjType,
511 ) -> Result<Obj, RuntimeError> {
512 let mut list = Vec::with_capacity(list_set.list.len());
513 for obj in list_set.list.iter() {
514 list.push(self.inst_obj(obj, param_to_arg_map, param_obj_type)?);
515 }
516 Ok(ListSet::new(list).into())
517 }
518
519 pub fn inst_set_builder(
520 &self,
521 set_builder: &SetBuilder,
522 param_to_arg_map: &HashMap<String, Obj>,
523 param_obj_type: ParamObjType,
524 ) -> Result<Obj, RuntimeError> {
525 let param_names = vec![set_builder.param.clone()];
526 let filtered_param_to_arg_map =
527 remove_param_names_from_param_to_arg_map(param_to_arg_map, ¶m_names);
528 let mut facts = Vec::with_capacity(set_builder.facts.len());
529 for fact in set_builder.facts.iter() {
530 facts.push(self.inst_or_and_chain_atomic_fact(
531 fact,
532 &filtered_param_to_arg_map,
533 param_obj_type,
534 None,
535 )?);
536 }
537 Ok(SetBuilder::new(
538 set_builder.param.clone(),
539 self.inst_obj(
540 &set_builder.param_set,
541 &filtered_param_to_arg_map,
542 param_obj_type,
543 )?,
544 facts,
545 )?
546 .into())
547 }
548
549 pub fn inst_fn_set_with_params(
550 &self,
551 fn_set_with_params: &FnSet,
552 param_to_arg_map: &HashMap<String, Obj>,
553 param_obj_type: ParamObjType,
554 ) -> Result<Obj, RuntimeError> {
555 let param_names =
556 ParamGroupWithSet::collect_param_names(&fn_set_with_params.body.params_def_with_set);
557 let filtered_param_to_arg_map =
558 remove_param_names_from_param_to_arg_map(param_to_arg_map, ¶m_names);
559 let mut params_def_with_set =
560 Vec::with_capacity(fn_set_with_params.body.params_def_with_set.len());
561 for param_def_with_set in fn_set_with_params.body.params_def_with_set.iter() {
562 params_def_with_set.push(ParamGroupWithSet::new(
563 param_def_with_set.params.clone(),
564 self.inst_obj(
565 ¶m_def_with_set.set,
566 &filtered_param_to_arg_map,
567 param_obj_type,
568 )?,
569 ));
570 }
571 let mut dom_facts = Vec::with_capacity(fn_set_with_params.body.dom_facts.len());
572 for dom_fact in fn_set_with_params.body.dom_facts.iter() {
573 dom_facts.push(self.inst_or_and_chain_atomic_fact(
574 dom_fact,
575 &filtered_param_to_arg_map,
576 param_obj_type,
577 None,
578 )?);
579 }
580 Ok(FnSet::new(
581 params_def_with_set,
582 dom_facts,
583 self.inst_obj(
584 &fn_set_with_params.body.ret_set,
585 &filtered_param_to_arg_map,
586 param_obj_type,
587 )?,
588 )?
589 .into())
590 }
591
592 pub fn inst_anonymous_fn_with_params(
593 &self,
594 af: &AnonymousFn,
595 param_to_arg_map: &HashMap<String, Obj>,
596 param_obj_type: ParamObjType,
597 ) -> Result<Obj, RuntimeError> {
598 let param_names = ParamGroupWithSet::collect_param_names(&af.body.params_def_with_set);
599 let filtered_param_to_arg_map =
600 remove_param_names_from_param_to_arg_map(param_to_arg_map, ¶m_names);
601 let mut params_def_with_set = Vec::with_capacity(af.body.params_def_with_set.len());
602 for param_def_with_set in af.body.params_def_with_set.iter() {
603 params_def_with_set.push(ParamGroupWithSet::new(
604 param_def_with_set.params.clone(),
605 self.inst_obj(
606 ¶m_def_with_set.set,
607 &filtered_param_to_arg_map,
608 param_obj_type,
609 )?,
610 ));
611 }
612 let mut dom_facts = Vec::with_capacity(af.body.dom_facts.len());
613 for dom_fact in af.body.dom_facts.iter() {
614 dom_facts.push(self.inst_or_and_chain_atomic_fact(
615 dom_fact,
616 &filtered_param_to_arg_map,
617 param_obj_type,
618 None,
619 )?);
620 }
621 Ok(AnonymousFn::new(
622 params_def_with_set,
623 dom_facts,
624 self.inst_obj(
625 af.body.ret_set.as_ref(),
626 &filtered_param_to_arg_map,
627 param_obj_type,
628 )?,
629 self.inst_obj(
630 af.equal_to.as_ref(),
631 &filtered_param_to_arg_map,
632 param_obj_type,
633 )?,
634 )?
635 .into())
636 }
637
638 pub fn inst_cart(
639 &self,
640 cart: &Cart,
641 param_to_arg_map: &HashMap<String, Obj>,
642 param_obj_type: ParamObjType,
643 ) -> Result<Obj, RuntimeError> {
644 let mut args = Vec::with_capacity(cart.args.len());
645 for arg in cart.args.iter() {
646 args.push(self.inst_obj(arg, param_to_arg_map, param_obj_type)?);
647 }
648 Ok(Cart::new(args).into())
649 }
650
651 pub fn inst_cart_dim(
652 &self,
653 cart_dim: &CartDim,
654 param_to_arg_map: &HashMap<String, Obj>,
655 param_obj_type: ParamObjType,
656 ) -> Result<Obj, RuntimeError> {
657 Ok(CartDim::new(self.inst_obj(&cart_dim.set, param_to_arg_map, param_obj_type)?).into())
658 }
659
660 pub fn inst_proj(
661 &self,
662 proj: &Proj,
663 param_to_arg_map: &HashMap<String, Obj>,
664 param_obj_type: ParamObjType,
665 ) -> Result<Obj, RuntimeError> {
666 Ok(Proj::new(
667 self.inst_obj(&proj.set, param_to_arg_map, param_obj_type)?,
668 self.inst_obj(&proj.dim, param_to_arg_map, param_obj_type)?,
669 )
670 .into())
671 }
672
673 pub fn inst_tuple_dim(
674 &self,
675 tuple_dim: &TupleDim,
676 param_to_arg_map: &HashMap<String, Obj>,
677 param_obj_type: ParamObjType,
678 ) -> Result<Obj, RuntimeError> {
679 Ok(TupleDim::new(self.inst_obj(&tuple_dim.arg, param_to_arg_map, param_obj_type)?).into())
680 }
681
682 pub fn inst_tuple(
683 &self,
684 tuple: &Tuple,
685 param_to_arg_map: &HashMap<String, Obj>,
686 param_obj_type: ParamObjType,
687 ) -> Result<Obj, RuntimeError> {
688 let mut elements = Vec::with_capacity(tuple.args.len());
689 for element in tuple.args.iter() {
690 elements.push(self.inst_obj(element, param_to_arg_map, param_obj_type)?);
691 }
692 Ok(Tuple::new(elements).into())
693 }
694
695 pub fn inst_count(
696 &self,
697 count: &Count,
698 param_to_arg_map: &HashMap<String, Obj>,
699 param_obj_type: ParamObjType,
700 ) -> Result<Obj, RuntimeError> {
701 Ok(Count::new(self.inst_obj(&count.set, param_to_arg_map, param_obj_type)?).into())
702 }
703
704 pub fn inst_sum(
705 &self,
706 sum: &Sum,
707 param_to_arg_map: &HashMap<String, Obj>,
708 param_obj_type: ParamObjType,
709 ) -> Result<Obj, RuntimeError> {
710 Ok(Sum::new(
711 self.inst_obj(&sum.start, param_to_arg_map, param_obj_type)?,
712 self.inst_obj(&sum.end, param_to_arg_map, param_obj_type)?,
713 self.inst_obj(&sum.func, param_to_arg_map, param_obj_type)?,
714 )
715 .into())
716 }
717
718 pub fn inst_product(
719 &self,
720 product: &Product,
721 param_to_arg_map: &HashMap<String, Obj>,
722 param_obj_type: ParamObjType,
723 ) -> Result<Obj, RuntimeError> {
724 Ok(Product::new(
725 self.inst_obj(&product.start, param_to_arg_map, param_obj_type)?,
726 self.inst_obj(&product.end, param_to_arg_map, param_obj_type)?,
727 self.inst_obj(&product.func, param_to_arg_map, param_obj_type)?,
728 )
729 .into())
730 }
731
732 pub fn inst_range(
733 &self,
734 range: &Range,
735 param_to_arg_map: &HashMap<String, Obj>,
736 param_obj_type: ParamObjType,
737 ) -> Result<Obj, RuntimeError> {
738 Ok(Range::new(
739 self.inst_obj(&range.start, param_to_arg_map, param_obj_type)?,
740 self.inst_obj(&range.end, param_to_arg_map, param_obj_type)?,
741 )
742 .into())
743 }
744
745 pub fn inst_closed_range(
746 &self,
747 closed_range: &ClosedRange,
748 param_to_arg_map: &HashMap<String, Obj>,
749 param_obj_type: ParamObjType,
750 ) -> Result<Obj, RuntimeError> {
751 Ok(ClosedRange::new(
752 self.inst_obj(&closed_range.start, param_to_arg_map, param_obj_type)?,
753 self.inst_obj(&closed_range.end, param_to_arg_map, param_obj_type)?,
754 )
755 .into())
756 }
757
758 pub fn inst_finite_seq_set(
759 &self,
760 fs: &FiniteSeqSet,
761 param_to_arg_map: &HashMap<String, Obj>,
762 param_obj_type: ParamObjType,
763 ) -> Result<Obj, RuntimeError> {
764 Ok(FiniteSeqSet::new(
765 self.inst_obj(&fs.set, param_to_arg_map, param_obj_type)?,
766 self.inst_obj(&fs.n, param_to_arg_map, param_obj_type)?,
767 )
768 .into())
769 }
770
771 pub fn inst_seq_set(
772 &self,
773 ss: &SeqSet,
774 param_to_arg_map: &HashMap<String, Obj>,
775 param_obj_type: ParamObjType,
776 ) -> Result<Obj, RuntimeError> {
777 Ok(SeqSet::new(self.inst_obj(&ss.set, param_to_arg_map, param_obj_type)?).into())
778 }
779
780 pub fn inst_finite_seq_list_obj(
781 &self,
782 v: &FiniteSeqListObj,
783 param_to_arg_map: &HashMap<String, Obj>,
784 param_obj_type: ParamObjType,
785 ) -> Result<Obj, RuntimeError> {
786 let mut objs = Vec::with_capacity(v.objs.len());
787 for o in v.objs.iter() {
788 objs.push(self.inst_obj(o, param_to_arg_map, param_obj_type)?);
789 }
790 Ok(FiniteSeqListObj::new(objs).into())
791 }
792
793 pub fn inst_matrix_set(
794 &self,
795 ms: &MatrixSet,
796 param_to_arg_map: &HashMap<String, Obj>,
797 param_obj_type: ParamObjType,
798 ) -> Result<Obj, RuntimeError> {
799 Ok(MatrixSet::new(
800 self.inst_obj(&ms.set, param_to_arg_map, param_obj_type)?,
801 self.inst_obj(&ms.row_len, param_to_arg_map, param_obj_type)?,
802 self.inst_obj(&ms.col_len, param_to_arg_map, param_obj_type)?,
803 )
804 .into())
805 }
806
807 pub fn inst_matrix_list_obj(
808 &self,
809 m: &MatrixListObj,
810 param_to_arg_map: &HashMap<String, Obj>,
811 param_obj_type: ParamObjType,
812 ) -> Result<Obj, RuntimeError> {
813 let mut rows: Vec<Vec<Obj>> = Vec::with_capacity(m.rows.len());
814 for row in m.rows.iter() {
815 let mut inst_row = Vec::with_capacity(row.len());
816 for o in row.iter() {
817 inst_row.push(self.inst_obj(o, param_to_arg_map, param_obj_type)?);
818 }
819 rows.push(inst_row);
820 }
821 Ok(MatrixListObj::new(rows).into())
822 }
823
824 pub fn inst_choose(
825 &self,
826 choose: &Choose,
827 param_to_arg_map: &HashMap<String, Obj>,
828 param_obj_type: ParamObjType,
829 ) -> Result<Obj, RuntimeError> {
830 Ok(Choose::new(self.inst_obj(&choose.set, param_to_arg_map, param_obj_type)?).into())
831 }
832
833 pub fn inst_obj_at_index(
834 &self,
835 obj_at_index: &ObjAtIndex,
836 param_to_arg_map: &HashMap<String, Obj>,
837 param_obj_type: ParamObjType,
838 ) -> Result<Obj, RuntimeError> {
839 Ok(ObjAtIndex::new(
840 self.inst_obj(&obj_at_index.obj, param_to_arg_map, param_obj_type)?,
841 self.inst_obj(&obj_at_index.index, param_to_arg_map, param_obj_type)?,
842 )
843 .into())
844 }
845
846 pub fn inst_standard_set(&self, standard_set: &StandardSet) -> Result<Obj, RuntimeError> {
847 Ok(standard_set.clone().into())
848 }
849
850 pub fn inst_param_type(
851 &self,
852 param_type: &ParamType,
853 param_to_arg_map: &HashMap<String, Obj>,
854 param_obj_type: ParamObjType,
855 ) -> Result<ParamType, RuntimeError> {
856 match param_type {
857 ParamType::Set(_) => Ok(param_type.clone()),
858 ParamType::FiniteSet(_) => Ok(param_type.clone()),
859 ParamType::NonemptySet(_) => Ok(param_type.clone()),
860 ParamType::Obj(obj) => Ok(ParamType::Obj(self.inst_obj(
861 obj,
862 param_to_arg_map,
863 param_obj_type,
864 )?)),
865 }
866 }
867
868 pub fn inst_param_def_with_set_one_by_one(
869 &self,
870 param_defs: &Vec<ParamGroupWithSet>,
871 args: &Vec<Obj>,
872 param_obj_type: ParamObjType,
873 ) -> Result<Vec<Obj>, RuntimeError> {
874 let total_param_count = ParamGroupWithSet::number_of_params(param_defs);
875 if total_param_count != args.len() {
876 return Err(
877 InstantiateRuntimeError(RuntimeErrorStruct::new_with_just_msg(format!(
878 "argument count mismatch: expected {} parameter(s), got {} argument(s)",
879 total_param_count,
880 args.len()
881 )))
882 .into(),
883 );
884 }
885
886 let mut param_to_arg_map: HashMap<String, Obj> = HashMap::with_capacity(total_param_count);
887 let mut arg_index: usize = 0;
888 let mut instantiated_param_sets: Vec<Obj> = Vec::with_capacity(param_defs.len());
889 for param_def in param_defs.iter() {
890 let instantiated_param_set = if arg_index != 0 {
891 self.inst_obj(¶m_def.set, ¶m_to_arg_map, param_obj_type)?
892 } else {
893 param_def.set.clone()
894 };
895 instantiated_param_sets.push(instantiated_param_set);
896
897 for param_name in param_def.params.iter() {
898 param_to_arg_map.insert(param_name.clone(), args[arg_index].clone());
899 arg_index += 1;
900 }
901 }
902
903 Ok(instantiated_param_sets)
904 }
905
906 pub fn inst_param_def_with_type_one_by_one(
907 &self,
908 param_defs: &ParamDefWithType,
909 args: &Vec<Obj>,
910 param_obj_type: ParamObjType,
911 ) -> Result<Vec<ParamType>, RuntimeError> {
912 let total_param_count = param_defs.number_of_params();
913 if total_param_count != args.len() {
914 return Err(
915 InstantiateRuntimeError(RuntimeErrorStruct::new_with_just_msg(format!(
916 "argument count mismatch: expected {} parameter(s), got {} argument(s)",
917 total_param_count,
918 args.len()
919 )))
920 .into(),
921 );
922 }
923
924 let mut param_arg_map: HashMap<String, Obj> = HashMap::with_capacity(total_param_count);
925 let mut arg_index: usize = 0;
926 let mut new_types: Vec<ParamType> = Vec::with_capacity(param_defs.groups.len());
927 for param_def in param_defs.groups.iter() {
928 let new_type = if arg_index != 0 {
929 self.inst_param_type(¶m_def.param_type, ¶m_arg_map, param_obj_type)?
930 } else {
931 param_def.param_type.clone()
932 };
933 new_types.push(new_type);
934
935 for param_name in param_def.params.iter() {
936 param_arg_map.insert(param_name.clone(), args[arg_index].clone());
937 arg_index += 1;
938 }
939 }
940
941 Ok(new_types)
942 }
943}