Skip to main content

litex/obj/
obj.rs

1use super::atom_obj::AtomObj;
2use super::fn_set::{AnonymousFn, FnSet, FnSetBody};
3use crate::prelude::*;
4use std::fmt;
5
6#[derive(Clone)]
7pub enum Obj {
8    Atom(AtomObj),
9    FnObj(FnObj),
10    Number(Number),
11    Add(Add),
12    Sub(Sub),
13    Mul(Mul),
14    Div(Div),
15    Mod(Mod),
16    Pow(Pow),
17    Abs(Abs),
18    Log(Log),
19    Max(Max),
20    Min(Min),
21    Union(Union),
22    Intersect(Intersect),
23    SetMinus(SetMinus),
24    SetDiff(SetDiff),
25    Cup(Cup),
26    Cap(Cap),
27    PowerSet(PowerSet),
28    ListSet(ListSet),
29    SetBuilder(SetBuilder),
30    FnSet(FnSet),
31    AnonymousFn(AnonymousFn),
32    Cart(Cart),
33    CartDim(CartDim),
34    Proj(Proj),
35    TupleDim(TupleDim),
36    Tuple(Tuple),
37    Count(Count),
38    Sum(Sum),
39    Product(Product),
40    Range(Range),
41    ClosedRange(ClosedRange),
42    FiniteSeqSet(FiniteSeqSet),
43    SeqSet(SeqSet),
44    FiniteSeqListObj(FiniteSeqListObj),
45    Choose(Choose),
46    ObjAtIndex(ObjAtIndex),
47    StandardSet(StandardSet),
48    FamilyObj(FamilyObj),
49    MatrixSet(MatrixSet),
50    MatrixListObj(MatrixListObj),
51    MatrixAdd(MatrixAdd),
52    MatrixSub(MatrixSub),
53    MatrixMul(MatrixMul),
54    MatrixScalarMul(MatrixScalarMul),
55    MatrixPow(MatrixPow),
56}
57
58#[derive(Clone)]
59pub struct Sum {
60    pub start: Box<Obj>,
61    pub end: Box<Obj>,
62    pub func: Box<Obj>,
63}
64
65#[derive(Clone)]
66pub struct Product {
67    pub start: Box<Obj>,
68    pub end: Box<Obj>,
69    pub func: Box<Obj>,
70}
71
72#[derive(Clone)]
73pub struct MatrixAdd {
74    pub left: Box<Obj>,
75    pub right: Box<Obj>,
76}
77
78#[derive(Clone)]
79pub struct MatrixSub {
80    pub left: Box<Obj>,
81    pub right: Box<Obj>,
82}
83
84#[derive(Clone)]
85pub struct MatrixMul {
86    pub left: Box<Obj>,
87    pub right: Box<Obj>,
88}
89
90#[derive(Clone)]
91pub struct MatrixScalarMul {
92    pub scalar: Box<Obj>,
93    pub matrix: Box<Obj>,
94}
95
96#[derive(Clone)]
97pub struct MatrixPow {
98    pub base: Box<Obj>,
99    pub exponent: Box<Obj>,
100}
101
102#[derive(Clone)]
103pub struct MatrixSet {
104    pub set: Box<Obj>,
105    pub row_len: Box<Obj>,
106    pub col_len: Box<Obj>,
107}
108
109#[derive(Clone)]
110pub struct MatrixListObj {
111    pub rows: Vec<Vec<Box<Obj>>>,
112}
113
114#[derive(Clone)]
115pub struct FamilyObj {
116    pub name: AtomicName,
117    pub params: Vec<Obj>,
118}
119
120impl FamilyObj {
121    pub fn new(name: AtomicName, params: Vec<Obj>) -> Self {
122        FamilyObj { name, params }
123    }
124}
125
126impl fmt::Display for FamilyObj {
127    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128        write!(
129            f,
130            "{}({})",
131            display_family_obj_head(&self.name),
132            vec_to_string_join_by_comma(&self.params)
133        )
134    }
135}
136
137fn display_family_obj_head(name: &AtomicName) -> String {
138    format!("{}{}", FAMILY_OBJ_PREFIX, name)
139}
140
141#[derive(Clone)]
142pub struct ObjAtIndex {
143    pub obj: Box<Obj>,
144    pub index: Box<Obj>,
145}
146
147#[derive(Clone)]
148pub struct Choose {
149    pub set: Box<Obj>,
150}
151
152#[derive(Clone)]
153pub struct PowerSet {
154    pub set: Box<Obj>,
155}
156
157#[derive(Clone)]
158pub struct Range {
159    pub start: Box<Obj>,
160    pub end: Box<Obj>,
161}
162
163#[derive(Clone)]
164pub struct ClosedRange {
165    pub start: Box<Obj>,
166    pub end: Box<Obj>,
167}
168
169/// Set of functions `fn(x N_pos: x <= n) s` (Lit surface syntax: keyword `finite_seq(s, n)`).
170#[derive(Clone)]
171pub struct FiniteSeqSet {
172    pub set: Box<Obj>,
173    pub n: Box<Obj>,
174}
175
176/// `seq(s)` — functions `fn(x N_pos) s` (no length bound; surface: keyword `seq(s)`).
177#[derive(Clone)]
178pub struct SeqSet {
179    pub set: Box<Obj>,
180}
181
182/// Literal `[a, b, ...]` as a finite sequence value (for membership in `finite_seq(s, n)`).
183#[derive(Clone)]
184pub struct FiniteSeqListObj {
185    pub objs: Vec<Box<Obj>>,
186}
187
188#[derive(Clone)]
189pub struct Count {
190    pub set: Box<Obj>,
191}
192
193#[derive(Clone)]
194pub struct Tuple {
195    pub args: Vec<Box<Obj>>,
196}
197
198#[derive(Clone)]
199pub struct TupleDim {
200    pub arg: Box<Obj>,
201}
202
203#[derive(Clone)]
204pub struct CartDim {
205    pub set: Box<Obj>,
206}
207
208#[derive(Clone)]
209pub struct Proj {
210    pub set: Box<Obj>,
211    pub dim: Box<Obj>,
212}
213
214#[derive(Clone)]
215pub struct FnObj {
216    pub head: Box<FnObjHead>,
217    pub body: Vec<Vec<Box<Obj>>>,
218}
219
220#[derive(Clone)]
221pub struct Number {
222    pub normalized_value: String,
223}
224
225#[derive(Clone)]
226pub struct Add {
227    pub left: Box<Obj>,
228    pub right: Box<Obj>,
229}
230
231#[derive(Clone)]
232pub struct Sub {
233    pub left: Box<Obj>,
234    pub right: Box<Obj>,
235}
236
237#[derive(Clone)]
238pub struct Mul {
239    pub left: Box<Obj>,
240    pub right: Box<Obj>,
241}
242
243#[derive(Clone)]
244pub struct Div {
245    pub left: Box<Obj>,
246    pub right: Box<Obj>,
247}
248
249#[derive(Clone)]
250pub struct Mod {
251    pub left: Box<Obj>,
252    pub right: Box<Obj>,
253}
254
255#[derive(Clone)]
256pub struct Pow {
257    pub base: Box<Obj>,
258    pub exponent: Box<Obj>,
259}
260
261#[derive(Clone)]
262pub struct Abs {
263    pub arg: Box<Obj>,
264}
265
266/// Real logarithm `log(base, x)` with `base > 0`, `base != 1`, `x > 0`.
267#[derive(Clone)]
268pub struct Log {
269    pub base: Box<Obj>,
270    pub arg: Box<Obj>,
271}
272
273#[derive(Clone)]
274pub struct Max {
275    pub left: Box<Obj>,
276    pub right: Box<Obj>,
277}
278
279#[derive(Clone)]
280pub struct Min {
281    pub left: Box<Obj>,
282    pub right: Box<Obj>,
283}
284
285#[derive(Clone)]
286pub struct Union {
287    pub left: Box<Obj>,
288    pub right: Box<Obj>,
289}
290
291#[derive(Clone)]
292pub struct Intersect {
293    pub left: Box<Obj>,
294    pub right: Box<Obj>,
295}
296
297#[derive(Clone)]
298pub struct SetMinus {
299    pub left: Box<Obj>,
300    pub right: Box<Obj>,
301}
302
303#[derive(Clone)]
304pub struct SetDiff {
305    pub left: Box<Obj>,
306    pub right: Box<Obj>,
307}
308
309#[derive(Clone)]
310pub struct Cup {
311    pub left: Box<Obj>,
312}
313
314#[derive(Clone)]
315pub struct Cap {
316    pub left: Box<Obj>,
317}
318
319#[derive(Clone)]
320pub struct ListSet {
321    pub list: Vec<Box<Obj>>,
322}
323
324#[derive(Clone)]
325pub struct SetBuilder {
326    pub param: String,
327    pub param_set: Box<Obj>,
328    pub facts: Vec<OrAndChainAtomicFact>,
329}
330
331#[derive(Clone)]
332pub struct Cart {
333    pub args: Vec<Box<Obj>>,
334}
335
336impl ObjAtIndex {
337    pub fn new(obj: Obj, index: Obj) -> Self {
338        ObjAtIndex {
339            obj: Box::new(obj),
340            index: Box::new(index),
341        }
342    }
343}
344
345impl FnObj {
346    pub fn new(head: FnObjHead, body: Vec<Vec<Box<Obj>>>) -> Self {
347        FnObj {
348            head: Box::new(head),
349            body,
350        }
351    }
352}
353
354impl Number {
355    pub fn new(value: String) -> Self {
356        Number {
357            normalized_value: normalize_decimal_number_string(&value),
358        }
359    }
360}
361
362impl Add {
363    pub fn new(left: Obj, right: Obj) -> Self {
364        Add {
365            left: Box::new(left),
366            right: Box::new(right),
367        }
368    }
369}
370
371impl Sub {
372    pub fn new(left: Obj, right: Obj) -> Self {
373        Sub {
374            left: Box::new(left),
375            right: Box::new(right),
376        }
377    }
378}
379
380impl Mul {
381    pub fn new(left: Obj, right: Obj) -> Self {
382        Mul {
383            left: Box::new(left),
384            right: Box::new(right),
385        }
386    }
387}
388
389impl Div {
390    pub fn new(left: Obj, right: Obj) -> Self {
391        Div {
392            left: Box::new(left),
393            right: Box::new(right),
394        }
395    }
396}
397
398impl Mod {
399    pub fn new(left: Obj, right: Obj) -> Self {
400        Mod {
401            left: Box::new(left),
402            right: Box::new(right),
403        }
404    }
405}
406
407impl Pow {
408    pub fn new(base: Obj, exponent: Obj) -> Self {
409        Pow {
410            base: Box::new(base),
411            exponent: Box::new(exponent),
412        }
413    }
414}
415
416impl Abs {
417    pub fn new(arg: Obj) -> Self {
418        Abs { arg: Box::new(arg) }
419    }
420}
421
422impl Log {
423    pub fn new(base: Obj, arg: Obj) -> Self {
424        Log {
425            base: Box::new(base),
426            arg: Box::new(arg),
427        }
428    }
429}
430
431impl Max {
432    pub fn new(left: Obj, right: Obj) -> Self {
433        Max {
434            left: Box::new(left),
435            right: Box::new(right),
436        }
437    }
438}
439
440impl Min {
441    pub fn new(left: Obj, right: Obj) -> Self {
442        Min {
443            left: Box::new(left),
444            right: Box::new(right),
445        }
446    }
447}
448
449impl Union {
450    pub fn new(left: Obj, right: Obj) -> Self {
451        Union {
452            left: Box::new(left),
453            right: Box::new(right),
454        }
455    }
456}
457
458impl Intersect {
459    pub fn new(left: Obj, right: Obj) -> Self {
460        Intersect {
461            left: Box::new(left),
462            right: Box::new(right),
463        }
464    }
465}
466
467impl SetMinus {
468    pub fn new(left: Obj, right: Obj) -> Self {
469        SetMinus {
470            left: Box::new(left),
471            right: Box::new(right),
472        }
473    }
474}
475
476impl SetDiff {
477    pub fn new(left: Obj, right: Obj) -> Self {
478        SetDiff {
479            left: Box::new(left),
480            right: Box::new(right),
481        }
482    }
483}
484
485impl Cup {
486    pub fn new(left: Obj) -> Self {
487        Cup {
488            left: Box::new(left),
489        }
490    }
491}
492
493impl Cap {
494    pub fn new(left: Obj) -> Self {
495        Cap {
496            left: Box::new(left),
497        }
498    }
499}
500
501impl ListSet {
502    pub fn new(list: Vec<Obj>) -> Self {
503        ListSet {
504            list: list.into_iter().map(Box::new).collect(),
505        }
506    }
507}
508
509impl SetBuilder {
510    pub fn new(
511        param: String,
512        param_set: Obj,
513        facts: Vec<OrAndChainAtomicFact>,
514    ) -> Result<Self, RuntimeError> {
515        let set_builder = SetBuilder {
516            param,
517            param_set: Box::new(param_set),
518            facts,
519        };
520        check_set_builder_has_no_duplicate_set_builder_free_parameter(&set_builder)?;
521        Ok(set_builder)
522    }
523}
524
525impl PowerSet {
526    pub fn new(set: Obj) -> Self {
527        PowerSet { set: Box::new(set) }
528    }
529}
530
531impl Choose {
532    pub fn new(set: Obj) -> Self {
533        Choose { set: Box::new(set) }
534    }
535}
536
537impl CartDim {
538    pub fn new(set: Obj) -> Self {
539        CartDim { set: Box::new(set) }
540    }
541}
542
543impl Proj {
544    pub fn new(set: Obj, dim: Obj) -> Self {
545        Proj {
546            set: Box::new(set),
547            dim: Box::new(dim),
548        }
549    }
550}
551
552impl TupleDim {
553    pub fn new(dim: Obj) -> Self {
554        TupleDim { arg: Box::new(dim) }
555    }
556}
557
558impl Cart {
559    pub fn new(args: Vec<Obj>) -> Self {
560        let n = args.len();
561        if n < 2 {
562            panic!("Cart::new: expected at least 2 factors, got {n}");
563        }
564        Cart {
565            args: args.into_iter().map(Box::new).collect(),
566        }
567    }
568}
569
570impl Tuple {
571    pub fn new(elements: Vec<Obj>) -> Self {
572        let n = elements.len();
573        if n < 2 {
574            panic!("Tuple::new: expected at least 2 elements, got {n}");
575        }
576        Tuple {
577            args: elements.into_iter().map(Box::new).collect(),
578        }
579    }
580}
581
582impl Count {
583    pub fn new(set: Obj) -> Self {
584        Count { set: Box::new(set) }
585    }
586}
587
588impl Range {
589    pub fn new(start: Obj, end: Obj) -> Self {
590        Range {
591            start: Box::new(start),
592            end: Box::new(end),
593        }
594    }
595}
596
597impl ClosedRange {
598    pub fn new(start: Obj, end: Obj) -> Self {
599        ClosedRange {
600            start: Box::new(start),
601            end: Box::new(end),
602        }
603    }
604}
605
606impl FiniteSeqSet {
607    pub fn new(set: Obj, n: Obj) -> Self {
608        FiniteSeqSet {
609            set: Box::new(set),
610            n: Box::new(n),
611        }
612    }
613}
614
615impl SeqSet {
616    pub fn new(set: Obj) -> Self {
617        SeqSet { set: Box::new(set) }
618    }
619}
620
621impl FiniteSeqListObj {
622    pub fn new(objs: Vec<Obj>) -> Self {
623        FiniteSeqListObj {
624            objs: objs.into_iter().map(Box::new).collect(),
625        }
626    }
627}
628
629impl MatrixSet {
630    pub fn new(set: Obj, row_len: Obj, col_len: Obj) -> Self {
631        MatrixSet {
632            set: Box::new(set),
633            row_len: Box::new(row_len),
634            col_len: Box::new(col_len),
635        }
636    }
637}
638
639impl MatrixListObj {
640    pub fn new(rows: Vec<Vec<Obj>>) -> Self {
641        MatrixListObj {
642            rows: rows
643                .into_iter()
644                .map(|row| row.into_iter().map(Box::new).collect())
645                .collect(),
646        }
647    }
648}
649
650impl MatrixAdd {
651    pub fn new(left: Obj, right: Obj) -> Self {
652        MatrixAdd {
653            left: Box::new(left),
654            right: Box::new(right),
655        }
656    }
657}
658
659impl MatrixSub {
660    pub fn new(left: Obj, right: Obj) -> Self {
661        MatrixSub {
662            left: Box::new(left),
663            right: Box::new(right),
664        }
665    }
666}
667
668impl MatrixMul {
669    pub fn new(left: Obj, right: Obj) -> Self {
670        MatrixMul {
671            left: Box::new(left),
672            right: Box::new(right),
673        }
674    }
675}
676
677impl MatrixScalarMul {
678    pub fn new(scalar: Obj, matrix: Obj) -> Self {
679        MatrixScalarMul {
680            scalar: Box::new(scalar),
681            matrix: Box::new(matrix),
682        }
683    }
684}
685
686impl MatrixPow {
687    pub fn new(base: Obj, exponent: Obj) -> Self {
688        MatrixPow {
689            base: Box::new(base),
690            exponent: Box::new(exponent),
691        }
692    }
693}
694
695impl Sum {
696    pub fn new(start: Obj, end: Obj, func: Obj) -> Self {
697        Sum {
698            start: Box::new(start),
699            end: Box::new(end),
700            func: Box::new(func),
701        }
702    }
703}
704
705impl Product {
706    pub fn new(start: Obj, end: Obj, func: Obj) -> Self {
707        Product {
708            start: Box::new(start),
709            end: Box::new(end),
710            func: Box::new(func),
711        }
712    }
713}
714
715/// 算术运算符优先级:数值越小绑定越紧。^ / matrix ops =1, * / % / *. =2, + -=3;非算术=0 不参与括号。
716fn precedence(o: &Obj) -> u8 {
717    match o {
718        Obj::Add(_) | Obj::Sub(_) => 3,
719        Obj::Mul(_)
720        | Obj::Div(_)
721        | Obj::Mod(_)
722        | Obj::Max(_)
723        | Obj::Min(_)
724        | Obj::MatrixScalarMul(_) => 2,
725        Obj::Pow(_)
726        | Obj::Abs(_)
727        | Obj::Log(_)
728        | Obj::MatrixAdd(_)
729        | Obj::MatrixSub(_)
730        | Obj::MatrixMul(_)
731        | Obj::MatrixPow(_) => 1,
732        _ => 0,
733    }
734}
735
736impl fmt::Display for Obj {
737    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
738        self.fmt_with_precedence(f, 0)
739    }
740}
741
742impl Obj {
743    /// Precedence-aware display: add parens when a child binds looser than the parent (e.g. + under *).
744    /// For same-precedence `+`/`-`, pass a stricter bound (2) on Sub's sides and Add's right so
745    /// `a - (b + c)` and `a + (b - c)` do not print as the ambiguous `a - b + c` / `a + b - c`.
746    pub fn fmt_with_precedence(
747        &self,
748        f: &mut fmt::Formatter<'_>,
749        parent_precedent: u8,
750    ) -> fmt::Result {
751        let precedent = precedence(self);
752        let need_parens = parent_precedent != 0 && precedent != 0 && precedent > parent_precedent;
753        if need_parens {
754            write!(f, "{}", LEFT_BRACE)?;
755        }
756        match self {
757            Obj::Add(a) => {
758                a.left.fmt_with_precedence(f, 3)?;
759                write!(f, " {} ", ADD)?;
760                a.right.fmt_with_precedence(f, 2)?;
761            }
762            Obj::Sub(s) => {
763                s.left.fmt_with_precedence(f, 2)?;
764                write!(f, " {} ", SUB)?;
765                s.right.fmt_with_precedence(f, 2)?;
766            }
767            Obj::Mul(m) => {
768                m.left.fmt_with_precedence(f, 2)?;
769                write!(f, " {} ", MUL)?;
770                m.right.fmt_with_precedence(f, 2)?;
771            }
772            Obj::Div(d) => {
773                d.left.fmt_with_precedence(f, 2)?;
774                write!(f, " {} ", DIV)?;
775                d.right.fmt_with_precedence(f, 2)?;
776            }
777            Obj::Mod(m) => {
778                m.left.fmt_with_precedence(f, 2)?;
779                write!(f, " {} ", MOD)?;
780                m.right.fmt_with_precedence(f, 2)?;
781            }
782            Obj::Pow(p) => {
783                p.base.fmt_with_precedence(f, 1)?;
784                write!(f, " {} ", POW)?;
785                p.exponent.fmt_with_precedence(f, 1)?;
786            }
787            Obj::MatrixAdd(m) => {
788                m.left.fmt_with_precedence(f, 1)?;
789                write!(f, " {} ", MATRIX_ADD)?;
790                m.right.fmt_with_precedence(f, 1)?;
791            }
792            Obj::MatrixSub(m) => {
793                m.left.fmt_with_precedence(f, 1)?;
794                write!(f, " {} ", MATRIX_SUB)?;
795                m.right.fmt_with_precedence(f, 1)?;
796            }
797            Obj::MatrixMul(m) => {
798                m.left.fmt_with_precedence(f, 1)?;
799                write!(f, " {} ", MATRIX_MUL)?;
800                m.right.fmt_with_precedence(f, 1)?;
801            }
802            Obj::MatrixPow(m) => {
803                m.base.fmt_with_precedence(f, 1)?;
804                write!(f, " {} ", MATRIX_POW)?;
805                m.exponent.fmt_with_precedence(f, 1)?;
806            }
807            Obj::MatrixScalarMul(m) => {
808                m.scalar.fmt_with_precedence(f, 2)?;
809                write!(f, " {} ", MATRIX_SCALAR_MUL)?;
810                m.matrix.fmt_with_precedence(f, 2)?;
811            }
812            Obj::Abs(a) => {
813                write!(f, "{} {}", ABS, LEFT_BRACE)?;
814                a.arg.fmt_with_precedence(f, 0)?;
815                write!(f, "{}", RIGHT_BRACE)?;
816            }
817            Obj::Log(l) => {
818                write!(f, "{} {}", LOG, LEFT_BRACE)?;
819                l.base.fmt_with_precedence(f, 0)?;
820                write!(f, "{} ", COMMA)?;
821                l.arg.fmt_with_precedence(f, 0)?;
822                write!(f, "{}", RIGHT_BRACE)?;
823            }
824            Obj::Max(m) => {
825                write!(f, "{} {}", MAX, LEFT_BRACE)?;
826                m.left.fmt_with_precedence(f, 0)?;
827                write!(f, "{} ", COMMA)?;
828                m.right.fmt_with_precedence(f, 0)?;
829                write!(f, "{}", RIGHT_BRACE)?;
830            }
831            Obj::Min(m) => {
832                write!(f, "{} {}", MIN, LEFT_BRACE)?;
833                m.left.fmt_with_precedence(f, 0)?;
834                write!(f, "{} ", COMMA)?;
835                m.right.fmt_with_precedence(f, 0)?;
836                write!(f, "{}", RIGHT_BRACE)?;
837            }
838            Obj::Union(x) => write!(f, "{}", x)?,
839            Obj::Intersect(x) => write!(f, "{}", x)?,
840            Obj::SetMinus(x) => write!(f, "{}", x)?,
841            Obj::SetDiff(x) => write!(f, "{}", x)?,
842            Obj::Cup(x) => write!(f, "{}", x)?,
843            Obj::Cap(x) => write!(f, "{}", x)?,
844            Obj::Atom(x) => write!(f, "{}", x)?,
845            Obj::FnObj(x) => write!(f, "{}", x)?,
846            Obj::Number(x) => write!(f, "{}", x)?,
847            Obj::ListSet(x) => write!(f, "{}", x)?,
848            Obj::SetBuilder(x) => write!(f, "{}", x)?,
849            Obj::FnSet(x) => write!(f, "{}", x)?,
850            Obj::AnonymousFn(x) => write!(f, "{}", x)?,
851            Obj::StandardSet(standard_set) => write!(f, "{}", standard_set)?,
852            Obj::Cart(x) => write!(f, "{}", x)?,
853            Obj::CartDim(x) => write!(f, "{}", x)?,
854            Obj::Proj(x) => write!(f, "{}", x)?,
855            Obj::TupleDim(x) => write!(f, "{}", x)?,
856            Obj::Tuple(x) => write!(f, "{}", x)?,
857            Obj::Count(x) => write!(f, "{}", x)?,
858            Obj::Sum(x) => write!(f, "{}", x)?,
859            Obj::Product(x) => write!(f, "{}", x)?,
860            Obj::Range(x) => write!(f, "{}", x)?,
861            Obj::ClosedRange(x) => write!(f, "{}", x)?,
862            Obj::FiniteSeqSet(x) => write!(f, "{}", x)?,
863            Obj::SeqSet(x) => write!(f, "{}", x)?,
864            Obj::FiniteSeqListObj(x) => write!(f, "{}", x)?,
865            Obj::MatrixSet(x) => write!(f, "{}", x)?,
866            Obj::MatrixListObj(x) => write!(f, "{}", x)?,
867            Obj::PowerSet(x) => write!(f, "{}", x)?,
868            Obj::Choose(x) => write!(f, "{}", x)?,
869            Obj::ObjAtIndex(x) => write!(f, "{}", x)?,
870            Obj::FamilyObj(x) => write!(f, "{}", x)?,
871        }
872        if need_parens {
873            write!(f, "{}", RIGHT_BRACE)?;
874        }
875        Ok(())
876    }
877
878    pub fn replace_bound_identifier(self, from: &str, to: &str) -> Obj {
879        if from == to {
880            return self;
881        }
882        match self {
883            Obj::Atom(a) => Obj::Atom(a.replace_bound_identifier(from, to)),
884            Obj::FnObj(inner) => {
885                let head = replace_bound_identifier_in_fn_obj_head(*inner.head, from, to);
886                let body = inner
887                    .body
888                    .into_iter()
889                    .map(|group| {
890                        group
891                            .into_iter()
892                            .map(|b| Box::new(Obj::replace_bound_identifier(*b, from, to)))
893                            .collect()
894                    })
895                    .collect();
896                FnObj::new(head, body).into()
897            }
898            Obj::Number(n) => n.into(),
899            Obj::Add(x) => Add::new(
900                Obj::replace_bound_identifier(*x.left, from, to),
901                Obj::replace_bound_identifier(*x.right, from, to),
902            )
903            .into(),
904            Obj::Sub(x) => Sub::new(
905                Obj::replace_bound_identifier(*x.left, from, to),
906                Obj::replace_bound_identifier(*x.right, from, to),
907            )
908            .into(),
909            Obj::Mul(x) => Mul::new(
910                Obj::replace_bound_identifier(*x.left, from, to),
911                Obj::replace_bound_identifier(*x.right, from, to),
912            )
913            .into(),
914            Obj::Div(x) => Div::new(
915                Obj::replace_bound_identifier(*x.left, from, to),
916                Obj::replace_bound_identifier(*x.right, from, to),
917            )
918            .into(),
919            Obj::Mod(x) => Mod::new(
920                Obj::replace_bound_identifier(*x.left, from, to),
921                Obj::replace_bound_identifier(*x.right, from, to),
922            )
923            .into(),
924            Obj::Pow(x) => Pow::new(
925                Obj::replace_bound_identifier(*x.base, from, to),
926                Obj::replace_bound_identifier(*x.exponent, from, to),
927            )
928            .into(),
929            Obj::Abs(x) => Abs::new(Obj::replace_bound_identifier(*x.arg, from, to)).into(),
930            Obj::Log(x) => Log::new(
931                Obj::replace_bound_identifier(*x.base, from, to),
932                Obj::replace_bound_identifier(*x.arg, from, to),
933            )
934            .into(),
935            Obj::Max(x) => Max::new(
936                Obj::replace_bound_identifier(*x.left, from, to),
937                Obj::replace_bound_identifier(*x.right, from, to),
938            )
939            .into(),
940            Obj::Min(x) => Min::new(
941                Obj::replace_bound_identifier(*x.left, from, to),
942                Obj::replace_bound_identifier(*x.right, from, to),
943            )
944            .into(),
945            Obj::Union(x) => Union::new(
946                Obj::replace_bound_identifier(*x.left, from, to),
947                Obj::replace_bound_identifier(*x.right, from, to),
948            )
949            .into(),
950            Obj::Intersect(x) => Intersect::new(
951                Obj::replace_bound_identifier(*x.left, from, to),
952                Obj::replace_bound_identifier(*x.right, from, to),
953            )
954            .into(),
955            Obj::SetMinus(x) => SetMinus::new(
956                Obj::replace_bound_identifier(*x.left, from, to),
957                Obj::replace_bound_identifier(*x.right, from, to),
958            )
959            .into(),
960            Obj::SetDiff(x) => SetDiff::new(
961                Obj::replace_bound_identifier(*x.left, from, to),
962                Obj::replace_bound_identifier(*x.right, from, to),
963            )
964            .into(),
965            Obj::Cup(x) => Cup::new(Obj::replace_bound_identifier(*x.left, from, to)).into(),
966            Obj::Cap(x) => Cap::new(Obj::replace_bound_identifier(*x.left, from, to)).into(),
967            Obj::PowerSet(x) => {
968                PowerSet::new(Obj::replace_bound_identifier(*x.set, from, to)).into()
969            }
970            Obj::ListSet(x) => ListSet::new(
971                x.list
972                    .into_iter()
973                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
974                    .collect(),
975            )
976            .into(),
977            Obj::SetBuilder(sb) => {
978                let param = if sb.param == from {
979                    to.to_string()
980                } else {
981                    sb.param
982                };
983                let param_set = Obj::replace_bound_identifier(*sb.param_set, from, to);
984                let facts = sb
985                    .facts
986                    .into_iter()
987                    .map(|f| f.replace_bound_identifier(from, to))
988                    .collect();
989                Obj::SetBuilder(
990                    SetBuilder::new(param, param_set, facts)
991                        .expect("renaming a valid set builder preserves object scope validity"),
992                )
993            }
994            Obj::FnSet(fs) => {
995                let FnSet { body } = fs;
996                let FnSetBody {
997                    params_def_with_set,
998                    dom_facts,
999                    ret_set,
1000                } = body;
1001                let params_def_with_set = params_def_with_set
1002                    .into_iter()
1003                    .map(|pg| {
1004                        ParamGroupWithSet::new(
1005                            pg.params
1006                                .into_iter()
1007                                .map(|p| if p == from { to.to_string() } else { p })
1008                                .collect(),
1009                            Obj::replace_bound_identifier(pg.set, from, to),
1010                        )
1011                    })
1012                    .collect();
1013                let dom_facts = dom_facts
1014                    .into_iter()
1015                    .map(|f| f.replace_bound_identifier(from, to))
1016                    .collect();
1017                let ret_set = Obj::replace_bound_identifier(*ret_set, from, to);
1018                FnSet::new(params_def_with_set, dom_facts, ret_set)
1019                    .expect("renaming a valid fn set preserves object scope validity")
1020                    .into()
1021            }
1022            Obj::AnonymousFn(af) => {
1023                let AnonymousFn { body, equal_to } = af;
1024                let FnSetBody {
1025                    params_def_with_set,
1026                    dom_facts,
1027                    ret_set,
1028                } = body;
1029                let params_def_with_set = params_def_with_set
1030                    .into_iter()
1031                    .map(|pg| {
1032                        ParamGroupWithSet::new(
1033                            pg.params
1034                                .into_iter()
1035                                .map(|p| if p == from { to.to_string() } else { p })
1036                                .collect(),
1037                            Obj::replace_bound_identifier(pg.set, from, to),
1038                        )
1039                    })
1040                    .collect();
1041                let dom_facts = dom_facts
1042                    .into_iter()
1043                    .map(|f| f.replace_bound_identifier(from, to))
1044                    .collect();
1045                let ret_set = Obj::replace_bound_identifier(*ret_set, from, to);
1046                let equal_to = Obj::replace_bound_identifier(*equal_to, from, to);
1047                AnonymousFn::new(params_def_with_set, dom_facts, ret_set, equal_to)
1048                    .expect("renaming a valid anonymous fn preserves object scope validity")
1049                    .into()
1050            }
1051            Obj::Cart(c) => Cart::new(
1052                c.args
1053                    .into_iter()
1054                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
1055                    .collect(),
1056            )
1057            .into(),
1058            Obj::CartDim(x) => CartDim::new(Obj::replace_bound_identifier(*x.set, from, to)).into(),
1059            Obj::Proj(x) => Proj::new(
1060                Obj::replace_bound_identifier(*x.set, from, to),
1061                Obj::replace_bound_identifier(*x.dim, from, to),
1062            )
1063            .into(),
1064            Obj::TupleDim(x) => {
1065                TupleDim::new(Obj::replace_bound_identifier(*x.arg, from, to)).into()
1066            }
1067            Obj::Tuple(t) => Tuple::new(
1068                t.args
1069                    .into_iter()
1070                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
1071                    .collect(),
1072            )
1073            .into(),
1074            Obj::Count(x) => Count::new(Obj::replace_bound_identifier(*x.set, from, to)).into(),
1075            Obj::Sum(x) => Sum::new(
1076                Obj::replace_bound_identifier(*x.start, from, to),
1077                Obj::replace_bound_identifier(*x.end, from, to),
1078                Obj::replace_bound_identifier(*x.func, from, to),
1079            )
1080            .into(),
1081            Obj::Product(x) => Product::new(
1082                Obj::replace_bound_identifier(*x.start, from, to),
1083                Obj::replace_bound_identifier(*x.end, from, to),
1084                Obj::replace_bound_identifier(*x.func, from, to),
1085            )
1086            .into(),
1087            Obj::Range(x) => Range::new(
1088                Obj::replace_bound_identifier(*x.start, from, to),
1089                Obj::replace_bound_identifier(*x.end, from, to),
1090            )
1091            .into(),
1092            Obj::ClosedRange(x) => ClosedRange::new(
1093                Obj::replace_bound_identifier(*x.start, from, to),
1094                Obj::replace_bound_identifier(*x.end, from, to),
1095            )
1096            .into(),
1097            Obj::FiniteSeqSet(x) => FiniteSeqSet::new(
1098                Obj::replace_bound_identifier(*x.set, from, to),
1099                Obj::replace_bound_identifier(*x.n, from, to),
1100            )
1101            .into(),
1102            Obj::SeqSet(x) => SeqSet::new(Obj::replace_bound_identifier(*x.set, from, to)).into(),
1103            Obj::FiniteSeqListObj(x) => FiniteSeqListObj::new(
1104                x.objs
1105                    .into_iter()
1106                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
1107                    .collect(),
1108            )
1109            .into(),
1110            Obj::MatrixSet(x) => MatrixSet::new(
1111                Obj::replace_bound_identifier(*x.set, from, to),
1112                Obj::replace_bound_identifier(*x.row_len, from, to),
1113                Obj::replace_bound_identifier(*x.col_len, from, to),
1114            )
1115            .into(),
1116            Obj::MatrixListObj(x) => MatrixListObj::new(
1117                x.rows
1118                    .into_iter()
1119                    .map(|row| {
1120                        row.into_iter()
1121                            .map(|b| Obj::replace_bound_identifier(*b, from, to))
1122                            .collect()
1123                    })
1124                    .collect(),
1125            )
1126            .into(),
1127            Obj::MatrixAdd(x) => MatrixAdd::new(
1128                Obj::replace_bound_identifier(*x.left, from, to),
1129                Obj::replace_bound_identifier(*x.right, from, to),
1130            )
1131            .into(),
1132            Obj::MatrixSub(x) => MatrixSub::new(
1133                Obj::replace_bound_identifier(*x.left, from, to),
1134                Obj::replace_bound_identifier(*x.right, from, to),
1135            )
1136            .into(),
1137            Obj::MatrixMul(x) => MatrixMul::new(
1138                Obj::replace_bound_identifier(*x.left, from, to),
1139                Obj::replace_bound_identifier(*x.right, from, to),
1140            )
1141            .into(),
1142            Obj::MatrixScalarMul(x) => MatrixScalarMul::new(
1143                Obj::replace_bound_identifier(*x.scalar, from, to),
1144                Obj::replace_bound_identifier(*x.matrix, from, to),
1145            )
1146            .into(),
1147            Obj::MatrixPow(x) => MatrixPow::new(
1148                Obj::replace_bound_identifier(*x.base, from, to),
1149                Obj::replace_bound_identifier(*x.exponent, from, to),
1150            )
1151            .into(),
1152            Obj::Choose(x) => Choose::new(Obj::replace_bound_identifier(*x.set, from, to)).into(),
1153            Obj::ObjAtIndex(x) => ObjAtIndex::new(
1154                Obj::replace_bound_identifier(*x.obj, from, to),
1155                Obj::replace_bound_identifier(*x.index, from, to),
1156            )
1157            .into(),
1158            Obj::StandardSet(s) => s.into(),
1159            Obj::FamilyObj(f) => FamilyObj::new(
1160                f.name,
1161                f.params
1162                    .into_iter()
1163                    .map(|o| Obj::replace_bound_identifier(o, from, to))
1164                    .collect(),
1165            )
1166            .into(),
1167        }
1168    }
1169}
1170
1171/// Replace in identifier / `mod::name` name-shaped [`Obj`] values only.
1172fn replace_bound_identifier_in_name_obj(obj: Obj, from: &str, to: &str) -> Obj {
1173    if from == to {
1174        return obj;
1175    }
1176    match obj {
1177        Obj::Atom(AtomObj::Identifier(i)) => {
1178            if i.name == from {
1179                Identifier::new(to.to_string()).into()
1180            } else {
1181                Obj::Atom(AtomObj::Identifier(i))
1182            }
1183        }
1184        Obj::Atom(AtomObj::IdentifierWithMod(m)) => {
1185            let name = if m.name == from {
1186                to.to_string()
1187            } else {
1188                m.name
1189            };
1190            Obj::from(IdentifierWithMod::new(m.mod_name, name))
1191        }
1192        _ => obj,
1193    }
1194}
1195
1196fn replace_bound_identifier_in_fn_obj_head(head: FnObjHead, from: &str, to: &str) -> FnObjHead {
1197    if from == to {
1198        return head;
1199    }
1200    match head {
1201        FnObjHead::Identifier(i) => {
1202            FnObjHead::given_an_atom_return_a_fn_obj_head(replace_bound_identifier_in_name_obj(
1203                Obj::Atom(AtomObj::Identifier(i.clone())),
1204                from,
1205                to,
1206            ))
1207            .expect("name replace preserves fn head shape")
1208        }
1209        FnObjHead::IdentifierWithMod(m) => {
1210            FnObjHead::given_an_atom_return_a_fn_obj_head(replace_bound_identifier_in_name_obj(
1211                Obj::Atom(AtomObj::IdentifierWithMod(m.clone())),
1212                from,
1213                to,
1214            ))
1215            .expect("name replace preserves fn head shape")
1216        }
1217        FnObjHead::Forall(p) => {
1218            let name = if p.name == from {
1219                to.to_string()
1220            } else {
1221                p.name
1222            };
1223            ForallFreeParamObj::new(name).into()
1224        }
1225        FnObjHead::DefHeader(p) => {
1226            let name = if p.name == from {
1227                to.to_string()
1228            } else {
1229                p.name
1230            };
1231            DefHeaderFreeParamObj::new(name).into()
1232        }
1233        FnObjHead::Exist(p) => {
1234            let name = if p.name == from {
1235                to.to_string()
1236            } else {
1237                p.name
1238            };
1239            ExistFreeParamObj::new(name).into()
1240        }
1241        FnObjHead::SetBuilder(p) => {
1242            let name = if p.name == from {
1243                to.to_string()
1244            } else {
1245                p.name
1246            };
1247            SetBuilderFreeParamObj::new(name).into()
1248        }
1249        FnObjHead::FnSet(p) => {
1250            let name = if p.name == from {
1251                to.to_string()
1252            } else {
1253                p.name
1254            };
1255            FnSetFreeParamObj::new(name).into()
1256        }
1257        FnObjHead::AnonymousFnLiteral(a) => {
1258            let inner = (*a).clone();
1259            let replaced = Obj::replace_bound_identifier(Obj::AnonymousFn(inner), from, to);
1260            let Obj::AnonymousFn(new_af) = replaced else {
1261                unreachable!()
1262            };
1263            FnObjHead::AnonymousFnLiteral(Box::new(new_af))
1264        }
1265        FnObjHead::Induc(p) => {
1266            let name = if p.name == from {
1267                to.to_string()
1268            } else {
1269                p.name
1270            };
1271            ByInducFreeParamObj::new(name).into()
1272        }
1273        FnObjHead::DefAlgo(p) => {
1274            let name = if p.name == from {
1275                to.to_string()
1276            } else {
1277                p.name
1278            };
1279            DefAlgoFreeParamObj::new(name).into()
1280        }
1281    }
1282}
1283
1284impl fmt::Display for ObjAtIndex {
1285    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1286        write!(
1287            f,
1288            "{}{}{}{}",
1289            self.obj, LEFT_BRACKET, self.index, RIGHT_BRACKET
1290        )
1291    }
1292}
1293
1294impl fmt::Display for Choose {
1295    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1296        write!(
1297            f,
1298            "{}{}",
1299            CHOOSE,
1300            braced_vec_to_string(&vec![self.set.as_ref()])
1301        )
1302    }
1303}
1304
1305impl fmt::Display for Range {
1306    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1307        write!(
1308            f,
1309            "{}{}",
1310            RANGE,
1311            braced_vec_to_string(&vec![self.start.as_ref(), self.end.as_ref()])
1312        )
1313    }
1314}
1315
1316impl fmt::Display for ClosedRange {
1317    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1318        write!(
1319            f,
1320            "{}{}",
1321            CLOSED_RANGE,
1322            braced_vec_to_string(&vec![self.start.as_ref(), self.end.as_ref()])
1323        )
1324    }
1325}
1326
1327impl fmt::Display for FiniteSeqSet {
1328    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1329        write!(
1330            f,
1331            "{}{}",
1332            FINITE_SEQ,
1333            braced_vec_to_string(&vec![self.set.as_ref(), self.n.as_ref()])
1334        )
1335    }
1336}
1337
1338impl fmt::Display for SeqSet {
1339    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1340        write!(
1341            f,
1342            "{}{}",
1343            SEQ,
1344            braced_vec_to_string(&vec![self.set.as_ref()])
1345        )
1346    }
1347}
1348
1349impl fmt::Display for FiniteSeqListObj {
1350    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1351        write!(f, "{}", LEFT_BRACKET)?;
1352        for (i, o) in self.objs.iter().enumerate() {
1353            if i > 0 {
1354                write!(f, "{} ", COMMA)?;
1355            }
1356            write!(f, "{}", o)?;
1357        }
1358        write!(f, "{}", RIGHT_BRACKET)
1359    }
1360}
1361
1362impl fmt::Display for MatrixSet {
1363    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1364        write!(
1365            f,
1366            "{}{}",
1367            MATRIX,
1368            braced_vec_to_string(&vec![
1369                self.set.as_ref(),
1370                self.row_len.as_ref(),
1371                self.col_len.as_ref(),
1372            ])
1373        )
1374    }
1375}
1376
1377impl fmt::Display for MatrixListObj {
1378    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1379        write!(f, "{}", LEFT_BRACKET)?;
1380        for (ri, row) in self.rows.iter().enumerate() {
1381            if ri > 0 {
1382                write!(f, "{} ", COMMA)?;
1383            }
1384            write!(f, "{}", LEFT_BRACKET)?;
1385            for (ci, o) in row.iter().enumerate() {
1386                if ci > 0 {
1387                    write!(f, "{} ", COMMA)?;
1388                }
1389                write!(f, "{}", o)?;
1390            }
1391            write!(f, "{}", RIGHT_BRACKET)?;
1392        }
1393        write!(f, "{}", RIGHT_BRACKET)
1394    }
1395}
1396
1397impl fmt::Display for Count {
1398    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1399        write!(
1400            f,
1401            "{}{}",
1402            COUNT,
1403            braced_vec_to_string(&vec![self.set.as_ref()])
1404        )
1405    }
1406}
1407
1408impl fmt::Display for Sum {
1409    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1410        write!(
1411            f,
1412            "{}{}",
1413            SUM,
1414            braced_vec_to_string(&vec![
1415                self.start.as_ref(),
1416                self.end.as_ref(),
1417                self.func.as_ref(),
1418            ])
1419        )
1420    }
1421}
1422
1423impl fmt::Display for Product {
1424    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1425        write!(
1426            f,
1427            "{}{}",
1428            PRODUCT,
1429            braced_vec_to_string(&vec![
1430                self.start.as_ref(),
1431                self.end.as_ref(),
1432                self.func.as_ref(),
1433            ])
1434        )
1435    }
1436}
1437
1438impl fmt::Display for Tuple {
1439    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1440        write!(f, "{}", braced_vec_to_string(&self.args))
1441    }
1442}
1443
1444impl fmt::Display for CartDim {
1445    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1446        write!(
1447            f,
1448            "{}{}",
1449            CART_DIM,
1450            braced_vec_to_string(&vec![self.set.as_ref()])
1451        )
1452    }
1453}
1454
1455impl fmt::Display for Proj {
1456    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1457        write!(
1458            f,
1459            "{}{}",
1460            PROJ,
1461            braced_vec_to_string(&vec![self.set.as_ref(), self.dim.as_ref()])
1462        )
1463    }
1464}
1465
1466impl fmt::Display for TupleDim {
1467    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1468        write!(
1469            f,
1470            "{}{}",
1471            TUPLE_DIM,
1472            braced_vec_to_string(&vec![self.arg.as_ref()])
1473        )
1474    }
1475}
1476
1477impl fmt::Display for Identifier {
1478    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1479        write!(f, "{}", self.name)
1480    }
1481}
1482
1483impl fmt::Display for FnObj {
1484    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1485        write!(f, "{}", fn_obj_to_string(self.head.as_ref(), &self.body))
1486    }
1487}
1488
1489pub fn fn_obj_to_string(head: &FnObjHead, body: &Vec<Vec<Box<Obj>>>) -> String {
1490    let mut fn_obj_string = head.to_string();
1491    for group in body.iter() {
1492        fn_obj_string = format!("{}{}", fn_obj_string, braced_vec_to_string(group));
1493    }
1494    fn_obj_string
1495}
1496
1497impl fmt::Display for Number {
1498    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1499        write!(f, "{}", self.normalized_value)
1500    }
1501}
1502
1503impl fmt::Display for Add {
1504    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1505        write!(f, "{} {} {}", self.left, ADD, self.right)
1506    }
1507}
1508
1509impl fmt::Display for Sub {
1510    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1511        write!(f, "{} {} {}", self.left, SUB, self.right)
1512    }
1513}
1514
1515impl fmt::Display for Mul {
1516    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1517        write!(f, "{} {} {}", self.left, MUL, self.right)
1518    }
1519}
1520
1521impl fmt::Display for Div {
1522    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1523        write!(f, "{} {} {}", self.left, DIV, self.right)
1524    }
1525}
1526
1527impl fmt::Display for Mod {
1528    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1529        write!(f, "{} {} {}", self.left, MOD, self.right)
1530    }
1531}
1532
1533impl fmt::Display for Pow {
1534    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1535        write!(f, "{} {} {}", self.base, POW, self.exponent)
1536    }
1537}
1538
1539impl fmt::Display for MatrixAdd {
1540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1541        write!(f, "{} {} {}", self.left, MATRIX_ADD, self.right)
1542    }
1543}
1544
1545impl fmt::Display for MatrixSub {
1546    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1547        write!(f, "{} {} {}", self.left, MATRIX_SUB, self.right)
1548    }
1549}
1550
1551impl fmt::Display for MatrixMul {
1552    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1553        write!(f, "{} {} {}", self.left, MATRIX_MUL, self.right)
1554    }
1555}
1556
1557impl fmt::Display for MatrixScalarMul {
1558    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1559        write!(f, "{} {} {}", self.scalar, MATRIX_SCALAR_MUL, self.matrix)
1560    }
1561}
1562
1563impl fmt::Display for MatrixPow {
1564    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1565        write!(f, "{} {} {}", self.base, MATRIX_POW, self.exponent)
1566    }
1567}
1568
1569impl fmt::Display for Abs {
1570    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1571        write!(f, "{} {}{}{}", ABS, LEFT_BRACE, self.arg, RIGHT_BRACE)
1572    }
1573}
1574
1575impl fmt::Display for Log {
1576    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1577        write!(
1578            f,
1579            "{} {}{}{}{}{}",
1580            LOG, LEFT_BRACE, self.base, COMMA, self.arg, RIGHT_BRACE
1581        )
1582    }
1583}
1584
1585impl fmt::Display for Max {
1586    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1587        write!(
1588            f,
1589            "{} {}{}{}{}{}",
1590            MAX, LEFT_BRACE, self.left, COMMA, self.right, RIGHT_BRACE
1591        )
1592    }
1593}
1594
1595impl fmt::Display for Min {
1596    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1597        write!(
1598            f,
1599            "{} {}{}{}{}{}",
1600            MIN, LEFT_BRACE, self.left, COMMA, self.right, RIGHT_BRACE
1601        )
1602    }
1603}
1604
1605impl fmt::Display for Union {
1606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607        write!(
1608            f,
1609            "{}{}",
1610            UNION,
1611            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1612        )
1613    }
1614}
1615
1616impl fmt::Display for Intersect {
1617    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1618        write!(
1619            f,
1620            "{}{}",
1621            INTERSECT,
1622            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1623        )
1624    }
1625}
1626
1627impl fmt::Display for SetMinus {
1628    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1629        write!(
1630            f,
1631            "{}{}",
1632            SET_MINUS,
1633            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1634        )
1635    }
1636}
1637
1638impl fmt::Display for SetDiff {
1639    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1640        write!(
1641            f,
1642            "{}{}",
1643            SET_DIFF,
1644            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1645        )
1646    }
1647}
1648
1649impl fmt::Display for Cup {
1650    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1651        write!(
1652            f,
1653            "{}{}",
1654            CUP,
1655            braced_vec_to_string(&vec![self.left.as_ref()])
1656        )
1657    }
1658}
1659
1660impl fmt::Display for Cap {
1661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1662        write!(
1663            f,
1664            "{}{}",
1665            CAP,
1666            braced_vec_to_string(&vec![self.left.as_ref()])
1667        )
1668    }
1669}
1670
1671impl fmt::Display for IdentifierWithMod {
1672    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1673        write!(f, "{}{}{}", self.mod_name, MOD_SIGN, self.name)
1674    }
1675}
1676
1677impl fmt::Display for ListSet {
1678    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1679        write!(f, "{}", curly_braced_vec_to_string(&self.list))
1680    }
1681}
1682
1683impl fmt::Display for SetBuilder {
1684    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1685        write!(
1686            f,
1687            "{}{} {}{} {}{}",
1688            LEFT_CURLY_BRACE,
1689            self.param,
1690            self.param_set,
1691            COLON,
1692            vec_to_string_join_by_comma(&self.facts),
1693            RIGHT_CURLY_BRACE
1694        )
1695    }
1696}
1697
1698impl fmt::Display for Cart {
1699    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1700        write!(f, "{}{}", CART, braced_vec_to_string(&self.args))
1701    }
1702}
1703
1704impl fmt::Display for PowerSet {
1705    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1706        write!(
1707            f,
1708            "{}{}",
1709            POWER_SET,
1710            braced_vec_to_string(&vec![self.set.as_ref()])
1711        )
1712    }
1713}
1714
1715impl From<Identifier> for Obj {
1716    fn from(id: Identifier) -> Self {
1717        Obj::Atom(AtomObj::Identifier(id))
1718    }
1719}
1720
1721impl From<usize> for Obj {
1722    fn from(n: usize) -> Self {
1723        Number::new(n.to_string()).into()
1724    }
1725}
1726
1727impl From<Number> for Obj {
1728    fn from(n: Number) -> Self {
1729        Obj::Number(n)
1730    }
1731}
1732
1733impl From<Add> for Obj {
1734    fn from(a: Add) -> Self {
1735        Obj::Add(a)
1736    }
1737}
1738
1739impl From<MatrixAdd> for Obj {
1740    fn from(m: MatrixAdd) -> Self {
1741        Obj::MatrixAdd(m)
1742    }
1743}
1744
1745impl From<MatrixSub> for Obj {
1746    fn from(m: MatrixSub) -> Self {
1747        Obj::MatrixSub(m)
1748    }
1749}
1750
1751impl From<MatrixMul> for Obj {
1752    fn from(m: MatrixMul) -> Self {
1753        Obj::MatrixMul(m)
1754    }
1755}
1756
1757impl From<MatrixScalarMul> for Obj {
1758    fn from(m: MatrixScalarMul) -> Self {
1759        Obj::MatrixScalarMul(m)
1760    }
1761}
1762
1763impl From<MatrixPow> for Obj {
1764    fn from(m: MatrixPow) -> Self {
1765        Obj::MatrixPow(m)
1766    }
1767}
1768
1769impl From<Sub> for Obj {
1770    fn from(s: Sub) -> Self {
1771        Obj::Sub(s)
1772    }
1773}
1774
1775impl From<FnObj> for Obj {
1776    fn from(f: FnObj) -> Self {
1777        Obj::FnObj(f)
1778    }
1779}
1780
1781impl From<Mul> for Obj {
1782    fn from(m: Mul) -> Self {
1783        Obj::Mul(m)
1784    }
1785}
1786
1787impl From<Div> for Obj {
1788    fn from(d: Div) -> Self {
1789        Obj::Div(d)
1790    }
1791}
1792
1793impl From<Mod> for Obj {
1794    fn from(m: Mod) -> Self {
1795        Obj::Mod(m)
1796    }
1797}
1798
1799impl From<Pow> for Obj {
1800    fn from(p: Pow) -> Self {
1801        Obj::Pow(p)
1802    }
1803}
1804
1805impl From<Abs> for Obj {
1806    fn from(a: Abs) -> Self {
1807        Obj::Abs(a)
1808    }
1809}
1810
1811impl From<Log> for Obj {
1812    fn from(l: Log) -> Self {
1813        Obj::Log(l)
1814    }
1815}
1816
1817impl From<Max> for Obj {
1818    fn from(m: Max) -> Self {
1819        Obj::Max(m)
1820    }
1821}
1822
1823impl From<Min> for Obj {
1824    fn from(m: Min) -> Self {
1825        Obj::Min(m)
1826    }
1827}
1828
1829impl From<Union> for Obj {
1830    fn from(u: Union) -> Self {
1831        Obj::Union(u)
1832    }
1833}
1834
1835impl From<Intersect> for Obj {
1836    fn from(i: Intersect) -> Self {
1837        Obj::Intersect(i)
1838    }
1839}
1840
1841impl From<SetMinus> for Obj {
1842    fn from(s: SetMinus) -> Self {
1843        Obj::SetMinus(s)
1844    }
1845}
1846
1847impl From<SetDiff> for Obj {
1848    fn from(s: SetDiff) -> Self {
1849        Obj::SetDiff(s)
1850    }
1851}
1852
1853impl From<Cup> for Obj {
1854    fn from(c: Cup) -> Self {
1855        Obj::Cup(c)
1856    }
1857}
1858
1859impl From<Cap> for Obj {
1860    fn from(c: Cap) -> Self {
1861        Obj::Cap(c)
1862    }
1863}
1864
1865impl From<PowerSet> for Obj {
1866    fn from(p: PowerSet) -> Self {
1867        Obj::PowerSet(p)
1868    }
1869}
1870
1871impl From<ListSet> for Obj {
1872    fn from(l: ListSet) -> Self {
1873        Obj::ListSet(l)
1874    }
1875}
1876
1877impl From<SetBuilder> for Obj {
1878    fn from(s: SetBuilder) -> Self {
1879        Obj::SetBuilder(s)
1880    }
1881}
1882
1883impl From<Cart> for Obj {
1884    fn from(c: Cart) -> Self {
1885        Obj::Cart(c)
1886    }
1887}
1888
1889impl From<CartDim> for Obj {
1890    fn from(c: CartDim) -> Self {
1891        Obj::CartDim(c)
1892    }
1893}
1894
1895impl From<Proj> for Obj {
1896    fn from(p: Proj) -> Self {
1897        Obj::Proj(p)
1898    }
1899}
1900
1901impl From<TupleDim> for Obj {
1902    fn from(t: TupleDim) -> Self {
1903        Obj::TupleDim(t)
1904    }
1905}
1906
1907impl From<Tuple> for Obj {
1908    fn from(t: Tuple) -> Self {
1909        Obj::Tuple(t)
1910    }
1911}
1912
1913impl From<Count> for Obj {
1914    fn from(c: Count) -> Self {
1915        Obj::Count(c)
1916    }
1917}
1918
1919impl From<Sum> for Obj {
1920    fn from(s: Sum) -> Self {
1921        Obj::Sum(s)
1922    }
1923}
1924
1925impl From<Product> for Obj {
1926    fn from(p: Product) -> Self {
1927        Obj::Product(p)
1928    }
1929}
1930
1931impl From<Range> for Obj {
1932    fn from(r: Range) -> Self {
1933        Obj::Range(r)
1934    }
1935}
1936
1937impl From<ClosedRange> for Obj {
1938    fn from(r: ClosedRange) -> Self {
1939        Obj::ClosedRange(r)
1940    }
1941}
1942
1943impl From<FiniteSeqSet> for Obj {
1944    fn from(v: FiniteSeqSet) -> Self {
1945        Obj::FiniteSeqSet(v)
1946    }
1947}
1948
1949impl From<SeqSet> for Obj {
1950    fn from(v: SeqSet) -> Self {
1951        Obj::SeqSet(v)
1952    }
1953}
1954
1955impl From<FiniteSeqListObj> for Obj {
1956    fn from(v: FiniteSeqListObj) -> Self {
1957        Obj::FiniteSeqListObj(v)
1958    }
1959}
1960
1961impl From<MatrixSet> for Obj {
1962    fn from(v: MatrixSet) -> Self {
1963        Obj::MatrixSet(v)
1964    }
1965}
1966
1967impl From<MatrixListObj> for Obj {
1968    fn from(v: MatrixListObj) -> Self {
1969        Obj::MatrixListObj(v)
1970    }
1971}
1972
1973impl From<Choose> for Obj {
1974    fn from(c: Choose) -> Self {
1975        Obj::Choose(c)
1976    }
1977}
1978
1979impl From<ObjAtIndex> for Obj {
1980    fn from(o: ObjAtIndex) -> Self {
1981        Obj::ObjAtIndex(o)
1982    }
1983}
1984
1985impl From<IdentifierWithMod> for Obj {
1986    fn from(m: IdentifierWithMod) -> Self {
1987        Obj::Atom(AtomObj::IdentifierWithMod(m))
1988    }
1989}
1990
1991impl From<FamilyObj> for Obj {
1992    fn from(f: FamilyObj) -> Self {
1993        Obj::FamilyObj(f)
1994    }
1995}
1996
1997impl From<StandardSet> for Obj {
1998    fn from(s: StandardSet) -> Self {
1999        Obj::StandardSet(s)
2000    }
2001}
2002
2003impl Identifier {
2004    /// Build a name-shaped [`Obj`] (via [`AtomObj::Identifier`]). Parameter is String (not &str).
2005    pub fn mk(name: String) -> Obj {
2006        Identifier::new(name).into()
2007    }
2008}