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