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