1
//! Uniplate and Traversal utilities for the AST.
2

            
3
use super::Expression;
4
use im::vector;
5
use uniplate::biplate::Uniplate;
6

            
7
use crate::ast::constants::Constant;
8

            
9
//NOTE (niklasdewally): Temporary manual implementation until the macro is sorted out
10
impl Uniplate for Expression {
11
    fn uniplate(
12
        &self,
13
    ) -> (
14
        uniplate::Tree<Self>,
15
        Box<dyn Fn(uniplate::Tree<Self>) -> Self>,
16
    ) {
17
        use uniplate::Tree::*;
18
        use Expression::*;
19
        match self {
20
            Nothing => (Zero, Box::new(|_| Nothing)),
21
            Constant(m, c) => {
22
                let m = m.clone(); // allows us to move m into the closure.
23
                let c = c.clone();
24
                (Zero, Box::new(move |_| (Constant(m.clone(), c.clone()))))
25
            }
26
            Reference(m, n) => {
27
                let m = m.clone();
28
                let n = n.clone();
29
                (Zero, Box::new(move |_| (Reference(m.clone(), n.clone()))))
30
            }
31
            Sum(m, es) => {
32
                let m = m.clone();
33
                (
34
                    Many(es.iter().map(|e| One(e.clone())).collect()),
35
                    Box::new(move |x| {
36
                        let Many(es) = x else { panic!() };
37
                        let es: Vec<Expression> = es
38
                            .into_iter()
39
                            .map(|e| {
40
                                let One(e) = e else { panic!() };
41
                                e
42
                            })
43
                            .collect();
44
                        Sum(m.clone(), es)
45
                    }),
46
                )
47
            }
48
            Min(m, es) => {
49
                let m = m.clone();
50
                (
51
                    Many(es.iter().map(|e| One(e.clone())).collect()),
52
                    Box::new(move |x| {
53
                        let Many(es) = x else { panic!() };
54
                        let es: Vec<Expression> = es
55
                            .into_iter()
56
                            .map(|e| {
57
                                let One(e) = e else { panic!() };
58
                                e
59
                            })
60
                            .collect();
61
                        Min(m.clone(), es)
62
                    }),
63
                )
64
            }
65
            And(m, es) => {
66
                let m = m.clone();
67
                (
68
                    Many(es.iter().map(|e| One(e.clone())).collect()),
69
                    Box::new(move |x| {
70
                        let Many(es) = x else { panic!() };
71
                        let es: Vec<Expression> = es
72
                            .into_iter()
73
                            .map(|e| {
74
                                let One(e) = e else { panic!() };
75
                                e
76
                            })
77
                            .collect();
78
                        And(m.clone(), es)
79
                    }),
80
                )
81
            }
82
            Or(m, es) => {
83
                let m = m.clone();
84
                (
85
                    Many(es.iter().map(|e| One(e.clone())).collect()),
86
                    Box::new(move |x| {
87
                        let Many(es) = x else { panic!() };
88
                        let es: Vec<Expression> = es
89
                            .into_iter()
90
                            .map(|e| {
91
                                let One(e) = e else { panic!() };
92
                                e
93
                            })
94
                            .collect();
95
                        Or(m.clone(), es)
96
                    }),
97
                )
98
            }
99
            AllDiff(m, es) => {
100
                let m = m.clone();
101
                (
102
                    Many(es.iter().map(|e| One(e.clone())).collect()),
103
                    Box::new(move |x| {
104
                        let Many(es) = x else { panic!() };
105
                        let es: Vec<Expression> = es
106
                            .into_iter()
107
                            .map(|e| {
108
                                let One(e) = e else { panic!() };
109
                                e
110
                            })
111
                            .collect();
112
                        AllDiff(m.clone(), es)
113
                    }),
114
                )
115
            }
116

            
117
            Not(m, e) => {
118
                let m = m.clone();
119
                (
120
                    One(*e.clone()),
121
                    Box::new(move |x| {
122
                        let One(e) = x else { panic!() };
123
                        Not(m.clone(), Box::new(e))
124
                    }),
125
                )
126
            }
127
            Bubble(m, e1, e2) => {
128
                let m = m.clone();
129
                (
130
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
131
                    Box::new(move |x| {
132
                        let Many(es) = x else { panic!() };
133
                        let One(e1) = &es[0] else { panic!() };
134
                        let One(e2) = &es[1] else { panic!() };
135
                        Bubble(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
136
                    }),
137
                )
138
            }
139
            Eq(m, e1, e2) => {
140
                let m = m.clone();
141
                (
142
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
143
                    Box::new(move |x| {
144
                        let Many(es) = x else { panic!() };
145
                        let One(e1) = &es[0] else { panic!() };
146
                        let One(e2) = &es[1] else { panic!() };
147
                        Eq(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
148
                    }),
149
                )
150
            }
151
            Neq(m, e1, e2) => {
152
                let m = m.clone();
153
                (
154
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
155
                    Box::new(move |x| {
156
                        let Many(es) = x else { panic!() };
157
                        let One(e1) = &es[0] else { panic!() };
158
                        let One(e2) = &es[1] else { panic!() };
159
                        Neq(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
160
                    }),
161
                )
162
            }
163
            Geq(m, e1, e2) => {
164
                let m = m.clone();
165
                (
166
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
167
                    Box::new(move |x| {
168
                        let Many(es) = x else { panic!() };
169
                        let One(e1) = &es[0] else { panic!() };
170
                        let One(e2) = &es[1] else { panic!() };
171
                        Geq(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
172
                    }),
173
                )
174
            }
175
            Leq(m, e1, e2) => {
176
                let m = m.clone();
177
                (
178
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
179
                    Box::new(move |x| {
180
                        let Many(es) = x else { panic!() };
181
                        let One(e1) = &es[0] else { panic!() };
182
                        let One(e2) = &es[1] else { panic!() };
183
                        Leq(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
184
                    }),
185
                )
186
            }
187
            Gt(m, e1, e2) => {
188
                let m = m.clone();
189
                (
190
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
191
                    Box::new(move |x| {
192
                        let Many(es) = x else { panic!() };
193
                        let One(e1) = &es[0] else { panic!() };
194
                        let One(e2) = &es[1] else { panic!() };
195
                        Gt(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
196
                    }),
197
                )
198
            }
199
            Lt(m, e1, e2) => {
200
                let m = m.clone();
201
                (
202
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
203
                    Box::new(move |x| {
204
                        let Many(es) = x else { panic!() };
205
                        let One(e1) = &es[0] else { panic!() };
206
                        let One(e2) = &es[1] else { panic!() };
207
                        Lt(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
208
                    }),
209
                )
210
            }
211
            SafeDiv(m, e1, e2) => {
212
                let m = m.clone();
213
                (
214
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
215
                    Box::new(move |x| {
216
                        let Many(es) = x else { panic!() };
217
                        let One(e1) = &es[0] else { panic!() };
218
                        let One(e2) = &es[1] else { panic!() };
219
                        SafeDiv(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
220
                    }),
221
                )
222
            }
223
            UnsafeDiv(m, e1, e2) => {
224
                let m = m.clone();
225
                (
226
                    Many(vector![One(*e1.clone()), One(*e2.clone())]),
227
                    Box::new(move |x| {
228
                        let Many(es) = x else { panic!() };
229
                        let One(e1) = &es[0] else { panic!() };
230
                        let One(e2) = &es[1] else { panic!() };
231
                        UnsafeDiv(m.clone(), Box::new(e1.clone()), Box::new(e2.clone()))
232
                    }),
233
                )
234
            }
235
            DivEq(m, e1, e2, e3) => {
236
                let m = m.clone();
237
                (
238
                    Many(vector![
239
                        One(*e1.clone()),
240
                        One(*e2.clone()),
241
                        One(*e3.clone())
242
                    ]),
243
                    Box::new(move |x| {
244
                        let Many(es) = x else { panic!() };
245
                        let One(e1) = &es[0] else { panic!() };
246
                        let One(e2) = &es[1] else { panic!() };
247
                        let One(e3) = &es[2] else { panic!() };
248
                        DivEq(
249
                            m.clone(),
250
                            Box::new(e1.clone()),
251
                            Box::new(e2.clone()),
252
                            Box::new(e3.clone()),
253
                        )
254
                    }),
255
                )
256
            }
257
            Ineq(m, e1, e2, e3) => {
258
                let m = m.clone();
259
                (
260
                    Many(vector![
261
                        One(*e1.clone()),
262
                        One(*e2.clone()),
263
                        One(*e3.clone())
264
                    ]),
265
                    Box::new(move |x| {
266
                        let Many(es) = x else { panic!() };
267
                        let One(e1) = &es[0] else { panic!() };
268
                        let One(e2) = &es[1] else { panic!() };
269
                        let One(e3) = &es[2] else { panic!() };
270
                        Ineq(
271
                            m.clone(),
272
                            Box::new(e1.clone()),
273
                            Box::new(e2.clone()),
274
                            Box::new(e3.clone()),
275
                        )
276
                    }),
277
                )
278
            }
279
            SumEq(m, es, e) => {
280
                let m = m.clone();
281
                let field_1 = Many(es.iter().map(|e| One(e.clone())).collect());
282
                let field_2 = One(*e.clone());
283
                let children = Many(vector![field_1, field_2]);
284
                (
285
                    children,
286
                    Box::new(move |x| {
287
                        let Many(x) = x else { panic!() };
288
                        let Many(es) = &x[0] else { panic!() };
289
                        let One(e) = &x[1] else { panic!() };
290
                        let es: Vec<Expression> = es
291
                            .iter()
292
                            .map(|e| {
293
                                let One(e) = e else { panic!() };
294
                                e.clone()
295
                            })
296
                            .collect();
297
                        SumEq(m.clone(), es, Box::new(e.clone()))
298
                    }),
299
                )
300
            }
301
            SumGeq(m, es, e) => {
302
                let m = m.clone();
303
                let field_1 = Many(es.iter().map(|e| One(e.clone())).collect());
304
                let field_2 = One(*e.clone());
305
                let children = Many(vector![field_1, field_2]);
306
                (
307
                    children,
308
                    Box::new(move |x| {
309
                        let Many(x) = x else { panic!() };
310
                        let Many(es) = &x[0] else { panic!() };
311
                        let One(e) = &x[1] else { panic!() };
312
                        let es: Vec<Expression> = es
313
                            .iter()
314
                            .map(|e| {
315
                                let One(e) = e else { panic!() };
316
                                e.clone()
317
                            })
318
                            .collect();
319
                        SumGeq(m.clone(), es, Box::new(e.clone()))
320
                    }),
321
                )
322
            }
323
            SumLeq(m, es, e) => {
324
                let m = m.clone();
325
                let field_1 = Many(es.iter().map(|e| One(e.clone())).collect());
326
                let field_2 = One(*e.clone());
327
                let children = Many(vector![field_1, field_2]);
328
                (
329
                    children,
330
                    Box::new(move |x| {
331
                        let Many(x) = x else { panic!() };
332
                        let Many(es) = &x[0] else { panic!() };
333
                        let One(e) = &x[1] else { panic!() };
334
                        let es: Vec<Expression> = es
335
                            .iter()
336
                            .map(|e| {
337
                                let One(e) = e else { panic!() };
338
                                e.clone()
339
                            })
340
                            .collect();
341
                        SumLeq(m.clone(), es, Box::new(e.clone()))
342
                    }),
343
                )
344
            }
345
        }
346
    }
347
}