Skip to main content

litex/obj/
obj.rs

1use super::standard_set::StandardSet;
2use crate::common::defaults::DEFAULT_MANGLED_FN_PARAM_PREFIX;
3use crate::prelude::*;
4use std::fmt;
5
6#[derive(Clone)]
7pub enum Obj {
8    Identifier(Identifier),
9    IdentifierWithMod(IdentifierWithMod),
10    FieldAccess(FieldAccess),
11    FieldAccessWithMod(FieldAccessWithMod),
12    FnObj(FnObj),
13    Number(Number),
14    Add(Add),
15    Sub(Sub),
16    Mul(Mul),
17    Div(Div),
18    Mod(Mod),
19    Pow(Pow),
20    Union(Union),
21    Intersect(Intersect),
22    SetMinus(SetMinus),
23    SetDiff(SetDiff),
24    Cup(Cup),
25    Cap(Cap),
26    PowerSet(PowerSet),
27    ListSet(ListSet),
28    SetBuilder(SetBuilder),
29    FnSet(FnSet),
30    Cart(Cart),
31    CartDim(CartDim),
32    Proj(Proj),
33    TupleDim(TupleDim),
34    Tuple(Tuple),
35    Count(Count),
36    Range(Range),
37    ClosedRange(ClosedRange),
38    Choose(Choose),
39    ObjAtIndex(ObjAtIndex),
40    StandardSet(StandardSet),
41    FamilyObj(FamilyObj),
42    StructObj(StructObj),
43}
44
45/// Instantiated family type: `family` name followed by argument objects (often sets).
46#[derive(Clone)]
47pub struct FamilyObj {
48    pub name: IdentifierOrIdentifierWithMod,
49    pub params: Vec<Obj>,
50}
51
52/// Instantiated struct type: `struct` name followed by argument objects (field types / indices).
53#[derive(Clone)]
54pub struct StructObj {
55    pub name: IdentifierOrIdentifierWithMod,
56    pub args: Vec<Obj>,
57}
58
59impl StructObj {
60    pub fn new(name: IdentifierOrIdentifierWithMod, args: Vec<Obj>) -> Self {
61        StructObj { name, args }
62    }
63}
64
65impl fmt::Display for FamilyObj {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        write!(
68            f,
69            "{} {}({})",
70            FAMILY,
71            self.name,
72            vec_to_string_join_by_comma(&self.params)
73        )
74    }
75}
76
77impl fmt::Display for StructObj {
78    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79        write!(
80            f,
81            "{} {}({})",
82            STRUCT,
83            self.name,
84            vec_to_string_join_by_comma(&self.args)
85        )
86    }
87}
88
89#[derive(Clone)]
90pub struct ObjAtIndex {
91    pub obj: Box<Obj>,
92    pub index: Box<Obj>,
93}
94
95#[derive(Clone)]
96pub struct Choose {
97    pub set: Box<Obj>,
98}
99
100#[derive(Clone)]
101pub struct PowerSet {
102    pub set: Box<Obj>,
103}
104
105#[derive(Clone)]
106pub struct Range {
107    pub start: Box<Obj>,
108    pub end: Box<Obj>,
109}
110
111#[derive(Clone)]
112pub struct ClosedRange {
113    pub start: Box<Obj>,
114    pub end: Box<Obj>,
115}
116
117#[derive(Clone)]
118pub struct Count {
119    pub set: Box<Obj>,
120}
121
122#[derive(Clone)]
123pub struct Tuple {
124    pub args: Vec<Box<Obj>>,
125}
126
127#[derive(Clone)]
128pub struct TupleDim {
129    pub arg: Box<Obj>,
130}
131
132#[derive(Clone)]
133pub struct CartDim {
134    pub set: Box<Obj>,
135}
136
137#[derive(Clone)]
138pub struct Proj {
139    pub set: Box<Obj>,
140    pub dim: Box<Obj>,
141}
142
143#[derive(Clone)]
144pub struct FnObj {
145    pub head: Box<Atom>,
146    pub body: Vec<Vec<Box<Obj>>>,
147}
148
149#[derive(Clone)]
150pub struct Number {
151    pub normalized_value: String,
152}
153
154#[derive(Clone)]
155pub struct Add {
156    pub left: Box<Obj>,
157    pub right: Box<Obj>,
158}
159
160#[derive(Clone)]
161pub struct Sub {
162    pub left: Box<Obj>,
163    pub right: Box<Obj>,
164}
165
166#[derive(Clone)]
167pub struct Mul {
168    pub left: Box<Obj>,
169    pub right: Box<Obj>,
170}
171
172#[derive(Clone)]
173pub struct Div {
174    pub left: Box<Obj>,
175    pub right: Box<Obj>,
176}
177
178#[derive(Clone)]
179pub struct Mod {
180    pub left: Box<Obj>,
181    pub right: Box<Obj>,
182}
183
184#[derive(Clone)]
185pub struct Pow {
186    pub base: Box<Obj>,
187    pub exponent: Box<Obj>,
188}
189
190#[derive(Clone)]
191pub struct Union {
192    pub left: Box<Obj>,
193    pub right: Box<Obj>,
194}
195
196#[derive(Clone)]
197pub struct Intersect {
198    pub left: Box<Obj>,
199    pub right: Box<Obj>,
200}
201
202#[derive(Clone)]
203pub struct SetMinus {
204    pub left: Box<Obj>,
205    pub right: Box<Obj>,
206}
207
208#[derive(Clone)]
209pub struct SetDiff {
210    pub left: Box<Obj>,
211    pub right: Box<Obj>,
212}
213
214#[derive(Clone)]
215pub struct Cup {
216    pub left: Box<Obj>,
217}
218
219#[derive(Clone)]
220pub struct Cap {
221    pub left: Box<Obj>,
222}
223
224#[derive(Clone)]
225pub struct ListSet {
226    pub list: Vec<Box<Obj>>,
227}
228
229#[derive(Clone)]
230pub struct SetBuilder {
231    pub param: String,
232    pub param_set: Box<Obj>,
233    pub facts: Vec<OrAndChainAtomicFact>,
234}
235
236#[derive(Clone)]
237pub struct FnSet {
238    pub params_def_with_set: Vec<ParamGroupWithSet>,
239    pub dom_facts: Vec<OrAndChainAtomicFact>,
240    pub ret_set: Box<Obj>,
241}
242
243#[derive(Clone)]
244pub struct Cart {
245    pub args: Vec<Box<Obj>>,
246}
247
248impl ObjAtIndex {
249    pub fn new(obj: Obj, index: Obj) -> Self {
250        ObjAtIndex {
251            obj: Box::new(obj),
252            index: Box::new(index),
253        }
254    }
255}
256
257impl FnObj {
258    pub fn new(head: Atom, body: Vec<Vec<Box<Obj>>>) -> Self {
259        FnObj {
260            head: Box::new(head),
261            body,
262        }
263    }
264}
265
266impl Number {
267    pub fn new(value: String) -> Self {
268        Number {
269            normalized_value: normalize_decimal_number_string(&value),
270        }
271    }
272}
273
274impl Add {
275    pub fn new(left: Obj, right: Obj) -> Self {
276        Add {
277            left: Box::new(left),
278            right: Box::new(right),
279        }
280    }
281}
282
283impl Sub {
284    pub fn new(left: Obj, right: Obj) -> Self {
285        Sub {
286            left: Box::new(left),
287            right: Box::new(right),
288        }
289    }
290}
291
292impl Mul {
293    pub fn new(left: Obj, right: Obj) -> Self {
294        Mul {
295            left: Box::new(left),
296            right: Box::new(right),
297        }
298    }
299}
300
301impl Div {
302    pub fn new(left: Obj, right: Obj) -> Self {
303        Div {
304            left: Box::new(left),
305            right: Box::new(right),
306        }
307    }
308}
309
310impl Mod {
311    pub fn new(left: Obj, right: Obj) -> Self {
312        Mod {
313            left: Box::new(left),
314            right: Box::new(right),
315        }
316    }
317}
318
319impl Pow {
320    pub fn new(base: Obj, exponent: Obj) -> Self {
321        Pow {
322            base: Box::new(base),
323            exponent: Box::new(exponent),
324        }
325    }
326}
327
328impl Union {
329    pub fn new(left: Obj, right: Obj) -> Self {
330        Union {
331            left: Box::new(left),
332            right: Box::new(right),
333        }
334    }
335}
336
337impl Intersect {
338    pub fn new(left: Obj, right: Obj) -> Self {
339        Intersect {
340            left: Box::new(left),
341            right: Box::new(right),
342        }
343    }
344}
345
346impl SetMinus {
347    pub fn new(left: Obj, right: Obj) -> Self {
348        SetMinus {
349            left: Box::new(left),
350            right: Box::new(right),
351        }
352    }
353}
354
355impl SetDiff {
356    pub fn new(left: Obj, right: Obj) -> Self {
357        SetDiff {
358            left: Box::new(left),
359            right: Box::new(right),
360        }
361    }
362}
363
364impl Cup {
365    pub fn new(left: Obj) -> Self {
366        Cup {
367            left: Box::new(left),
368        }
369    }
370}
371
372impl Cap {
373    pub fn new(left: Obj) -> Self {
374        Cap {
375            left: Box::new(left),
376        }
377    }
378}
379
380impl ListSet {
381    pub fn new(list: Vec<Obj>) -> Self {
382        ListSet {
383            list: list.into_iter().map(Box::new).collect(),
384        }
385    }
386}
387
388impl SetBuilder {
389    pub fn new(param: String, param_set: Obj, facts: Vec<OrAndChainAtomicFact>) -> Self {
390        SetBuilder {
391            param: param,
392            param_set: Box::new(param_set),
393            facts,
394        }
395    }
396
397    // Same storage shape as parsing `{user cart(...): ...}`: bound name is `__` + user (facts rewritten).
398    pub fn new_with_mangled_name(
399        user_param: String,
400        param_set: Obj,
401        facts: Vec<OrAndChainAtomicFact>,
402    ) -> Self {
403        let mangled = format!("{}{}", DEFAULT_MANGLED_FN_PARAM_PREFIX, user_param);
404        let param_set = Obj::replace_bound_identifier(param_set, &user_param, &mangled);
405        let facts = facts
406            .into_iter()
407            .map(|f| f.replace_bound_identifier(&user_param, &mangled))
408            .collect();
409        Self::new(mangled, param_set, facts)
410    }
411}
412
413impl FnSet {
414    pub fn new(
415        params_and_their_sets: Vec<ParamGroupWithSet>,
416        dom_facts: Vec<OrAndChainAtomicFact>,
417        ret_set: Obj,
418    ) -> Self {
419        FnSet {
420            params_def_with_set: params_and_their_sets,
421            dom_facts,
422            ret_set: Box::new(ret_set),
423        }
424    }
425
426    pub fn get_params(&self) -> Vec<String> {
427        let mut ret = Vec::with_capacity(ParamGroupWithSet::number_of_params(
428            &self.params_def_with_set,
429        ));
430        for param_def_with_set in &self.params_def_with_set {
431            ret.extend(param_def_with_set.params.iter().cloned());
432        }
433        ret
434    }
435}
436
437impl PowerSet {
438    pub fn new(set: Obj) -> Self {
439        PowerSet { set: Box::new(set) }
440    }
441}
442
443impl Choose {
444    pub fn new(set: Obj) -> Self {
445        Choose { set: Box::new(set) }
446    }
447}
448
449impl CartDim {
450    pub fn new(set: Obj) -> Self {
451        CartDim { set: Box::new(set) }
452    }
453}
454
455impl Proj {
456    pub fn new(set: Obj, dim: Obj) -> Self {
457        Proj {
458            set: Box::new(set),
459            dim: Box::new(dim),
460        }
461    }
462}
463
464impl TupleDim {
465    pub fn new(dim: Obj) -> Self {
466        TupleDim { arg: Box::new(dim) }
467    }
468}
469
470impl Cart {
471    pub fn new(args: Vec<Obj>) -> Self {
472        let n = args.len();
473        if n < 2 {
474            panic!("Cart::new: expected at least 2 factors, got {n}");
475        }
476        Cart {
477            args: args.into_iter().map(Box::new).collect(),
478        }
479    }
480}
481
482impl Tuple {
483    pub fn new(elements: Vec<Obj>) -> Self {
484        let n = elements.len();
485        if n < 2 {
486            panic!("Tuple::new: expected at least 2 elements, got {n}");
487        }
488        Tuple {
489            args: elements.into_iter().map(Box::new).collect(),
490        }
491    }
492}
493
494impl Count {
495    pub fn new(set: Obj) -> Self {
496        Count { set: Box::new(set) }
497    }
498}
499
500impl Range {
501    pub fn new(start: Obj, end: Obj) -> Self {
502        Range {
503            start: Box::new(start),
504            end: Box::new(end),
505        }
506    }
507}
508
509impl ClosedRange {
510    pub fn new(start: Obj, end: Obj) -> Self {
511        ClosedRange {
512            start: Box::new(start),
513            end: Box::new(end),
514        }
515    }
516}
517
518/// 算术运算符优先级:数值越小绑定越紧。^=1, * / %=2, + -=3;非算术=0 不参与括号。
519fn precedence(o: &Obj) -> u8 {
520    match o {
521        Obj::Add(_) | Obj::Sub(_) => 3,
522        Obj::Mul(_) | Obj::Div(_) | Obj::Mod(_) => 2,
523        Obj::Pow(_) => 1,
524        _ => 0,
525    }
526}
527
528impl fmt::Display for Obj {
529    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
530        self.fmt_with_precedence(f, 0)
531    }
532}
533
534impl Obj {
535    /// 按优先级输出:当子表达式优先级低于父节点时自动加括号,例如 ^ 下出现 + 则写成 (a + b)。
536    pub fn fmt_with_precedence(
537        &self,
538        f: &mut fmt::Formatter<'_>,
539        parent_precedent: u8,
540    ) -> fmt::Result {
541        let precedent = precedence(self);
542        let need_parens = parent_precedent != 0 && precedent != 0 && precedent > parent_precedent;
543        if need_parens {
544            write!(f, "{}", LEFT_BRACE)?;
545        }
546        match self {
547            Obj::Add(a) => {
548                a.left.fmt_with_precedence(f, 3)?;
549                write!(f, " {} ", ADD)?;
550                a.right.fmt_with_precedence(f, 3)?;
551            }
552            Obj::Sub(s) => {
553                s.left.fmt_with_precedence(f, 3)?;
554                write!(f, " {} ", SUB)?;
555                s.right.fmt_with_precedence(f, 3)?;
556            }
557            Obj::Mul(m) => {
558                m.left.fmt_with_precedence(f, 2)?;
559                write!(f, " {} ", MUL)?;
560                m.right.fmt_with_precedence(f, 2)?;
561            }
562            Obj::Div(d) => {
563                d.left.fmt_with_precedence(f, 2)?;
564                write!(f, " {} ", DIV)?;
565                d.right.fmt_with_precedence(f, 2)?;
566            }
567            Obj::Mod(m) => {
568                m.left.fmt_with_precedence(f, 2)?;
569                write!(f, " {} ", MOD)?;
570                m.right.fmt_with_precedence(f, 2)?;
571            }
572            Obj::Pow(p) => {
573                p.base.fmt_with_precedence(f, 1)?;
574                write!(f, " {} ", POW)?;
575                p.exponent.fmt_with_precedence(f, 1)?;
576            }
577            Obj::Union(x) => write!(f, "{}", x)?,
578            Obj::Intersect(x) => write!(f, "{}", x)?,
579            Obj::SetMinus(x) => write!(f, "{}", x)?,
580            Obj::SetDiff(x) => write!(f, "{}", x)?,
581            Obj::Cup(x) => write!(f, "{}", x)?,
582            Obj::Cap(x) => write!(f, "{}", x)?,
583            Obj::Identifier(x) => write!(f, "{}", x)?,
584            Obj::IdentifierWithMod(x) => write!(f, "{}", x)?,
585            Obj::FieldAccess(x) => write!(f, "{}", x)?,
586            Obj::FieldAccessWithMod(x) => write!(f, "{}", x)?,
587            Obj::FnObj(x) => write!(f, "{}", x)?,
588            Obj::Number(x) => write!(f, "{}", x)?,
589            Obj::ListSet(x) => write!(f, "{}", x)?,
590            Obj::SetBuilder(x) => write!(f, "{}", x)?,
591            Obj::FnSet(x) => write!(f, "{}", x)?,
592            Obj::StandardSet(standard_set) => write!(f, "{}", standard_set)?,
593            Obj::Cart(x) => write!(f, "{}", x)?,
594            Obj::CartDim(x) => write!(f, "{}", x)?,
595            Obj::Proj(x) => write!(f, "{}", x)?,
596            Obj::TupleDim(x) => write!(f, "{}", x)?,
597            Obj::Tuple(x) => write!(f, "{}", x)?,
598            Obj::Count(x) => write!(f, "{}", x)?,
599            Obj::Range(x) => write!(f, "{}", x)?,
600            Obj::ClosedRange(x) => write!(f, "{}", x)?,
601            Obj::PowerSet(x) => write!(f, "{}", x)?,
602            Obj::Choose(x) => write!(f, "{}", x)?,
603            Obj::ObjAtIndex(x) => write!(f, "{}", x)?,
604            Obj::FamilyObj(x) => write!(f, "{}", x)?,
605            Obj::StructObj(x) => write!(f, "{}", x)?,
606        }
607        if need_parens {
608            write!(f, "{}", RIGHT_BRACE)?;
609        }
610        Ok(())
611    }
612
613    pub fn replace_bound_identifier(self, from: &str, to: &str) -> Obj {
614        if from == to {
615            return self;
616        }
617        match self {
618            Obj::Identifier(i) => {
619                if i.name == from {
620                    Obj::Identifier(Identifier::new(to.to_string()))
621                } else {
622                    Obj::Identifier(i)
623                }
624            }
625            Obj::IdentifierWithMod(m) => {
626                let name = if m.name == from {
627                    to.to_string()
628                } else {
629                    m.name
630                };
631                Obj::IdentifierWithMod(IdentifierWithMod::new(m.mod_name, name))
632            }
633            Obj::FieldAccess(f) => {
634                let name = if f.name == from {
635                    to.to_string()
636                } else {
637                    f.name
638                };
639                Obj::FieldAccess(FieldAccess::new(name, f.field))
640            }
641            Obj::FieldAccessWithMod(f) => {
642                let name = if f.name == from {
643                    to.to_string()
644                } else {
645                    f.name
646                };
647                Obj::FieldAccessWithMod(FieldAccessWithMod::new(f.mod_name, name, f.field))
648            }
649            Obj::FnObj(inner) => {
650                let head = Box::new(replace_bound_identifier_in_atom(*inner.head, from, to));
651                let body = inner
652                    .body
653                    .into_iter()
654                    .map(|group| {
655                        group
656                            .into_iter()
657                            .map(|b| Box::new(Obj::replace_bound_identifier(*b, from, to)))
658                            .collect()
659                    })
660                    .collect();
661                Obj::FnObj(FnObj { head, body })
662            }
663            Obj::Number(n) => Obj::Number(n),
664            Obj::Add(x) => Obj::Add(Add::new(
665                Obj::replace_bound_identifier(*x.left, from, to),
666                Obj::replace_bound_identifier(*x.right, from, to),
667            )),
668            Obj::Sub(x) => Obj::Sub(Sub::new(
669                Obj::replace_bound_identifier(*x.left, from, to),
670                Obj::replace_bound_identifier(*x.right, from, to),
671            )),
672            Obj::Mul(x) => Obj::Mul(Mul::new(
673                Obj::replace_bound_identifier(*x.left, from, to),
674                Obj::replace_bound_identifier(*x.right, from, to),
675            )),
676            Obj::Div(x) => Obj::Div(Div::new(
677                Obj::replace_bound_identifier(*x.left, from, to),
678                Obj::replace_bound_identifier(*x.right, from, to),
679            )),
680            Obj::Mod(x) => Obj::Mod(Mod::new(
681                Obj::replace_bound_identifier(*x.left, from, to),
682                Obj::replace_bound_identifier(*x.right, from, to),
683            )),
684            Obj::Pow(x) => Obj::Pow(Pow::new(
685                Obj::replace_bound_identifier(*x.base, from, to),
686                Obj::replace_bound_identifier(*x.exponent, from, to),
687            )),
688            Obj::Union(x) => Obj::Union(Union::new(
689                Obj::replace_bound_identifier(*x.left, from, to),
690                Obj::replace_bound_identifier(*x.right, from, to),
691            )),
692            Obj::Intersect(x) => Obj::Intersect(Intersect::new(
693                Obj::replace_bound_identifier(*x.left, from, to),
694                Obj::replace_bound_identifier(*x.right, from, to),
695            )),
696            Obj::SetMinus(x) => Obj::SetMinus(SetMinus::new(
697                Obj::replace_bound_identifier(*x.left, from, to),
698                Obj::replace_bound_identifier(*x.right, from, to),
699            )),
700            Obj::SetDiff(x) => Obj::SetDiff(SetDiff::new(
701                Obj::replace_bound_identifier(*x.left, from, to),
702                Obj::replace_bound_identifier(*x.right, from, to),
703            )),
704            Obj::Cup(x) => Obj::Cup(Cup::new(Obj::replace_bound_identifier(*x.left, from, to))),
705            Obj::Cap(x) => Obj::Cap(Cap::new(Obj::replace_bound_identifier(*x.left, from, to))),
706            Obj::PowerSet(x) => Obj::PowerSet(PowerSet::new(Obj::replace_bound_identifier(
707                *x.set, from, to,
708            ))),
709            Obj::ListSet(x) => Obj::ListSet(ListSet::new(
710                x.list
711                    .into_iter()
712                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
713                    .collect(),
714            )),
715            Obj::SetBuilder(sb) => {
716                let param = if sb.param == from {
717                    to.to_string()
718                } else {
719                    sb.param
720                };
721                let param_set = Box::new(Obj::replace_bound_identifier(*sb.param_set, from, to));
722                let facts = sb
723                    .facts
724                    .into_iter()
725                    .map(|f| f.replace_bound_identifier(from, to))
726                    .collect();
727                Obj::SetBuilder(SetBuilder {
728                    param,
729                    param_set,
730                    facts,
731                })
732            }
733            Obj::FnSet(fs) => {
734                let params_def_with_set = fs
735                    .params_def_with_set
736                    .into_iter()
737                    .map(|pg| ParamGroupWithSet {
738                        params: pg
739                            .params
740                            .into_iter()
741                            .map(|p| {
742                                if p == from {
743                                    to.to_string()
744                                } else {
745                                    p
746                                }
747                            })
748                            .collect(),
749                        set: Obj::replace_bound_identifier(pg.set, from, to),
750                    })
751                    .collect();
752                let dom_facts = fs
753                    .dom_facts
754                    .into_iter()
755                    .map(|f| f.replace_bound_identifier(from, to))
756                    .collect();
757                let ret_set = Obj::replace_bound_identifier(*fs.ret_set, from, to);
758                Obj::FnSet(FnSet::new(params_def_with_set, dom_facts, ret_set))
759            }
760            Obj::Cart(c) => Obj::Cart(Cart::new(
761                c.args
762                    .into_iter()
763                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
764                    .collect(),
765            )),
766            Obj::CartDim(x) => Obj::CartDim(CartDim::new(Obj::replace_bound_identifier(
767                *x.set, from, to,
768            ))),
769            Obj::Proj(x) => Obj::Proj(Proj::new(
770                Obj::replace_bound_identifier(*x.set, from, to),
771                Obj::replace_bound_identifier(*x.dim, from, to),
772            )),
773            Obj::TupleDim(x) => Obj::TupleDim(TupleDim::new(Obj::replace_bound_identifier(
774                *x.arg, from, to,
775            ))),
776            Obj::Tuple(t) => Obj::Tuple(Tuple::new(
777                t.args
778                    .into_iter()
779                    .map(|b| Obj::replace_bound_identifier(*b, from, to))
780                    .collect(),
781            )),
782            Obj::Count(x) => Obj::Count(Count::new(Obj::replace_bound_identifier(*x.set, from, to))),
783            Obj::Range(x) => Obj::Range(Range::new(
784                Obj::replace_bound_identifier(*x.start, from, to),
785                Obj::replace_bound_identifier(*x.end, from, to),
786            )),
787            Obj::ClosedRange(x) => Obj::ClosedRange(ClosedRange::new(
788                Obj::replace_bound_identifier(*x.start, from, to),
789                Obj::replace_bound_identifier(*x.end, from, to),
790            )),
791            Obj::Choose(x) => Obj::Choose(Choose::new(Obj::replace_bound_identifier(*x.set, from, to))),
792            Obj::ObjAtIndex(x) => Obj::ObjAtIndex(ObjAtIndex::new(
793                Obj::replace_bound_identifier(*x.obj, from, to),
794                Obj::replace_bound_identifier(*x.index, from, to),
795            )),
796            Obj::StandardSet(s) => Obj::StandardSet(s),
797            Obj::FamilyObj(f) => Obj::FamilyObj(FamilyObj {
798                name: f.name,
799                params: f
800                    .params
801                    .into_iter()
802                    .map(|o| Obj::replace_bound_identifier(o, from, to))
803                    .collect(),
804            }),
805            Obj::StructObj(s) => Obj::StructObj(StructObj {
806                name: s.name,
807                args: s
808                    .args
809                    .into_iter()
810                    .map(|o| Obj::replace_bound_identifier(o, from, to))
811                    .collect(),
812            }),
813        }
814    }
815}
816
817fn replace_bound_identifier_in_atom(atom: Atom, from: &str, to: &str) -> Atom {
818    if from == to {
819        return atom;
820    }
821    match atom {
822        Atom::Identifier(i) => {
823            if i.name == from {
824                Atom::Identifier(Identifier::new(to.to_string()))
825            } else {
826                Atom::Identifier(i)
827            }
828        }
829        Atom::IdentifierWithMod(m) => {
830            let name = if m.name == from {
831                to.to_string()
832            } else {
833                m.name
834            };
835            Atom::IdentifierWithMod(IdentifierWithMod::new(m.mod_name, name))
836        }
837        Atom::FieldAccess(f) => {
838            let name = if f.name == from {
839                to.to_string()
840            } else {
841                f.name
842            };
843            Atom::FieldAccess(FieldAccess::new(name, f.field))
844        }
845        Atom::FieldAccessWithMod(f) => {
846            let name = if f.name == from {
847                to.to_string()
848            } else {
849                f.name
850            };
851            Atom::FieldAccessWithMod(FieldAccessWithMod::new(f.mod_name, name, f.field))
852        }
853    }
854}
855
856impl fmt::Display for ObjAtIndex {
857    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
858        write!(
859            f,
860            "{}{}{}{}",
861            self.obj, LEFT_BRACKET, self.index, RIGHT_BRACKET
862        )
863    }
864}
865
866impl fmt::Display for Choose {
867    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
868        write!(
869            f,
870            "{}{}",
871            CHOOSE,
872            braced_vec_to_string(&vec![self.set.as_ref()])
873        )
874    }
875}
876
877impl fmt::Display for Range {
878    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
879        write!(
880            f,
881            "{}{}",
882            RANGE,
883            braced_vec_to_string(&vec![self.start.as_ref(), self.end.as_ref()])
884        )
885    }
886}
887
888impl fmt::Display for ClosedRange {
889    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
890        write!(
891            f,
892            "{}{}",
893            CLOSED_RANGE,
894            braced_vec_to_string(&vec![self.start.as_ref(), self.end.as_ref()])
895        )
896    }
897}
898
899impl fmt::Display for Count {
900    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
901        write!(
902            f,
903            "{}{}",
904            COUNT,
905            braced_vec_to_string(&vec![self.set.as_ref()])
906        )
907    }
908}
909
910impl fmt::Display for Tuple {
911    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
912        write!(f, "{}", braced_vec_to_string(&self.args))
913    }
914}
915
916impl fmt::Display for CartDim {
917    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
918        write!(
919            f,
920            "{}{}",
921            CART_DIM,
922            braced_vec_to_string(&vec![self.set.as_ref()])
923        )
924    }
925}
926
927impl fmt::Display for Proj {
928    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
929        write!(
930            f,
931            "{}{}",
932            PROJ,
933            braced_vec_to_string(&vec![self.set.as_ref(), self.dim.as_ref()])
934        )
935    }
936}
937
938impl fmt::Display for TupleDim {
939    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
940        write!(
941            f,
942            "{}{}",
943            TUPLE_DIM,
944            braced_vec_to_string(&vec![self.arg.as_ref()])
945        )
946    }
947}
948
949impl fmt::Display for Identifier {
950    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
951        write!(f, "{}", self.name)
952    }
953}
954
955impl fmt::Display for FnObj {
956    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
957        write!(f, "{}", fn_obj_to_string(self.head.as_ref(), &self.body))
958    }
959}
960
961pub fn fn_obj_to_string(head: &Atom, body: &Vec<Vec<Box<Obj>>>) -> String {
962    let mut fn_obj_string = head.to_string();
963    for group in body.iter() {
964        fn_obj_string = format!("{}{}", fn_obj_string, braced_vec_to_string(group));
965    }
966    fn_obj_string
967}
968
969impl fmt::Display for Number {
970    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971        write!(f, "{}", self.normalized_value)
972    }
973}
974
975impl fmt::Display for Add {
976    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977        write!(f, "{} {} {}", self.left, ADD, self.right)
978    }
979}
980
981impl fmt::Display for Sub {
982    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
983        write!(f, "{} {} {}", self.left, SUB, self.right)
984    }
985}
986
987impl fmt::Display for Mul {
988    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989        write!(f, "{} {} {}", self.left, MUL, self.right)
990    }
991}
992
993impl fmt::Display for Div {
994    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
995        write!(f, "{} {} {}", self.left, DIV, self.right)
996    }
997}
998
999impl fmt::Display for Mod {
1000    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1001        write!(f, "{} {} {}", self.left, MOD, self.right)
1002    }
1003}
1004
1005impl fmt::Display for Pow {
1006    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1007        write!(f, "{} {} {}", self.base, POW, self.exponent)
1008    }
1009}
1010
1011impl fmt::Display for Union {
1012    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1013        write!(
1014            f,
1015            "{}{}",
1016            UNION,
1017            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1018        )
1019    }
1020}
1021
1022impl fmt::Display for Intersect {
1023    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1024        write!(
1025            f,
1026            "{}{}",
1027            INTERSECT,
1028            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1029        )
1030    }
1031}
1032
1033impl fmt::Display for SetMinus {
1034    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1035        write!(
1036            f,
1037            "{}{}",
1038            SET_MINUS,
1039            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1040        )
1041    }
1042}
1043
1044impl fmt::Display for SetDiff {
1045    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1046        write!(
1047            f,
1048            "{}{}",
1049            SET_DIFF,
1050            braced_vec_to_string(&vec![self.left.as_ref(), self.right.as_ref()])
1051        )
1052    }
1053}
1054
1055impl fmt::Display for Cup {
1056    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1057        write!(
1058            f,
1059            "{}{}",
1060            CUP,
1061            braced_vec_to_string(&vec![self.left.as_ref()])
1062        )
1063    }
1064}
1065
1066impl fmt::Display for Cap {
1067    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1068        write!(
1069            f,
1070            "{}{}",
1071            CAP,
1072            braced_vec_to_string(&vec![self.left.as_ref()])
1073        )
1074    }
1075}
1076
1077impl fmt::Display for IdentifierWithMod {
1078    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1079        write!(f, "{}{}{}", self.mod_name, MOD_SIGN, self.name)
1080    }
1081}
1082
1083impl fmt::Display for ListSet {
1084    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1085        write!(f, "{}", curly_braced_vec_to_string(&self.list))
1086    }
1087}
1088
1089impl fmt::Display for SetBuilder {
1090    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1091        write!(
1092            f,
1093            "{}{} {}{} {}{}",
1094            LEFT_CURLY_BRACE,
1095            self.param,
1096            self.param_set,
1097            COLON,
1098            vec_to_string_join_by_comma(&self.facts),
1099            RIGHT_CURLY_BRACE
1100        )
1101    }
1102}
1103
1104impl fmt::Display for FnSet {
1105    /// 与 AST 一致:形参表、dom 均使用**存储名**(`fn` 形参为 `__` + 用户符面)。  
1106    /// 区别于单独 [`ParamGroupWithSet`] 的 `Display`(会隐去 `__` 以便其它上下文)。
1107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1108        let params_with_sets_display: Vec<String> = self
1109            .params_def_with_set
1110            .iter()
1111            .map(|g| format!("{} {}", vec_to_string_join_by_comma(&g.params), g.set))
1112            .collect();
1113        write!(
1114            f,
1115            "{} {} {}",
1116            FN_LOWER_CASE,
1117            brace_vec_colon_vec_to_string(&params_with_sets_display, &self.dom_facts),
1118            self.ret_set
1119        )
1120    }
1121}
1122
1123impl fmt::Display for Cart {
1124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1125        write!(f, "{}{}", CART, braced_vec_to_string(&self.args))
1126    }
1127}
1128
1129impl fmt::Display for PowerSet {
1130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1131        write!(
1132            f,
1133            "{}{}",
1134            POWER_SET,
1135            braced_vec_to_string(&vec![self.set.as_ref()])
1136        )
1137    }
1138}
1139
1140impl From<Atom> for Obj {
1141    fn from(atom: Atom) -> Self {
1142        match atom {
1143            Atom::Identifier(a) => Obj::Identifier(a),
1144            Atom::IdentifierWithMod(a) => Obj::IdentifierWithMod(a),
1145            Atom::FieldAccess(a) => Obj::FieldAccess(a),
1146            Atom::FieldAccessWithMod(a) => Obj::FieldAccessWithMod(a),
1147        }
1148    }
1149}
1150
1151impl Identifier {
1152    /// Build an Obj::Identifier from a name. Parameter is String (not &str).
1153    pub fn mk(name: String) -> Obj {
1154        Obj::Identifier(Identifier { name })
1155    }
1156}