smt_lang/problem/expression/
substitute.rs1use crate::problem::*;
2
3impl Expr {
4 pub fn substitute(&self, old: &Expr, expr: &Expr) -> Expr {
5 if self.is_same(old) {
6 expr.clone()
7 } else {
8 match self {
9 Expr::BoolValue(_, _) => self.clone(),
10 Expr::IntValue(_, _) => self.clone(),
11 Expr::RealValue(_, _) => self.clone(),
12 Expr::Unary(op, e, pos) => {
13 Expr::Unary(*op, Box::new(e.substitute(old, expr)), pos.clone())
14 }
15 Expr::Binary(left, op, right, pos) => {
16 let left = Box::new(left.substitute(old, expr));
17 let right = Box::new(right.substitute(old, expr));
18 Expr::Binary(left, *op, right, pos.clone())
19 }
20 Expr::Nary(op, kids, pos) => {
21 let v = kids.iter().map(|p| p.substitute(old, expr)).collect();
22 Expr::Nary(*op, v, pos.clone())
23 }
24 Expr::FunctionCall(id, params, pos) => {
25 let params = params.iter().map(|p| p.substitute(old, expr)).collect();
26 Expr::FunctionCall(*id, params, pos.clone())
27 }
28 Expr::Instance(_, _) => self.clone(),
29 Expr::Variable(_, _) => self.clone(),
30 Expr::Parameter(_) => self.clone(),
31 Expr::StrucSelf(_, _) => self.clone(),
32 Expr::StrucAttribute(e, id, pos) => {
33 Expr::StrucAttribute(Box::new(e.substitute(old, expr)), *id, pos.clone())
34 }
35 Expr::StrucMetCall(e, id, args, pos) => {
36 let e = e.substitute(old, expr);
37 let args = args.iter().map(|a| a.substitute(old, expr)).collect();
38 Expr::StrucMetCall(Box::new(e), *id, args, pos.clone())
39 }
40 Expr::ClassSelf(_, _) => self.clone(),
41 Expr::ClassAttribute(e, id, pos) => {
42 Expr::ClassAttribute(Box::new(e.substitute(old, expr)), *id, pos.clone())
43 }
44 Expr::ClassMetCall(e, id, args, pos) => {
45 let e = e.substitute(old, expr);
46 let args = args.iter().map(|a| a.substitute(old, expr)).collect();
47 Expr::ClassMetCall(Box::new(e), *id, args, pos.clone())
48 }
49 Expr::AsClass(e, id) => Expr::AsClass(Box::new(e.substitute(old, expr)), *id),
50 Expr::AsInterval(e, min, max, pos) => {
51 Expr::AsInterval(Box::new(e.substitute(old, expr)), *min, *max, pos.clone())
52 }
53 Expr::AsInt(e, pos) => {
54 let e = Box::new(e.substitute(old, expr));
55 let pos = pos.clone();
56 Expr::AsInt(e, pos)
57 }
58 Expr::AsReal(e, pos) => {
59 let e = Box::new(e.substitute(old, expr));
60 let pos = pos.clone();
61 Expr::AsReal(e, pos)
62 }
63 Expr::IfThenElse(c, t, l, e, pos) => {
64 let c = Box::new(c.substitute(old, expr));
65 let t = Box::new(t.substitute(old, expr));
66 let l = l
67 .iter()
68 .map(|(x, y)| (x.substitute(old, expr), y.substitute(old, expr)))
69 .collect();
70 let e = Box::new(e.substitute(old, expr));
71 let pos = pos.clone();
72 Expr::IfThenElse(c, t, l, e, pos)
73 }
74 Expr::Quantifier(op, p, e, pos) => {
75 let p = p.clone();
76 let e = Box::new(e.substitute(old, expr));
77 let pos = pos.clone();
78 Expr::Quantifier(*op, p, e, pos)
79 }
80 Expr::Unresolved(_, _) => self.clone(),
81 Expr::UnresolvedFunCall(_, _, _) => panic!(),
82 Expr::UnresolvedAttribute(_, _, _) => panic!(),
83 Expr::UnresolvedMethCall(_, _, _, _) => panic!(),
84 }
85 }
86 }
87
88 pub fn substitute_all(&self, all: Vec<(Expr, Expr)>) -> Expr {
89 let mut expr = self.clone();
90 for (o, e) in all.iter() {
91 expr = expr.substitute(o, e);
92 }
93 expr
94 }
95}