refined/implication/arithmetic/
mul.rs

1use core::{marker::PhantomData, ops::Mul};
2
3use crate::{boundable::*, Predicate, Refinement};
4
5use super::*;
6
7impl<
8        const A: usize,
9        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
10        B: UnsignedMax<Type> + Predicate<Type>,
11    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::LessThan<A>>
12where
13    Refinement<Type, unsigned::LessThan<{ (A - 1) * B::UMAX + 1 }>>: Sized,
14{
15    type Output = Refinement<Type, unsigned::LessThan<{ (A - 1) * B::UMAX + 1 }>>;
16
17    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
18        Refinement(self.0 * rhs.0, PhantomData)
19    }
20}
21
22impl<
23        const A: usize,
24        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
25        B: UnsignedMax<Type> + Predicate<Type>,
26    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::LessThanEqual<A>>
27where
28    Refinement<Type, unsigned::LessThanEqual<{ A * B::UMAX }>>: Sized,
29{
30    type Output = Refinement<Type, unsigned::LessThanEqual<{ A * B::UMAX }>>;
31
32    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
33        Refinement(self.0 * rhs.0, PhantomData)
34    }
35}
36
37impl<
38        const A: usize,
39        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
40        B: UnsignedMin<Type> + Predicate<Type>,
41    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::GreaterThan<A>>
42where
43    Refinement<Type, unsigned::GreaterThan<{ (A + 1) * B::UMIN - 1 }>>: Sized,
44{
45    type Output = Refinement<Type, unsigned::GreaterThan<{ (A + 1) * B::UMIN - 1 }>>;
46
47    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
48        Refinement(self.0 * rhs.0, PhantomData)
49    }
50}
51
52impl<
53        const A: usize,
54        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
55        B: UnsignedMin<Type> + Predicate<Type>,
56    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::GreaterThanEqual<A>>
57where
58    Refinement<Type, unsigned::GreaterThanEqual<{ A * B::UMIN }>>: Sized,
59{
60    type Output = Refinement<Type, unsigned::GreaterThanEqual<{ A * B::UMIN }>>;
61
62    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
63        Refinement(self.0 * rhs.0, PhantomData)
64    }
65}
66
67impl<
68        const MIN: usize,
69        const MAX: usize,
70        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
71        B: UnsignedMinMax<Type> + Predicate<Type>,
72    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::OpenInterval<MIN, MAX>>
73where
74    Refinement<
75        Type,
76        unsigned::OpenInterval<{ (MIN + 1) * B::UMIN - 1 }, { (MAX - 1) * B::UMAX + 1 }>,
77    >: Sized,
78{
79    type Output = Refinement<
80        Type,
81        unsigned::OpenInterval<{ (MIN + 1) * B::UMIN - 1 }, { (MAX - 1) * B::UMAX + 1 }>,
82    >;
83
84    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
85        Refinement(self.0 * rhs.0, PhantomData)
86    }
87}
88
89impl<
90        const MIN: usize,
91        const MAX: usize,
92        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
93        B: UnsignedMinMax<Type> + Predicate<Type>,
94    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::ClosedInterval<MIN, MAX>>
95where
96    Refinement<Type, unsigned::ClosedInterval<{ MIN * B::UMIN }, { MAX * B::UMAX }>>: Sized,
97{
98    type Output = Refinement<Type, unsigned::ClosedInterval<{ MIN * B::UMIN }, { MAX * B::UMAX }>>;
99
100    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
101        Refinement(self.0 * rhs.0, PhantomData)
102    }
103}
104
105impl<
106        const MIN: usize,
107        const MAX: usize,
108        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
109        B: UnsignedMinMax<Type> + Predicate<Type>,
110    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::OpenClosedInterval<MIN, MAX>>
111where
112    Refinement<Type, unsigned::OpenClosedInterval<{ (MIN + 1) * B::UMIN - 1 }, { MAX * B::UMAX }>>:
113        Sized,
114{
115    type Output = Refinement<
116        Type,
117        unsigned::OpenClosedInterval<{ (MIN + 1) * B::UMIN - 1 }, { MAX * B::UMAX }>,
118    >;
119
120    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
121        Refinement(self.0 * rhs.0, PhantomData)
122    }
123}
124
125impl<
126        const MIN: usize,
127        const MAX: usize,
128        Type: unsigned::UnsignedBoundable + Mul<Output = Type>,
129        B: UnsignedMinMax<Type> + Predicate<Type>,
130    > Mul<Refinement<Type, B>> for Refinement<Type, unsigned::ClosedOpenInterval<MIN, MAX>>
131where
132    Refinement<Type, unsigned::ClosedOpenInterval<{ MIN * B::UMIN }, { (MAX - 1) * B::UMAX + 1 }>>:
133        Sized,
134{
135    type Output = Refinement<
136        Type,
137        unsigned::ClosedOpenInterval<{ MIN * B::UMIN }, { (MAX - 1) * B::UMAX + 1 }>,
138    >;
139
140    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
141        Refinement(self.0 * rhs.0, PhantomData)
142    }
143}
144
145#[cfg(test)]
146mod unsigned_tests {
147    use super::*;
148    use crate::prelude::*;
149
150    #[test]
151    fn test_lt_mul_lt() {
152        let a = Refinement::<u8, unsigned::LessThan<10>>::refine(9).unwrap();
153        let b = Refinement::<u8, unsigned::LessThan<10>>::refine(9).unwrap();
154        let c: Refinement<u8, unsigned::LessThan<82>> = a * b;
155        assert_eq!(*c, 81);
156    }
157
158    #[test]
159    fn test_lte_mul_lte() {
160        let a = Refinement::<u8, unsigned::LessThanEqual<10>>::refine(6).unwrap();
161        let b = Refinement::<u8, unsigned::LessThanEqual<10>>::refine(3).unwrap();
162        let c: Refinement<u8, unsigned::LessThanEqual<100>> = a * b;
163        assert_eq!(*c, 18);
164    }
165
166    #[test]
167    fn test_lte_mul_lt() {
168        let a = Refinement::<u8, unsigned::LessThanEqual<10>>::refine(6).unwrap();
169        let b = Refinement::<u8, unsigned::LessThan<11>>::refine(3).unwrap();
170        let c: Refinement<u8, unsigned::LessThanEqual<100>> = a * b;
171        assert_eq!(*c, 18);
172    }
173
174    #[test]
175    fn test_gt_mul_gt() {
176        let a = Refinement::<u8, unsigned::GreaterThan<10>>::refine(11).unwrap();
177        let b = Refinement::<u8, unsigned::GreaterThan<10>>::refine(11).unwrap();
178        let c: Refinement<u8, unsigned::GreaterThan<120>> = a * b;
179        assert_eq!(*c, 121);
180    }
181
182    #[test]
183    fn test_gt_mul_gte() {
184        let a = Refinement::<u8, unsigned::GreaterThan<10>>::refine(11).unwrap();
185        let b = Refinement::<u8, unsigned::GreaterThanEqual<3>>::refine(3).unwrap();
186        let c: Refinement<u8, unsigned::GreaterThan<32>> = a * b;
187        assert_eq!(*c, 33);
188    }
189
190    #[test]
191    fn test_gte_mul_gte() {
192        let a = Refinement::<u8, unsigned::GreaterThanEqual<10>>::refine(12).unwrap();
193        let b = Refinement::<u8, unsigned::GreaterThanEqual<3>>::refine(3).unwrap();
194        let c: Refinement<u8, unsigned::GreaterThanEqual<30>> = a * b;
195        assert_eq!(*c, 36);
196    }
197
198    #[test]
199    fn test_gte_mul_gt() {
200        let a = Refinement::<u8, unsigned::GreaterThanEqual<12>>::refine(15).unwrap();
201        let b = Refinement::<u8, unsigned::GreaterThan<3>>::refine(4).unwrap();
202        let c: Refinement<u8, unsigned::GreaterThanEqual<48>> = a * b;
203        assert_eq!(*c, 60);
204    }
205
206    #[test]
207    fn test_open_closed_interval_mul() {
208        let a = Refinement::<u8, unsigned::OpenClosedInterval<15, 20>>::refine(18).unwrap();
209        let b = Refinement::<u8, unsigned::OpenClosedInterval<3, 6>>::refine(6).unwrap();
210        let c: Refinement<u8, unsigned::OpenClosedInterval<63, 120>> = a * b;
211        assert_eq!(*c, 108);
212    }
213
214    #[test]
215    fn test_closed_open_interval_mul() {
216        let a = Refinement::<u16, unsigned::ClosedOpenInterval<50, 100>>::refine(99).unwrap();
217        let b = Refinement::<u16, unsigned::ClosedOpenInterval<5, 10>>::refine(9).unwrap();
218        let c: Refinement<u16, unsigned::ClosedOpenInterval<250, 892>> = a * b;
219        assert_eq!(*c, 891);
220    }
221
222    #[test]
223    fn test_open_interval_mul() {
224        let a = Refinement::<u8, unsigned::OpenInterval<15, 30>>::refine(18).unwrap();
225        let b = Refinement::<u8, unsigned::OpenInterval<3, 6>>::refine(5).unwrap();
226        let c: Refinement<u8, unsigned::OpenInterval<63, 146>> = a * b;
227        assert_eq!(*c, 90);
228    }
229
230    #[test]
231    fn test_closed_interval_mul() {
232        let a = Refinement::<u8, unsigned::ClosedInterval<15, 50>>::refine(30).unwrap();
233        let b = Refinement::<u8, unsigned::ClosedInterval<3, 6>>::refine(6).unwrap();
234        let c: Refinement<u8, unsigned::ClosedInterval<45, 300>> = a * b;
235        assert_eq!(*c, 180);
236    }
237}
238
239impl<
240        const MIN: isize,
241        const MAX: isize,
242        Type: signed::SignedBoundable + Mul<Output = Type>,
243        B: SignedMinMax<Type> + Predicate<Type>,
244    > Mul<Refinement<Type, B>> for Refinement<Type, signed::OpenInterval<MIN, MAX>>
245where
246    Refinement<
247        Type,
248        signed::OpenInterval<
249            { min_mul(MIN + 1, MAX - 1, B::UMIN, B::UMAX) - 1 },
250            { max_mul(MIN + 1, MAX - 1, B::UMIN, B::UMAX) + 1 },
251        >,
252    >: Sized,
253{
254    type Output = Refinement<
255        Type,
256        signed::OpenInterval<
257            { min_mul(MIN + 1, MAX - 1, B::UMIN, B::UMAX) - 1 },
258            { max_mul(MIN + 1, MAX - 1, B::UMIN, B::UMAX) + 1 },
259        >,
260    >;
261
262    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
263        Refinement(self.0 * rhs.0, PhantomData)
264    }
265}
266
267impl<
268        const MIN: isize,
269        const MAX: isize,
270        Type: signed::SignedBoundable + Mul<Output = Type>,
271        B: SignedMinMax<Type> + Predicate<Type>,
272    > Mul<Refinement<Type, B>> for Refinement<Type, signed::ClosedInterval<MIN, MAX>>
273where
274    Refinement<
275        Type,
276        signed::ClosedInterval<
277            { min_mul(MIN, MAX, B::UMIN, B::UMAX) },
278            { max_mul(MIN, MAX, B::UMIN, B::UMAX) },
279        >,
280    >: Sized,
281{
282    type Output = Refinement<
283        Type,
284        signed::ClosedInterval<
285            { min_mul(MIN, MAX, B::UMIN, B::UMAX) },
286            { max_mul(MIN, MAX, B::UMIN, B::UMAX) },
287        >,
288    >;
289
290    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
291        Refinement(self.0 * rhs.0, PhantomData)
292    }
293}
294
295impl<
296        const MIN: isize,
297        const MAX: isize,
298        Type: signed::SignedBoundable + Mul<Output = Type>,
299        B: SignedMinMax<Type> + Predicate<Type>,
300    > Mul<Refinement<Type, B>> for Refinement<Type, signed::OpenClosedInterval<MIN, MAX>>
301where
302    Refinement<
303        Type,
304        signed::OpenClosedInterval<
305            { min_mul(MIN + 1, MAX, B::UMIN, B::UMAX) - 1 },
306            { max_mul(MIN + 1, MAX, B::UMIN, B::UMAX) },
307        >,
308    >: Sized,
309{
310    type Output = Refinement<
311        Type,
312        signed::OpenClosedInterval<
313            { min_mul(MIN + 1, MAX, B::UMIN, B::UMAX) - 1 },
314            { max_mul(MIN + 1, MAX, B::UMIN, B::UMAX) },
315        >,
316    >;
317
318    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
319        Refinement(self.0 * rhs.0, PhantomData)
320    }
321}
322
323impl<
324        const MIN: isize,
325        const MAX: isize,
326        Type: signed::SignedBoundable + Mul<Output = Type>,
327        B: SignedMinMax<Type> + Predicate<Type>,
328    > Mul<Refinement<Type, B>> for Refinement<Type, signed::ClosedOpenInterval<MIN, MAX>>
329where
330    Refinement<
331        Type,
332        signed::ClosedOpenInterval<
333            { min_mul(MIN, MAX - 1, B::UMIN, B::UMAX) },
334            { max_mul(MIN, MAX - 1, B::UMIN, B::UMAX) + 1 },
335        >,
336    >: Sized,
337{
338    type Output = Refinement<
339        Type,
340        signed::ClosedOpenInterval<
341            { min_mul(MIN, MAX - 1, B::UMIN, B::UMAX) },
342            { max_mul(MIN, MAX - 1, B::UMIN, B::UMAX) + 1 },
343        >,
344    >;
345
346    fn mul(self, rhs: Refinement<Type, B>) -> Self::Output {
347        Refinement(self.0 * rhs.0, PhantomData)
348    }
349}
350
351#[cfg(test)]
352mod signed_tests {
353    use super::*;
354    use crate::prelude::*;
355
356    #[test]
357    fn test_open_closed_interval_mul() {
358        let a = Refinement::<i8, signed::OpenClosedInterval<15, 20>>::refine(20).unwrap();
359        let b = Refinement::<i8, signed::OpenClosedInterval<-6, -3>>::refine(-5).unwrap();
360        let c: Refinement<i8, signed::OpenClosedInterval<-101, -48>> = a * b;
361        assert_eq!(*c, -100);
362    }
363
364    #[test]
365    fn test_closed_open_interval_mul() {
366        let a = Refinement::<i16, signed::ClosedOpenInterval<-50, 100>>::refine(99).unwrap();
367        let b = Refinement::<i16, signed::ClosedOpenInterval<5, 10>>::refine(9).unwrap();
368        let c: Refinement<i16, signed::ClosedOpenInterval<-450, 892>> = a * b;
369        assert_eq!(*c, 891);
370    }
371
372    #[test]
373    fn test_open_interval_mul() {
374        let a = Refinement::<i8, signed::OpenInterval<15, 30>>::refine(16).unwrap();
375        let b = Refinement::<i8, signed::OpenInterval<-13, -6>>::refine(-7).unwrap();
376        let c: Refinement<i8, signed::OpenInterval<-349, -111>> = a * b;
377        assert_eq!(*c, -112);
378    }
379
380    #[test]
381    fn test_closed_interval_mul() {
382        let a = Refinement::<i16, signed::ClosedInterval<15, 50>>::refine(30).unwrap();
383        let b = Refinement::<i16, signed::ClosedInterval<3, 6>>::refine(6).unwrap();
384        let c: Refinement<i16, signed::ClosedInterval<45, 300>> = a * b;
385        assert_eq!(*c, 180);
386    }
387}