casuarius/
operators.rs

1use crate::{
2    Term,
3    Expression,
4    Constraint
5};
6
7/// A trait for creating constraints using custom variable types.
8pub trait Constrainable<Var>
9where
10    Var: Sized,
11    Self: Sized
12{
13    fn equal_to<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone;
14
15    fn is<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone {
16        self.equal_to(x)
17    }
18
19    fn greater_than_or_equal_to<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone;
20
21    fn is_ge<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone {
22        self.greater_than_or_equal_to(x)
23    }
24
25    fn less_than_or_equal_to<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone;
26
27    fn is_le<X>(self, x: X) -> Constraint<Var> where X: Into<Expression<Var>> + Clone {
28        self.less_than_or_equal_to(x)
29    }
30}
31
32
33// Term
34
35impl<T> std::ops::Mul<f64> for Term<T> {
36    type Output = Term<T>;
37    fn mul(mut self, v: f64) -> Term<T> {
38        self *= v;
39        self
40    }
41}
42
43impl<T> std::ops::MulAssign<f64> for Term<T> {
44    fn mul_assign(&mut self, v: f64) {
45        *(self.coefficient.as_mut()) *= v;
46    }
47}
48
49impl<T> std::ops::Mul<f32> for Term<T> {
50    type Output = Term<T>;
51    fn mul(self, v: f32) -> Term<T> {
52        self.mul(v as f64)
53    }
54}
55
56impl<T> std::ops::MulAssign<f32> for Term<T> {
57    fn mul_assign(&mut self, v: f32) {
58        self.mul_assign(v as f64)
59    }
60}
61
62impl<T> std::ops::Mul<Term<T>> for f64 {
63    type Output = Term<T>;
64    fn mul(self, mut t: Term<T>) -> Term<T> {
65        *(t.coefficient.as_mut()) *= self;
66        t
67    }
68}
69
70impl<T> std::ops::Mul<Term<T>> for f32 {
71    type Output = Term<T>;
72    fn mul(self, t: Term<T>) -> Term<T> {
73        (self as f64).mul(t)
74    }
75}
76
77impl<T> std::ops::Div<f64> for Term<T> {
78    type Output = Term<T>;
79    fn div(mut self, v: f64) -> Term<T> {
80        self /= v;
81        self
82    }
83}
84
85impl<T> std::ops::DivAssign<f64> for Term<T> {
86    fn div_assign(&mut self, v: f64) {
87        *(self.coefficient.as_mut()) /= v;
88    }
89}
90
91impl<T> std::ops::Div<f32> for Term<T> {
92    type Output = Term<T>;
93    fn div(self, v: f32) -> Term<T> {
94        self.div(v as f64)
95    }
96}
97
98impl<T> std::ops::DivAssign<f32> for Term<T> {
99    fn div_assign(&mut self, v: f32) {
100        self.div_assign(v as f64)
101    }
102}
103
104impl<T:Clone> std::ops::Add<f64> for Term<T> {
105    type Output = Expression<T>;
106    fn add(self, v: f64) -> Expression<T> {
107        Expression::new(vec![self], v)
108    }
109}
110
111impl<T:Clone> std::ops::Add<f32> for Term<T> {
112    type Output = Expression<T>;
113    fn add(self, v: f32) -> Expression<T> {
114        self.add(v as f64)
115    }
116}
117
118impl<T:Clone> std::ops::Add<Term<T>> for f64 {
119    type Output = Expression<T>;
120    fn add(self, t: Term<T>) -> Expression<T> {
121        Expression::new(vec![t], self)
122    }
123}
124
125impl<T:Clone> std::ops::Add<Term<T>> for f32 {
126    type Output = Expression<T>;
127    fn add(self, t: Term<T>) -> Expression<T> {
128        (self as f64).add(t)
129    }
130}
131
132impl<T:Clone> std::ops::Add<Term<T>> for Term<T> {
133    type Output = Expression<T>;
134    fn add(self, t: Term<T>) -> Expression<T> {
135        Expression::new(vec![self, t], 0.0)
136    }
137}
138
139impl<T> std::ops::Add<Expression<T>> for Term<T> {
140    type Output = Expression<T>;
141    fn add(self, mut e: Expression<T>) -> Expression<T> {
142        e.terms.push(self);
143        e
144    }
145}
146
147impl<T> std::ops::Add<Term<T>> for Expression<T> {
148    type Output = Expression<T>;
149    fn add(mut self, t: Term<T>) -> Expression<T> {
150        self += t;
151        self
152    }
153}
154
155impl<T> std::ops::AddAssign<Term<T>> for Expression<T> {
156    fn add_assign(&mut self, t: Term<T>) {
157        self.terms.push(t);
158    }
159}
160
161impl<T> std::ops::Neg for Term<T> {
162    type Output = Term<T>;
163    fn neg(mut self) -> Term<T> {
164        *(self.coefficient.as_mut()) = -(self.coefficient.into_inner());
165        self
166    }
167}
168
169impl<T:Clone> std::ops::Sub<f64> for Term<T> {
170    type Output = Expression<T>;
171    fn sub(self, v: f64) -> Expression<T> {
172        Expression::new(vec![self], -v)
173    }
174}
175
176impl<T:Clone> std::ops::Sub<f32> for Term<T> {
177    type Output = Expression<T>;
178    fn sub(self, v: f32) -> Expression<T> {
179        self.sub(v as f64)
180    }
181}
182
183impl<T:Clone> std::ops::Sub<Term<T>> for f64 {
184    type Output = Expression<T>;
185    fn sub(self, t: Term<T>) -> Expression<T> {
186        Expression::new(vec![-t], self)
187    }
188}
189
190impl<T:Clone> std::ops::Sub<Term<T>> for f32 {
191    type Output = Expression<T>;
192    fn sub(self, t: Term<T>) -> Expression<T> {
193        (self as f64).sub(t)
194    }
195}
196
197impl<T:Clone> std::ops::Sub<Term<T>> for Term<T> {
198    type Output = Expression<T>;
199    fn sub(self, t: Term<T>) -> Expression<T> {
200        Expression::new(vec![self, -t], 0.0)
201    }
202}
203
204impl<T:Clone> std::ops::Sub<Expression<T>> for Term<T> {
205    type Output = Expression<T>;
206    fn sub(self, mut e: Expression<T>) -> Expression<T> {
207        e.negate();
208        e.terms.push(self);
209        e
210    }
211}
212
213impl<T> std::ops::Sub<Term<T>> for Expression<T> {
214    type Output = Expression<T>;
215    fn sub(mut self, t: Term<T>) -> Expression<T> {
216        self -= t;
217        self
218    }
219}
220
221impl<T> std::ops::SubAssign<Term<T>> for Expression<T> {
222    fn sub_assign(&mut self, t: Term<T>) {
223        self.terms.push(-t);
224    }
225}
226
227// Expression
228
229impl<T:Clone> std::ops::Mul<f64> for Expression<T> {
230    type Output = Expression<T>;
231    fn mul(mut self, v: f64) -> Expression<T> {
232        self *= v.clone();
233        self
234    }
235}
236
237impl<T:Clone> std::ops::MulAssign<f64> for Expression<T> {
238    fn mul_assign(&mut self, v: f64) {
239        *(self.constant.as_mut()) *= v;
240        for t in &mut self.terms {
241            *t = t.clone() * v;
242        }
243    }
244}
245
246impl<T:Clone> std::ops::Mul<Expression<T>> for f64 {
247    type Output = Expression<T>;
248    fn mul(self, mut e: Expression<T>) -> Expression<T> {
249        *(e.constant.as_mut()) *= self;
250        for t in &mut e.terms {
251            *t = t.clone() * self;
252        }
253        e
254    }
255}
256
257impl<T:Clone> std::ops::Div<f64> for Expression<T> {
258    type Output = Expression<T>;
259    fn div(mut self, v: f64) -> Expression<T> {
260        self /= v;
261        self
262    }
263}
264
265impl<T:Clone> std::ops::DivAssign<f64> for Expression<T> {
266    fn div_assign(&mut self, v: f64) {
267        *(self.constant.as_mut()) /= v;
268        for t in &mut self.terms {
269            *t = t.clone() / v;
270        }
271    }
272}
273
274impl<T> std::ops::Add<f64> for Expression<T> {
275    type Output = Expression<T>;
276    fn add(mut self, v: f64) -> Expression<T> {
277        self += v;
278        self
279    }
280}
281
282impl<T> std::ops::AddAssign<f64> for Expression<T> {
283    fn add_assign(&mut self, v: f64) {
284        *(self.constant.as_mut()) += v;
285    }
286}
287
288impl<T> std::ops::Add<Expression<T>> for f64 {
289    type Output = Expression<T>;
290    fn add(self, mut e: Expression<T>) -> Expression<T> {
291        *(e.constant.as_mut()) += self;
292        e
293    }
294}
295
296impl<T> std::ops::Add<Expression<T>> for Expression<T> {
297    type Output = Expression<T>;
298    fn add(mut self, e: Expression<T>) -> Expression<T> {
299        self += e;
300        self
301    }
302}
303
304impl<T> std::ops::AddAssign<Expression<T>> for Expression<T> {
305    fn add_assign(&mut self, mut e: Expression<T>) {
306        self.terms.append(&mut e.terms);
307        *(self.constant.as_mut()) += e.constant.into_inner();
308    }
309}
310
311impl<T:Clone> std::ops::Neg for Expression<T> {
312    type Output = Expression<T>;
313    fn neg(mut self) -> Expression<T> {
314        self.negate();
315        self
316    }
317}
318
319impl<T> std::ops::Sub<f64> for Expression<T> {
320    type Output = Expression<T>;
321    fn sub(mut self, v: f64) -> Expression<T> {
322        self -= v;
323        self
324    }
325}
326
327impl<T> std::ops::SubAssign<f64> for Expression<T> {
328    fn sub_assign(&mut self, v: f64) {
329        *(self.constant.as_mut()) -= v;
330    }
331}
332
333impl<T:Clone> std::ops::Sub<Expression<T>> for f64 {
334    type Output = Expression<T>;
335    fn sub(self, mut e: Expression<T>) -> Expression<T> {
336        e.negate();
337        *(e.constant.as_mut()) += self;
338        e
339    }
340}
341
342impl<T:Clone> std::ops::Sub<Expression<T>> for Expression<T> {
343    type Output = Expression<T>;
344    fn sub(mut self, e: Expression<T>) -> Expression<T> {
345        self -= e;
346        self
347    }
348}
349
350impl<T:Clone> std::ops::SubAssign<Expression<T>> for Expression<T> {
351    fn sub_assign(&mut self, mut e: Expression<T>) {
352        e.negate();
353        self.terms.append(&mut e.terms);
354        *(self.constant.as_mut()) += e.constant.into_inner();
355    }
356}
357
358macro_rules! derive_expr_ops_for {
359  ( $x:ty ) => {
360    impl<T:Clone> std::ops::Mul<$x> for Expression<T> {
361      type Output = Expression<T>;
362      fn mul(self, v: $x) -> Expression<T> {
363        self.mul(v as f64)
364      }
365    }
366
367    impl<T:Clone> std::ops::MulAssign<$x> for Expression<T> {
368      fn mul_assign(&mut self, v: $x) {
369        let v2 = v as f64;
370        *(self.constant.as_mut()) *= v2;
371        for t in &mut self.terms {
372          *t = t.clone() * v2;
373        }
374      }
375    }
376
377    impl<T:Clone> std::ops::Mul<Expression<T>> for $x {
378      type Output = Expression<T>;
379      fn mul(self, e: Expression<T>) -> Expression<T> {
380        (self as f64).mul(e)
381      }
382    }
383
384    impl<T:Clone> std::ops::Div<$x> for Expression<T> {
385      type Output = Expression<T>;
386      fn div(self, v: $x) -> Expression<T> {
387        self.div(v as f64)
388      }
389    }
390
391    impl<T:Clone> std::ops::DivAssign<$x> for Expression<T> {
392      fn div_assign(&mut self, v: $x) {
393        self.div_assign(v as f64)
394      }
395    }
396
397    impl<T> std::ops::Add<$x> for Expression<T> {
398      type Output = Expression<T>;
399      fn add(self, v: $x) -> Expression<T> {
400        self.add(v as f64)
401      }
402    }
403
404    impl<T> std::ops::AddAssign<$x> for Expression<T> {
405      fn add_assign(&mut self, v: $x) {
406        self.add_assign(v as f64)
407      }
408    }
409
410    impl<T> std::ops::Add<Expression<T>> for $x {
411      type Output = Expression<T>;
412      fn add(self, e: Expression<T>) -> Expression<T> {
413        (self as f64).add(e)
414      }
415    }
416
417    impl<T> std::ops::Sub<$x> for Expression<T> {
418      type Output = Expression<T>;
419      fn sub(self, v: $x) -> Expression<T> {
420        self.sub(v as f64)
421      }
422    }
423
424    impl<T:Clone> std::ops::Sub<Expression<T>> for $x {
425      type Output = Expression<T>;
426      fn sub(self, e: Expression<T>) -> Expression<T> {
427        (self as f64).sub(e)
428      }
429    }
430
431    impl<T> std::ops::SubAssign<$x> for Expression<T> {
432      fn sub_assign(&mut self, v: $x) {
433        self.sub_assign(v as f64)
434      }
435    }
436  };
437}
438
439derive_expr_ops_for!(f32);
440derive_expr_ops_for!(i32);
441derive_expr_ops_for!(u32);