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