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