Skip to main content

litex/obj/
obj.rs

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