abstalg/
vector_algebra.rs1use crate::*;
5
6#[derive(Clone, Debug)]
9pub struct VectorAlgebra<A>
10where
11 A: Domain,
12{
13 base: A,
14 len: usize,
15}
16
17#[allow(clippy::len_without_is_empty)]
18impl<A> VectorAlgebra<A>
19where
20 A: Domain,
21{
22 pub fn new(base: A, len: usize) -> Self {
24 Self { base, len }
25 }
26
27 pub fn base(&self) -> &A {
29 &self.base
30 }
31
32 pub fn len(&self) -> usize {
35 self.len
36 }
37
38 pub fn diagonal(&self, elem: A::Elem) -> Vec<A::Elem> {
40 vec![elem; self.len]
41 }
42}
43
44impl<A> Domain for VectorAlgebra<A>
45where
46 A: Domain,
47{
48 type Elem = Vec<A::Elem>;
49
50 fn contains(&self, elem: &Self::Elem) -> bool {
51 if elem.len() != self.len {
52 false
53 } else {
54 elem.iter().all(|a| self.base.contains(a))
55 }
56 }
57
58 fn equals(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> bool {
59 assert!(elem1.len() == self.len && elem2.len() == self.len);
60 elem1
61 .iter()
62 .zip(elem2.iter())
63 .all(|(x, y)| self.base.equals(x, y))
64 }
65}
66
67impl<A> Semigroup for VectorAlgebra<A>
68where
69 A: Semigroup,
70{
71 fn mul(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
72 assert!(elem1.len() == self.len && elem2.len() == self.len);
73 elem1
74 .iter()
75 .zip(elem2.iter())
76 .map(|(x, y)| self.base.mul(x, y))
77 .collect()
78 }
79
80 fn mul_assign(&self, elem1: &mut Self::Elem, elem2: &Self::Elem) {
81 assert!(elem1.len() == self.len && elem2.len() == self.len);
82 elem1
83 .iter_mut()
84 .zip(elem2.iter())
85 .for_each(|(x, y)| self.base.mul_assign(x, y));
86 }
87
88 fn square(&self, elem: &mut Self::Elem) {
89 assert!(elem.len() == self.len);
90 elem.iter_mut().for_each(|x| self.base.square(x));
91 }
92}
93
94impl<A> Monoid for VectorAlgebra<A>
95where
96 A: Monoid,
97{
98 fn one(&self) -> Self::Elem {
99 self.diagonal(self.base.one())
100 }
101
102 fn is_one(&self, elem: &Self::Elem) -> bool {
103 assert!(elem.len() == self.len);
104 elem.iter().all(|x| self.base.is_one(x))
105 }
106
107 fn try_inv(&self, elem: &Self::Elem) -> Option<Self::Elem> {
108 assert!(elem.len() == self.len);
109 let mut v = Vec::with_capacity(self.len);
110 for x in elem.iter() {
111 if let Some(y) = self.base.try_inv(x) {
112 v.push(y)
113 } else {
114 return None;
115 }
116 }
117 Some(v)
118 }
119
120 fn invertible(&self, elem: &Self::Elem) -> bool {
121 assert!(elem.len() == self.len);
122 elem.iter().all(|x| self.base.invertible(x))
123 }
124}
125
126impl<A> Group for VectorAlgebra<A>
127where
128 A: Group,
129{
130 fn inv(&self, elem: &Self::Elem) -> Self::Elem {
131 assert!(elem.len() == self.len);
132 elem.iter().map(|x| self.base.inv(x)).collect()
133 }
134}
135
136impl<A> CommuntativeMonoid for VectorAlgebra<A>
137where
138 A: CommuntativeMonoid,
139{
140 fn zero(&self) -> Self::Elem {
141 self.diagonal(self.base.zero())
142 }
143
144 fn is_zero(&self, elem: &Self::Elem) -> bool {
145 assert!(elem.len() == self.len);
146 elem.iter().all(|x| self.base.is_zero(x))
147 }
148
149 fn add(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
150 assert!(elem1.len() == self.len && elem2.len() == self.len);
151 elem1
152 .iter()
153 .zip(elem2.iter())
154 .map(|(x, y)| self.base.add(x, y))
155 .collect()
156 }
157
158 fn add_assign(&self, elem1: &mut Self::Elem, elem2: &Self::Elem) {
159 assert!(elem1.len() == self.len && elem2.len() == self.len);
160 elem1
161 .iter_mut()
162 .zip(elem2.iter())
163 .for_each(|(x, y)| self.base.add_assign(x, y));
164 }
165
166 fn double(&self, elem: &mut Self::Elem) {
167 assert!(elem.len() == self.len);
168 elem.iter_mut().for_each(|x| self.base.double(x))
169 }
170}
171
172impl<A> AbelianGroup for VectorAlgebra<A>
173where
174 A: AbelianGroup,
175{
176 fn neg(&self, elem: &Self::Elem) -> Self::Elem {
177 assert!(elem.len() == self.len);
178 elem.iter().map(|x| self.base.neg(x)).collect()
179 }
180
181 fn neg_assign(&self, elem: &mut Self::Elem) {
182 assert!(elem.len() == self.len);
183 elem.iter_mut().for_each(|x| self.base.neg_assign(x))
184 }
185
186 fn sub(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
187 assert!(elem1.len() == self.len && elem2.len() == self.len);
188 elem1
189 .iter()
190 .zip(elem2.iter())
191 .map(|(x, y)| self.base.sub(x, y))
192 .collect()
193 }
194
195 fn sub_assign(&self, elem1: &mut Self::Elem, elem2: &Self::Elem) {
196 assert!(elem1.len() == self.len && elem2.len() == self.len);
197 elem1
198 .iter_mut()
199 .zip(elem2.iter())
200 .for_each(|(x, y)| self.base.sub_assign(x, y));
201 }
202}
203
204impl<A> SemiRing for VectorAlgebra<A> where A: SemiRing {}
205
206impl<A> UnitaryRing for VectorAlgebra<A>
207where
208 A: UnitaryRing,
209{
210 fn int(&self, elem: isize) -> Self::Elem {
211 self.diagonal(self.base.int(elem))
212 }
213}
214
215impl<A> PartialOrder for VectorAlgebra<A>
216where
217 A: PartialOrder,
218{
219 fn leq(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> bool {
220 assert!(elem1.len() == self.len && elem2.len() == self.len);
221 elem1
222 .iter()
223 .zip(elem2.iter())
224 .all(|(x, y)| self.base.leq(x, y))
225 }
226}
227
228impl<A> BoundedOrder for VectorAlgebra<A>
229where
230 A: BoundedOrder,
231{
232 fn max(&self) -> Self::Elem {
233 self.diagonal(self.base.max())
234 }
235
236 fn min(&self) -> Self::Elem {
237 self.diagonal(self.base.min())
238 }
239}
240
241impl<A> Lattice for VectorAlgebra<A>
242where
243 A: Lattice,
244{
245 fn meet(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
246 assert!(elem1.len() == self.len && elem2.len() == self.len);
247 elem1
248 .iter()
249 .zip(elem2.iter())
250 .map(|(x, y)| self.base.meet(x, y))
251 .collect()
252 }
253
254 fn join(&self, elem1: &Self::Elem, elem2: &Self::Elem) -> Self::Elem {
255 assert!(elem1.len() == self.len && elem2.len() == self.len);
256 elem1
257 .iter()
258 .zip(elem2.iter())
259 .map(|(x, y)| self.base.join(x, y))
260 .collect()
261 }
262}
263
264impl<A> DistributiveLattice for VectorAlgebra<A> where A: DistributiveLattice {}
265
266impl<A> BooleanAlgebra for VectorAlgebra<A>
267where
268 A: BooleanAlgebra,
269{
270 fn not(&self, elem: &Self::Elem) -> Self::Elem {
271 assert!(elem.len() == self.len);
272 elem.iter().map(|x| self.base.not(x)).collect()
273 }
274}