1#![macro_use]
2
3use crate::{name::*, util::assoc::Assoc};
57use std::{fmt, rc::Rc};
58
59#[derive(Eq, Clone, Default)]
73pub struct EnvMBE<T: Clone> {
75 leaves: Assoc<Name, T>,
77
78 repeats: Vec<Rc<Vec<EnvMBE<T>>>>,
84
85 leaf_locations: Assoc<Name, Option<usize>>,
89
90 named_repeats: Assoc<Name, Option<usize>>,
92}
93
94impl<T: Clone + crate::runtime::reify::Reifiable> crate::runtime::reify::Reifiable for EnvMBE<T> {
96 fn ty_name() -> Name { n("EnvMBE") }
97 fn concrete_arguments() -> Option<Vec<crate::ast::Ast>> { Some(vec![T::ty_invocation()]) }
98 fn reify(&self) -> crate::runtime::eval::Value {
99 crate::runtime::eval::Value::Sequence(vec![
100 Rc::new(self.leaves.reify()),
101 Rc::new(self.repeats.reify()),
102 Rc::new(self.leaf_locations.reify()),
103 Rc::new(self.named_repeats.reify()),
104 ])
105 }
106 fn reflect(v: &crate::runtime::eval::Value) -> Self {
107 extract!((v) crate::runtime::eval::Value::Sequence = (ref parts) => {
108 EnvMBE {
109 leaves: <Assoc<Name, T>>::reflect(&*parts[0]),
110 repeats: <Vec<Rc<Vec<EnvMBE<T>>>>>::reflect(&*parts[1]),
111 leaf_locations: <Assoc<Name, Option<usize>>>::reflect(&*parts[2]),
112 named_repeats: <Assoc<Name, Option<usize>>>::reflect(&*parts[3])
113 }
114 })
115 }
116}
117
118impl<T: PartialEq + Clone> PartialEq for EnvMBE<T> {
119 fn eq(&self, other: &EnvMBE<T>) -> bool {
120 fn assoc_eq_modulo_none<K: Eq + std::hash::Hash + Clone, V: PartialEq + Clone>(
121 lhs: &Assoc<K, Option<V>>,
122 rhs: &Assoc<K, Option<V>>,
123 ) -> bool {
124 for (k, v_maybe) in lhs.iter_pairs() {
125 if let Some(ref v) = *v_maybe {
126 if let Some(&Some(ref other_v)) = rhs.find(k) {
127 if !(v == other_v) {
128 return false;
129 }
130 } else {
131 return false;
132 }
133 }
134 }
135
136 for (other_k, other_v_maybe) in rhs.iter_pairs() {
137 if let Some(ref other_v) = *other_v_maybe {
138 if let Some(&Some(ref v)) = rhs.find(other_k) {
139 if !(v == other_v) {
140 return false;
141 }
142 } else {
143 return false;
144 }
145 }
146 }
147
148 true
149 }
150
151 self.leaves == other.leaves
156 && self.repeats == other.repeats
157 && assoc_eq_modulo_none(&self.leaf_locations, &other.leaf_locations)
158 && assoc_eq_modulo_none(&self.named_repeats, &other.named_repeats)
159 }
160}
161
162impl<T: Clone + fmt::Debug> fmt::Debug for EnvMBE<T> {
163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 if self.leaves.empty() && self.repeats.is_empty() {
165 write!(f, "mbe∅")
166 } else {
167 write!(f, "{{ 🍂 {:#?}, ✶", self.leaves)?;
168 let mut first = true;
169 for (i, rep) in self.repeats.iter().enumerate() {
170 if !first {
171 write!(f, ", ")?;
172 }
173 first = false;
174
175 for (name, idx_maybe) in self.named_repeats.iter_pairs() {
177 if let Some(idx) = *idx_maybe {
178 if idx == i {
179 write!(f, "⋯({:#?})⋯ ", name)?;
180 }
181 }
182 }
183 write!(f, "{:#?}", rep)?;
184 }
185 write!(f, "}}")
186 }
187 }
188}
189
190impl<T: Clone + fmt::Display> fmt::Display for EnvMBE<T> {
191 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
192 if self.leaves.empty() && self.repeats.is_empty() {
193 write!(f, "∅")
194 } else {
195 write!(f, "{{MBE {}, ✶", self.leaves)?;
196 let mut first = true;
197 for (i, rep) in self.repeats.iter().enumerate() {
198 if !first {
199 write!(f, ", ")?;
200 }
201 first = false;
202
203 for (name, idx_maybe) in self.named_repeats.iter_pairs() {
205 if let Some(idx) = *idx_maybe {
206 if idx == i {
207 write!(f, "⋯({})⋯ ", name)?;
208 }
209 }
210 }
211 for mbe in &**rep {
212 write!(f, "{} ", mbe)?;
213 }
214 }
215 write!(f, "}}")
216 }
217 }
218}
219
220impl<T: Clone> EnvMBE<T> {
221 pub fn new() -> EnvMBE<T> {
222 EnvMBE {
223 leaves: Assoc::new(),
224 repeats: vec![],
225 leaf_locations: Assoc::new(),
226 named_repeats: Assoc::new(),
227 }
228 }
229
230 pub fn new_from_leaves(l: Assoc<Name, T>) -> EnvMBE<T> {
232 EnvMBE {
233 leaves: l,
234 repeats: vec![],
235 leaf_locations: Assoc::new(),
236 named_repeats: Assoc::new(),
237 }
238 }
239
240 pub fn new_from_anon_repeat(r: Vec<EnvMBE<T>>) -> EnvMBE<T> {
242 let mut res = EnvMBE::new();
243 res.add_anon_repeat(r);
244 res
245 }
246
247 pub fn new_from_named_repeat(n: Name, r: Vec<EnvMBE<T>>) -> EnvMBE<T> {
249 let mut res = EnvMBE::new();
250 res.add_named_repeat(n, r);
251 res
252 }
253
254 pub fn combine_overriding(&self, rhs: &EnvMBE<T>) -> EnvMBE<T> {
259 let adjust_rhs_by = self.repeats.len();
260
261 let mut new_repeats = self.repeats.clone();
262 new_repeats.append(&mut rhs.repeats.clone());
263
264 EnvMBE {
265 leaves: self.leaves.set_assoc(&rhs.leaves),
266 repeats: new_repeats,
267 leaf_locations: self.leaf_locations.set_assoc(
268 &rhs.leaf_locations.map(|idx_opt| idx_opt.map(|idx| idx + adjust_rhs_by)),
269 ),
270 named_repeats: self.named_repeats.set_assoc(
271 &rhs.named_repeats.map(|idx_opt| idx_opt.map(|idx| idx + adjust_rhs_by)),
272 ),
273 }
274 }
275
276 pub fn merge(&self, rhs: &EnvMBE<T>) -> EnvMBE<T> {
280 let mut res = self.clone();
281
282 let mut rhs_idx_is_named: Vec<bool> = rhs.repeats.iter().map(|_| false).collect();
283
284 for (n, rep_idx) in rhs.named_repeats.iter_pairs() {
288 if let Some(rep_idx) = *rep_idx {
289 res.add_named_repeat(*n, (*rhs.repeats[rep_idx]).clone());
290 rhs_idx_is_named[rep_idx] = true;
291 }
292 }
293
294 for (idx, rep) in rhs.repeats.iter().enumerate() {
295 if !rhs_idx_is_named[idx] {
296 res.add_anon_repeat((**rep).clone());
297 }
298 }
299
300 res.leaves = res.leaves.set_assoc(&rhs.leaves);
301
302 res
303 }
304
305 pub fn march_all(&self, driving_names: &[Name]) -> Vec<EnvMBE<T>> {
312 let mut march_loc: Option<(usize, Name)> = None;
313
314 for &n in driving_names {
315 match (march_loc, self.leaf_locations.find(&n).unwrap_or(&None)) {
316 (_, &None) => {}
317 (None, &Some(loc)) => march_loc = Some((loc, n)),
318 (Some((old_loc, old_name)), &Some(new_loc)) => {
319 if old_loc != new_loc {
320 panic!(
321 "{:#?} and {:#?} cannot march together; they weren't matched to have \
322 the same number of repeats",
323 old_name, n
324 );
325 }
326 }
327 }
328 }
329
330 let march_loc = match march_loc {
331 None => {
332 return vec![];
333 } Some((loc, _)) => loc,
335 };
336
337 let mut result = vec![];
338 for marched_out in self.repeats[march_loc].iter() {
339 result
342 .push(EnvMBE::new_from_leaves(self.leaves.clone()).combine_overriding(marched_out));
343 }
344
345 result
346 }
347
348 pub fn get_leaf(&self, n: Name) -> Option<&T> { self.leaves.find(&n) }
350
351 pub fn get_rep_leaf(&self, n: Name) -> Option<Vec<&T>> {
352 let mut res = vec![];
356 let leaf_loc = match self.leaf_locations.find(&n) {
357 Some(&Some(ll)) => ll,
358 _ => {
359 return Some(vec![]);
360 }
361 };
362
363 for r in &*self.repeats[leaf_loc] {
364 match r.get_leaf(n) {
365 Some(leaf) => res.push(leaf),
366 None => {
367 return Some(vec![]);
368 } }
370 }
371 Some(res)
372 }
373
374 pub fn add_leaf(&mut self, n: Name, v: T) { self.leaves = self.leaves.set(n, v); }
376
377 pub fn add_named_repeat(&mut self, n: Name, sub: Vec<EnvMBE<T>>) {
378 if sub.is_empty() {
379 return;
380 } match *self.named_repeats.find(&n).unwrap_or(&None) {
383 None => {
384 let new_index = self.repeats.len();
385 self.update_leaf_locs(new_index, &sub);
386
387 self.repeats.push(Rc::new(sub));
388 self.named_repeats = self.named_repeats.set(n, Some(new_index));
389 }
390 Some(idx) => {
391 if self.repeats[idx].len() != sub.len() {
392 panic!(
393 "Named repetition {:#?} is repeated {:#?} times in one place, {:#?} times \
394 in another.",
395 n,
396 self.repeats[idx].len(),
397 sub.len()
398 )
399 }
400
401 self.update_leaf_locs(idx, &sub);
402
403 let mut new_repeats_at_idx = vec![];
404 for pairs in self.repeats[idx].iter().zip(sub.iter()) {
405 new_repeats_at_idx.push(pairs.0.combine_overriding(pairs.1));
406 }
407 self.repeats[idx] = Rc::new(new_repeats_at_idx);
408 }
409 }
410 }
411
412 pub fn add_anon_repeat(&mut self, sub: Vec<EnvMBE<T>>) {
413 if sub.is_empty() {
414 return;
415 } let new_index = self.repeats.len();
418 self.update_leaf_locs(new_index, &sub);
419
420 self.repeats.push(Rc::new(sub));
421 }
422
423 pub fn anonimize_repeat(&mut self, n: Name) {
424 self.named_repeats = self.named_repeats.set(n, None);
426 }
427
428 pub fn map<NewT: Clone, F>(&self, f: &mut F) -> EnvMBE<NewT>
429 where F: FnMut(&T) -> NewT {
430 self.named_map(&mut |_n, elt| f(elt))
431 }
432
433 pub fn map_marched_against<NewT: Clone, Mode: crate::walk_mode::WalkMode, F>(
435 &self,
436 f: &mut F,
437 ctxt: &crate::ast_walk::LazyWalkReses<Mode>,
438 ) -> EnvMBE<NewT>
439 where
440 F: FnMut(&T, &crate::ast_walk::LazyWalkReses<Mode>) -> NewT,
441 {
442 EnvMBE {
443 leaves: self.leaves.map_borrow_f(&mut |t: &T| f(t, ctxt)),
444 repeats: self
445 .repeats
446 .iter()
447 .enumerate()
448 .map(|(rpt_idx, rc_vec_mbe): (usize, &Rc<Vec<EnvMBE<T>>>)| {
449 let marched_ctxts = match self.leaf_locations.find_value(&Some(rpt_idx)) {
450 Some(this_rpt_name) => ctxt.march_all(&[*this_rpt_name]),
451 None => {
452 let mut res = vec![];
454 res.resize(rc_vec_mbe.len(), ctxt.clone());
455 res
456 }
457 };
458
459 Rc::new(
460 rc_vec_mbe
461 .iter()
462 .zip(marched_ctxts)
463 .map(
464 |(mbe, marched_ctxt): (
465 &EnvMBE<T>,
466 crate::ast_walk::LazyWalkReses<Mode>,
467 )| {
468 mbe.map_marched_against(f, &marched_ctxt)
469 },
470 )
471 .collect(),
472 )
473 })
474 .collect(),
475 leaf_locations: self.leaf_locations.clone(),
476 named_repeats: self.named_repeats.clone(),
477 }
478 }
479
480 pub fn named_map<NewT: Clone, F>(&self, f: &mut F) -> EnvMBE<NewT>
481 where F: FnMut(&Name, &T) -> NewT {
482 EnvMBE {
483 leaves: self.leaves.keyed_map_borrow_f(f),
484 repeats: self
485 .repeats
486 .iter()
487 .map(|rc_vec_mbe: &Rc<Vec<EnvMBE<T>>>| {
488 Rc::new(rc_vec_mbe.iter().map(|mbe: &EnvMBE<T>| mbe.named_map(f)).collect())
489 })
490 .collect(),
491 leaf_locations: self.leaf_locations.clone(),
492 named_repeats: self.named_repeats.clone(),
493 }
494 }
495
496 pub fn map_reduce<NewT: Clone>(
497 &self,
498 f: &dyn Fn(&T) -> NewT,
499 red: &dyn Fn(&NewT, &NewT) -> NewT,
500 base: NewT,
501 ) -> NewT {
502 let reduced: NewT = self.leaves.map(f).reduce(&|_k, v, res| red(v, &res), base);
503
504 self.repeats.iter().fold(reduced, |base: NewT, rc_vec_mbe: &Rc<Vec<EnvMBE<T>>>| {
505 rc_vec_mbe.iter().fold(base, |base: NewT, mbe: &EnvMBE<T>| mbe.map_reduce(f, red, base))
506 })
507 }
508
509 pub fn marched_map<NewT: Clone, F>(&self, f: &mut F) -> EnvMBE<NewT>
512 where F: FnMut(Name, &EnvMBE<T>, &T) -> NewT {
513 self.marched_map_rec(self, f)
514 }
515
516 fn marched_map_rec<NewT: Clone, F>(&self, outer: &EnvMBE<T>, f: &mut F) -> EnvMBE<NewT>
517 where F: FnMut(Name, &EnvMBE<T>, &T) -> NewT {
518 let local_mbe = outer.combine_overriding(self);
519
520 let new_leaves =
521 self.leaves.keyed_map_borrow_f(&mut |n: &Name, elt: &T| f(*n, &local_mbe, elt));
522 EnvMBE {
523 leaves: new_leaves,
524 repeats: self
525 .repeats
526 .iter()
527 .map(|rc_vec_mbe: &Rc<Vec<EnvMBE<T>>>| {
528 Rc::new(
529 rc_vec_mbe
530 .iter()
531 .map(|marched_out: &EnvMBE<T>| marched_out.marched_map_rec(outer, f))
532 .collect(),
533 )
534 })
535 .collect(),
536 leaf_locations: self.leaf_locations.clone(),
537 named_repeats: self.named_repeats.clone(),
538 }
539 }
540
541 pub fn can_map_with(&self, o: &EnvMBE<T>) -> bool {
543 let mut lhs_keys = std::collections::HashSet::<Name>::new();
544 for (k, _) in self.leaves.iter_pairs() {
545 lhs_keys.insert(*k);
546 }
547 let mut rhs_keys = std::collections::HashSet::<Name>::new();
548 for (k, _) in o.leaves.iter_pairs() {
549 rhs_keys.insert(*k);
550 }
551
552 if lhs_keys != rhs_keys {
553 return false;
554 }
555
556 if self.repeats.len() != o.repeats.len() {
557 return false;
558 }
559 for (subs, o_subs) in self.repeats.iter().zip(o.repeats.iter()) {
560 if subs.len() != o_subs.len() {
561 return false;
562 }
563 for (mbe, o_mbe) in subs.iter().zip(o_subs.iter()) {
564 if !mbe.can_map_with(o_mbe) {
565 return false;
566 }
567 }
568 }
569
570 true
571 }
572
573 pub fn map_with<S: Clone, NewT: Clone>(
574 &self,
575 o: &EnvMBE<S>,
576 f: &dyn Fn(&T, &S) -> NewT,
577 ) -> EnvMBE<NewT> {
578 self.named_map_with(o, &|_name, l, r| f(l, r))
579 }
580
581 pub fn named_map_with<S: Clone, NewT: Clone>(
582 &self,
583 o: &EnvMBE<S>,
584 f: &dyn Fn(&Name, &T, &S) -> NewT,
585 ) -> EnvMBE<NewT> {
586 EnvMBE {
587 leaves: self.leaves.keyed_map_with(&o.leaves, f),
588
589 repeats: self
591 .repeats
592 .iter()
593 .zip(o.repeats.iter())
594 .map(&|(rc_vec_mbe, o_rc_vec_mbe): (&Rc<Vec<EnvMBE<T>>>, &Rc<Vec<EnvMBE<S>>>)| {
595 Rc::new(
596 rc_vec_mbe
597 .iter()
598 .zip(o_rc_vec_mbe.iter())
599 .map(|(mbe, o_mbe)| mbe.named_map_with(o_mbe, f))
600 .collect(),
601 )
602 })
603 .collect(),
604 leaf_locations: self.leaf_locations.clone(),
605 named_repeats: self.named_repeats.clone(),
606 }
607 }
608
609 pub fn map_reduce_with<S: Clone, NewT: Clone>(
610 &self,
611 other: &EnvMBE<S>,
612 f: &dyn Fn(&T, &S) -> NewT,
613 red: &dyn Fn(NewT, NewT) -> NewT,
614 base: NewT,
615 ) -> NewT {
616 let mut reduced: NewT =
618 self.leaves.map_with(&other.leaves, f).reduce(&|_k, v, res| red(v.clone(), res), base);
619
620 let mut already_processed: Vec<bool> = self.repeats.iter().map(|_| false).collect();
621
622 for (leaf_name, self_idx) in self.leaf_locations.iter_pairs() {
623 let self_idx = match *self_idx {
624 Some(si) => si,
625 None => {
626 continue;
627 }
628 };
629 if already_processed[self_idx] {
630 continue;
631 }
632 already_processed[self_idx] = true;
633
634 let other_idx = other.leaf_locations.find_or_panic(leaf_name).unwrap();
635
636 for (self_elt, other_elt) in
637 self.repeats[self_idx].iter().zip(other.repeats[other_idx].iter())
638 {
639 reduced = self_elt.map_reduce_with(other_elt, f, &red, reduced);
640 }
641 }
642
643 reduced
644 }
645
646 fn update_leaf_locs(&mut self, idx: usize, sub: &[EnvMBE<T>]) {
647 let mut already_placed_leaves = std::collections::HashSet::<Name>::new();
648 let mut already_placed_repeats = std::collections::HashSet::<Name>::new();
649
650 for sub_mbe in sub {
651 for leaf_name in sub_mbe.leaf_locations.iter_keys().chain(sub_mbe.leaves.iter_keys()) {
652 if !already_placed_leaves.contains(leaf_name) {
653 self.leaf_locations = self.leaf_locations.set(*leaf_name, Some(idx));
654 already_placed_leaves.insert(*leaf_name);
655 }
656 }
657 for repeat_name in sub_mbe.named_repeats.iter_keys() {
658 if !already_placed_repeats.contains(repeat_name) {
659 self.named_repeats = self.named_repeats.set(*repeat_name, Some(idx));
660 already_placed_repeats.insert(*repeat_name);
661 }
662 }
663 }
664 }
665
666 pub fn heal_splices<E>(
668 &mut self,
669 f: &dyn Fn(&T) -> Result<Option<Vec<T>>, E>,
670 ) -> Result<(), E> {
671 for repeat in &mut self.repeats {
672 let mut cur_repeat: Vec<EnvMBE<T>> = (**repeat).clone();
673 let mut i = 0;
674 while i < cur_repeat.len() {
675 cur_repeat[i].heal_splices(f)?;
676
677 let mut splices = vec![];
678 {
679 let n_and_vals = cur_repeat[i].leaves.iter_pairs();
680 for (n, val) in n_and_vals {
681 if let Some(splice) = f(val)? {
682 splices.push((*n, splice));
683 }
684 }
685 }
686
687 if !splices.is_empty() {
688 let mut template = cur_repeat.remove(i);
689
690 for rep in 0..splices[0].1.len() {
693 for splice in &splices {
694 template.add_leaf(splice.0, splice.1[rep].clone());
695 }
696 cur_repeat.insert(i + rep, template.clone())
697 }
698 i += splices[0].1.len();
699 } else {
700 i += 1;
701 }
702 }
703 *repeat = Rc::new(cur_repeat)
704 }
705 Ok(())
706 }
707
708 pub fn heal_splices__with<E, S: Clone>(
710 &mut self,
711 other: &EnvMBE<S>,
712 f: &dyn Fn(&T, &dyn Fn() -> Vec<S>) -> Result<Option<Vec<T>>, E>,
713 ) -> Result<(), E>
714 where
715 T: std::fmt::Debug,
716 {
717 for repeat in &mut self.repeats {
718 let mut names_needed = vec![];
720 for (name, _) in self.leaf_locations.iter_pairs() {
721 names_needed.push(name);
722 }
723 let other__rep_loc = match other.leaf_locations.find(names_needed[0]) {
724 Some(Some(l)) => *l,
725 _ => {
726 return Ok(()); }
728 };
729
730 let other__cur_repeat: &Vec<EnvMBE<S>> = &*other.repeats[other__rep_loc];
731 let mut cur_repeat: Vec<EnvMBE<T>> = (**repeat).clone();
732
733 let splice_length =
736 (other__cur_repeat.len() + 1).checked_sub(cur_repeat.len()).unwrap();
737
738 let mut i = 0;
739 let mut other_i = 0;
740 while i < cur_repeat.len() && other_i < other__cur_repeat.len() {
741 cur_repeat[i].heal_splices__with(&other__cur_repeat[other_i], f)?;
742
743 let mut splices = vec![];
744 {
745 let n_and_vals = cur_repeat[i].leaves.iter_pairs();
746 for (n, val) in n_and_vals {
747 let concrete_splice__thunk = || {
748 let mut result = vec![];
749 for other_i in other__cur_repeat.iter().skip(i).take(splice_length) {
750 result.push(other_i.leaves.find_or_panic(n).clone())
751 }
752 result
753 };
754
755 if let Some(splice) = f(val, &concrete_splice__thunk)? {
756 splices.push((*n, splice));
757 }
758 }
759 }
760
761 if !splices.is_empty() {
762 let mut template = cur_repeat.remove(i);
763
764 for rep in 0..splices[0].1.len() {
767 for splice in &splices {
768 template.add_leaf(splice.0, splice.1[rep].clone());
769 }
770 cur_repeat.insert(i + rep, template.clone())
771 }
772 i += splice_length;
773 other_i += splice_length;
774 } else {
775 i += 1;
776 other_i += 1;
777 }
778 }
779 *repeat = Rc::new(cur_repeat)
783 }
784 Ok(())
785 }
786}
787
788impl<T: Clone, E: Clone> EnvMBE<Result<T, E>> {
789 pub fn lift_result(&self) -> Result<EnvMBE<T>, E> {
791 let mut leaves: Assoc<Name, T> = Assoc::new();
793 for (k, v) in self.leaves.iter_pairs() {
794 leaves = leaves.set(*k, (*v).clone()?);
795 }
796
797 let mut repeats = vec![];
798 for rep in &self.repeats {
799 let mut items = vec![];
800 for item in &**rep {
801 items.push(item.lift_result()?);
802 }
803 repeats.push(Rc::new(items));
804 }
805
806 Ok(EnvMBE {
807 leaves: leaves,
808 repeats: repeats,
809 leaf_locations: self.leaf_locations.clone(),
810 named_repeats: self.named_repeats.clone(),
811 })
812 }
813}
814
815impl<T: Clone + fmt::Debug> EnvMBE<T> {
816 pub fn get_leaf_or_panic(&self, n: &Name) -> &T {
818 match self.leaves.find(n) {
819 Some(v) => v,
820 None => panic!(" {:#?} not found in {:#?} (perhaps it is still repeated?)", n, self),
821 }
822 }
823
824 pub fn get_rep_leaf_or_panic(&self, n: Name) -> Vec<&T> { self.get_rep_leaf(n).unwrap() }
825
826 pub fn map_flatten_rep_leaf_or_panic<S>(
827 &self,
828 n: Name,
829 depth: u8,
830 m: &dyn Fn(&T) -> S,
831 f: &dyn Fn(Vec<S>) -> S,
832 ) -> S {
833 if depth == 0 {
834 return m(self.get_leaf_or_panic(&n));
835 }
836 let leaf_loc = match self.leaf_locations.find(&n) {
837 Some(&Some(ll)) => ll,
838 _ => panic!("Leaf {} not found", n),
839 };
840
841 f(self.repeats[leaf_loc]
842 .iter()
843 .map(|mbe| mbe.map_flatten_rep_leaf_or_panic(n, depth - 1, m, f))
844 .collect())
845 }
846}
847
848#[test]
849fn basic_mbe() {
850 let mut mbe = EnvMBE::new();
851 mbe.add_leaf(n("eight"), 8 as i32);
852 mbe.add_leaf(n("nine"), 9);
853
854 assert!(mbe != EnvMBE::new());
855 assert!(EnvMBE::new() != mbe);
856
857 let teens_mbe = vec![
858 EnvMBE::new_from_leaves(assoc_n!("t" => 11)),
859 EnvMBE::new_from_leaves(assoc_n!("t" => 12)),
860 EnvMBE::new_from_leaves(assoc_n!("t" => 13)),
861 ];
862
863 mbe.add_named_repeat(n("low_two_digits"), teens_mbe.clone());
864
865 let big_mbe = vec![
866 EnvMBE::new_from_leaves(assoc_n!("y" => 9001)),
867 EnvMBE::new_from_leaves(assoc_n!("y" => 9002)),
868 ];
869
870 mbe.add_anon_repeat(big_mbe);
871
872 for (sub_mbe, teen) in mbe.march_all(&vec![n("t"), n("eight")]).iter().zip(vec![11, 12, 13]) {
873 assert_eq!(sub_mbe.get_leaf(n("eight")), Some(&8));
874 assert_eq!(sub_mbe.get_leaf(n("nine")), Some(&9));
875 assert_eq!(sub_mbe.get_leaf(n("t")), Some(&teen));
876 assert_eq!(sub_mbe.get_leaf(n("y")), None);
877
878 for (sub_sub_mbe, big) in
879 sub_mbe.march_all(&vec![n("y"), n("eight")]).iter().zip(vec![9001, 9002])
880 {
881 assert_eq!(sub_sub_mbe.get_leaf(n("eight")), Some(&8));
882 assert_eq!(sub_sub_mbe.get_leaf(n("nine")), Some(&9));
883 assert_eq!(sub_sub_mbe.get_leaf(n("t")), Some(&teen));
884 assert_eq!(sub_sub_mbe.get_leaf(n("y")), Some(&big));
885 }
886 }
887
888 let neg_teens_mbe = vec![
889 EnvMBE::new_from_leaves(assoc_n!("nt" => -11)),
890 EnvMBE::new_from_leaves(assoc_n!("nt" => -12)),
891 EnvMBE::new_from_leaves(assoc_n!("nt" => -13)),
892 ];
893
894 mbe.add_named_repeat(n("low_two_digits"), neg_teens_mbe);
895
896 for (sub_mbe, teen) in
897 mbe.march_all(&vec![n("t"), n("nt"), n("eight")]).iter().zip(vec![11, 12, 13])
898 {
899 assert_eq!(sub_mbe.get_leaf(n("eight")), Some(&8));
900 assert_eq!(sub_mbe.get_leaf(n("nine")), Some(&9));
901 assert_eq!(sub_mbe.get_leaf(n("t")), Some(&teen));
902 assert_eq!(sub_mbe.get_leaf(n("nt")), Some(&-teen));
903
904 for (sub_sub_mbe, big) in
905 sub_mbe.march_all(&vec![n("y"), n("eight")]).iter().zip(vec![9001, 9002])
906 {
907 assert_eq!(sub_sub_mbe.get_leaf(n("eight")), Some(&8));
908 assert_eq!(sub_sub_mbe.get_leaf(n("nine")), Some(&9));
909 assert_eq!(sub_sub_mbe.get_leaf(n("t")), Some(&teen));
910 assert_eq!(sub_sub_mbe.get_leaf(n("nt")), Some(&-teen));
911 assert_eq!(sub_sub_mbe.get_leaf(n("y")), Some(&big));
912 }
913 }
914
915 let all_zeroes = mbe.map_with(&mbe, &|a, b| a - b);
916 for sub_mbe in all_zeroes.march_all(&vec![n("t"), n("nt"), n("eight")]) {
917 assert_eq!(sub_mbe.get_leaf(n("eight")), Some(&0));
918 assert_eq!(sub_mbe.get_leaf(n("nine")), Some(&0));
919 assert_eq!(sub_mbe.get_leaf(n("t")), Some(&0));
920 assert_eq!(sub_mbe.get_leaf(n("nt")), Some(&0));
921
922 for (sub_sub_mbe, _) in
923 sub_mbe.march_all(&vec![n("y"), n("eight")]).iter().zip(vec![9001, 9002])
924 {
925 assert_eq!(sub_sub_mbe.get_leaf(n("eight")), Some(&0));
926 assert_eq!(sub_sub_mbe.get_leaf(n("nine")), Some(&0));
927 assert_eq!(sub_sub_mbe.get_leaf(n("t")), Some(&0));
928 assert_eq!(sub_sub_mbe.get_leaf(n("nt")), Some(&0));
929 assert_eq!(sub_sub_mbe.get_leaf(n("y")), Some(&0));
930 }
931 }
932
933 assert_eq!(mbe, mbe);
934 assert!(mbe != mbe.map(&mut |x| x - 1));
935 assert_eq!(mbe, mbe.map(&mut |x| x - 0));
936 assert!(mbe != EnvMBE::new());
937 assert!(EnvMBE::new() != mbe);
938
939 assert_eq!(mbe, mbe.map_with(&all_zeroes, &|a, b| a + b));
940 assert_eq!(mbe, all_zeroes.map_with(&mbe, &|a, b| a + b));
941
942 assert_eq!(
943 mbe.map_reduce_with(&all_zeroes, &|a, b| if *a < *b { *a } else { *b }, &|a, b| a + b, 0),
944 -11 + -12 + -13
945 );
946
947 assert_eq!(
948 Err(()),
949 mbe.clone().map(&mut |x: &i32| if *x == 12 { Err(()) } else { Ok(*x) }).lift_result()
950 );
951 assert_eq!(
952 Ok(mbe.clone()),
953 mbe.clone().map(&mut |x: &i32| if *x == 121212 { Err(()) } else { Ok(*x) }).lift_result()
954 );
955
956 let mapped_mbe = mbe.map(&mut |x: &i32| (*x, *x - 9000));
957
958 let first_sub_mbe = &mapped_mbe.march_all(&vec![n("y")])[0];
959
960 assert_eq!(first_sub_mbe.get_leaf(n("y")), Some(&(9001, 1)));
961 assert_eq!(first_sub_mbe.get_leaf(n("eight")), Some(&(8, (8 - 9000))));
962 assert_eq!(first_sub_mbe.get_leaf(n("x")), None);
963
964 let mut teens_with_outer = EnvMBE::new_from_anon_repeat(teens_mbe);
967 teens_with_outer.add_leaf(n("outer"), 0);
968 let mut nothing_with_other = EnvMBE::new_from_anon_repeat(vec![]);
969 nothing_with_other.add_leaf(n("outer"), 1);
970
971 let teens_and_nothing =
972 EnvMBE::new_from_anon_repeat(vec![teens_with_outer, nothing_with_other]);
973
974 let mut output = vec![];
975 for outer in teens_and_nothing.march_all(&vec![n("outer")]) {
976 for inner in outer.march_all(&vec![n("t")]) {
977 output.push((
978 inner.get_leaf(n("outer")).map(|x| x.clone()),
979 inner.get_leaf(n("t")).map(|x| x.clone()),
980 ));
981 }
982 }
983 assert_eq!(output, vec![(Some(0), Some(11)), (Some(0), Some(12)), (Some(0), Some(13))]);
984}
985
986#[test]
987fn splice_healing() {
988 use crate::ast::Ast;
989
990 let orig = mbe!(
991 "rator" => (vr "add"), "rand" => [(vr "a"), (vr "b"), (vr "c"), (vr "d")]
992 );
993 let mut noop = orig.clone();
994 noop.heal_splices::<()>(&|_| Ok(None)).unwrap();
995 assert_eq!(noop, orig);
996
997 let mut b_to_xxx = orig.clone();
998 b_to_xxx
999 .heal_splices::<()>(&|a| {
1000 if a == &ast!((vr "b")) {
1001 Ok(Some(vec![ast!((vr "x")), ast!((vr "xx"))]))
1002 } else {
1003 Ok(None)
1004 }
1005 })
1006 .unwrap();
1007 assert_eq!(
1008 b_to_xxx,
1009 mbe!(
1010 "rator" => (vr "add"), "rand" => [(vr "a"), (vr "x"), (vr "xx"), (vr "c"), (vr "d")]
1011 )
1012 );
1013
1014 let steal_from_other =
1015 |a: &Ast, other__a_vec__thunk: &dyn Fn() -> Vec<Ast>| -> Result<Option<Vec<Ast>>, ()> {
1016 if a == &ast!((vr "c")) {
1017 Ok(Some(other__a_vec__thunk()))
1018 } else {
1019 Ok(None)
1020 }
1021 };
1022
1023 let other_short = mbe!(
1024 "rator" => (vr "---"), "rand" => [(vr "1"), (vr "2"), (vr "3")]);
1025
1026 let mut with_short = orig.clone();
1027 assert_eq!(with_short.heal_splices__with::<(), Ast>(&other_short, &steal_from_other), Ok(()));
1028 assert_eq!(with_short, mbe!("rator" => (vr "add"), "rand" => [(vr "a"), (vr "b"), (vr "d")]));
1029
1030 let other_long = mbe!(
1031 "rator" => (vr "---"),
1032 "rand" => [(vr "1"), (vr "2"), (vr "3"), (vr "4"), (vr "5"), (vr "6")]);
1033
1034 let mut with_long = orig.clone();
1035 assert_eq!(with_long.heal_splices__with::<(), Ast>(&other_long, &steal_from_other), Ok(()));
1036 assert_eq!(
1037 with_long,
1038 mbe!("rator" => (vr "add"),
1039 "rand" => [(vr "a"), (vr "b"), (vr "3"), (vr "4"), (vr "5"), (vr "d")])
1040 );
1041
1042 }