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