Skip to main content

litex/obj/
obj.rs

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