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