1use std::{ops::*, hash::Hash, fmt::{Display, Debug}};
2
3use crate::homomorphism::*;
4use crate::ring::*;
5use crate::field::*;
6
7pub struct RingElementWrapper<R>
41 where R: RingStore
42{
43 ring: R,
44 element: El<R>
45}
46
47impl<R: RingStore> RingElementWrapper<R> {
48
49 pub const fn new(ring: R, element: El<R>) -> Self {
53 Self { ring, element }
54 }
55
56 pub fn pow(self, power: usize) -> Self {
63 Self {
64 element: self.ring.pow(self.element, power),
65 ring: self.ring
66 }
67 }
68
69 pub fn pow_ref(&self, power: usize) -> Self
73 where R: Clone
74 {
75 Self {
76 element: self.ring.pow(self.ring.clone_el(&self.element), power),
77 ring: self.ring.clone()
78 }
79 }
80
81 pub fn unwrap(self) -> El<R> {
85 self.element
86 }
87
88 pub fn unwrap_ref(&self) -> &El<R> {
92 &self.element
93 }
94
95 pub fn parent(&self) -> &R {
99 &self.ring
100 }
101}
102
103macro_rules! impl_xassign_trait {
104 ($trait_name:ident, $fn_name:ident, $fn_ref_name:ident) => {
105
106 impl<R: RingStore> $trait_name for RingElementWrapper<R> {
107
108 fn $fn_name(&mut self, rhs: Self) {
109 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
110 self.ring.$fn_name(&mut self.element, rhs.element);
111 }
112 }
113
114 impl<'a, R: RingStore> $trait_name<&'a Self> for RingElementWrapper<R> {
115
116 fn $fn_name(&mut self, rhs: &'a Self) {
117 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
118 self.ring.$fn_ref_name(&mut self.element, &rhs.element);
119 }
120 }
121 };
122}
123
124macro_rules! impl_trait {
125 ($trait_name:ident, $fn_name:ident, $fn_name_ref_fst:ident, $fn_name_ref_snd:ident, $fn_name_ref:ident) => {
126
127 impl<R: RingStore> $trait_name for RingElementWrapper<R> {
128 type Output = Self;
129
130 fn $fn_name(self, rhs: Self) -> Self::Output {
131 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
132 Self { ring: self.ring, element: rhs.ring.$fn_name(self.element, rhs.element) }
133 }
134 }
135
136 impl<'a, R: RingStore> $trait_name<RingElementWrapper<R>> for &'a RingElementWrapper<R> {
137 type Output = RingElementWrapper<R>;
138
139 fn $fn_name(self, rhs: RingElementWrapper<R>) -> Self::Output {
140 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
141 RingElementWrapper { ring: rhs.ring, element: self.ring.$fn_name_ref_fst(&self.element, rhs.element) }
142 }
143 }
144
145 impl<'a, R: RingStore> $trait_name<&'a RingElementWrapper<R>> for RingElementWrapper<R> {
146 type Output = RingElementWrapper<R>;
147
148 fn $fn_name(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
149 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
150 RingElementWrapper { ring: self.ring, element: rhs.ring.$fn_name_ref_snd(self.element, &rhs.element) }
151 }
152 }
153
154 impl<'a, 'b, R: RingStore + Clone> $trait_name<&'a RingElementWrapper<R>> for &'b RingElementWrapper<R> {
155 type Output = RingElementWrapper<R>;
156
157 fn $fn_name(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
158 debug_assert!(self.ring.get_ring() == rhs.ring.get_ring());
159 RingElementWrapper { ring: self.ring.clone(), element: self.ring.$fn_name_ref(&self.element, &rhs.element) }
160 }
161 }
162 };
163}
164
165impl_xassign_trait!{ AddAssign, add_assign, add_assign_ref }
166impl_xassign_trait!{ MulAssign, mul_assign, mul_assign_ref }
167impl_xassign_trait!{ SubAssign, sub_assign, sub_assign_ref }
168impl_trait!{ Add, add, add_ref_fst, add_ref_snd, add_ref }
169impl_trait!{ Mul, mul, mul_ref_fst, mul_ref_snd, mul_ref }
170impl_trait!{ Sub, sub, sub_ref_fst, sub_ref_snd, sub_ref }
171
172impl<R: RingStore> Div<RingElementWrapper<R>> for RingElementWrapper<R>
173 where R::Type: Field
174{
175 type Output = Self;
176
177 fn div(self, rhs: RingElementWrapper<R>) -> Self::Output {
178 RingElementWrapper { element: self.ring.div(&self.element, &rhs.element), ring: self.ring }
179 }
180}
181
182impl<'a, 'b, R: RingStore + Clone> Div<&'a RingElementWrapper<R>> for &'b RingElementWrapper<R>
183 where R::Type: Field
184{
185 type Output = RingElementWrapper<R>;
186
187 fn div(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
188 RingElementWrapper { element: self.ring.div(&self.element, &rhs.element), ring: self.ring.clone() }
189 }
190}
191
192impl<'a, R: RingStore + Clone> Div<RingElementWrapper<R>> for &'a RingElementWrapper<R>
193 where R::Type: Field
194{
195 type Output = RingElementWrapper<R>;
196
197 fn div(self, rhs: RingElementWrapper<R>) -> Self::Output {
198 RingElementWrapper { element: self.ring.div(&self.element, &rhs.element), ring: rhs.ring }
199 }
200}
201
202impl<'a, R: RingStore + Clone> Div<&'a RingElementWrapper<R>> for RingElementWrapper<R>
203 where R::Type: Field
204{
205 type Output = RingElementWrapper<R>;
206
207 fn div(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
208 RingElementWrapper { element: rhs.ring.div(&self.element, &rhs.element), ring: self.ring }
209 }
210}
211
212macro_rules! impl_xassign_trait_int {
213 ($trait_name:ident, $fn_name:ident) => {
214
215 impl<R: RingStore> $trait_name<i32> for RingElementWrapper<R> {
216
217 fn $fn_name(&mut self, rhs: i32) {
218 self.ring.$fn_name(&mut self.element, self.ring.int_hom().map(rhs));
219 }
220 }
221 };
222}
223
224macro_rules! impl_trait_int {
225 ($trait_name:ident, $fn_name:ident) => {
226
227 impl<R: RingStore> $trait_name<i32> for RingElementWrapper<R> {
228 type Output = Self;
229
230 fn $fn_name(self, rhs: i32) -> Self::Output {
231 RingElementWrapper { element: self.ring.$fn_name(self.element, self.ring.int_hom().map(rhs)), ring: self.ring }
232 }
233 }
234
235 impl<R: RingStore> $trait_name<RingElementWrapper<R>> for i32 {
236 type Output = RingElementWrapper<R>;
237
238 fn $fn_name(self, rhs: RingElementWrapper<R>) -> Self::Output {
239 RingElementWrapper { element: rhs.ring.$fn_name(rhs.ring.int_hom().map(self), rhs.element), ring: rhs.ring }
240 }
241 }
242
243 impl<'a, R: RingStore + Clone> $trait_name<i32> for &'a RingElementWrapper<R> {
244 type Output = RingElementWrapper<R>;
245
246 fn $fn_name(self, rhs: i32) -> Self::Output {
247 RingElementWrapper { element: self.ring.$fn_name(self.ring.clone_el(&self.element), self.ring.int_hom().map(rhs)), ring: self.ring.clone() }
248 }
249 }
250
251 impl<'a, R: RingStore + Clone> $trait_name<&'a RingElementWrapper<R>> for i32 {
252 type Output = RingElementWrapper<R>;
253
254 fn $fn_name(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
255 RingElementWrapper { element: rhs.ring.$fn_name(rhs.ring.int_hom().map(self), rhs.ring.clone_el(&rhs.element)), ring: rhs.ring.clone() }
256 }
257 }
258 };
259}
260
261impl_xassign_trait_int!{ AddAssign, add_assign }
262impl_xassign_trait_int!{ MulAssign, mul_assign }
263impl_xassign_trait_int!{ SubAssign, sub_assign }
264impl_trait_int!{ Add, add }
265impl_trait_int!{ Mul, mul }
266impl_trait_int!{ Sub, sub }
267
268impl<R: RingStore> Div<i32> for RingElementWrapper<R>
269 where R::Type: Field
270{
271 type Output = Self;
272
273 fn div(self, rhs: i32) -> Self::Output {
274 RingElementWrapper { element: self.ring.div(&self.element, &self.ring.int_hom().map(rhs)), ring: self.ring }
275 }
276}
277
278impl<R: RingStore> Div<RingElementWrapper<R>> for i32
279 where R::Type: Field
280{
281 type Output = RingElementWrapper<R>;
282
283 fn div(self, rhs: RingElementWrapper<R>) -> Self::Output {
284 RingElementWrapper { element: rhs.ring.div(&rhs.ring.int_hom().map(self), &rhs.element), ring: rhs.ring }
285 }
286}
287
288impl<'a, R: RingStore + Clone> Div<i32> for &'a RingElementWrapper<R>
289 where R::Type: Field
290{
291 type Output = RingElementWrapper<R>;
292
293 fn div(self, rhs: i32) -> Self::Output {
294 RingElementWrapper { element: self.ring.div(&self.element, &self.ring.int_hom().map(rhs)), ring: self.ring.clone() }
295 }
296}
297
298impl<'a, R: RingStore + Clone> Div<&'a RingElementWrapper<R>> for i32
299 where R::Type: Field
300{
301 type Output = RingElementWrapper<R>;
302
303 fn div(self, rhs: &'a RingElementWrapper<R>) -> Self::Output {
304 RingElementWrapper { element: rhs.ring.div(&rhs.ring.int_hom().map(self), &rhs.element), ring: rhs.ring.clone() }
305 }
306}
307
308impl<R: RingStore + Copy> Copy for RingElementWrapper<R>
309 where El<R>: Copy
310{}
311
312impl<R: RingStore + Clone> Clone for RingElementWrapper<R> {
313
314 fn clone(&self) -> Self {
315 Self { ring: self.ring.clone(), element: self.ring.clone_el(&self.element) }
316 }
317}
318
319impl<R: RingStore> PartialEq for RingElementWrapper<R> {
320
321 fn eq(&self, other: &Self) -> bool {
322 debug_assert!(self.ring.get_ring() == other.ring.get_ring());
323 self.ring.eq_el(&self.element, &other.element)
324 }
325}
326
327impl<R: RingStore> Eq for RingElementWrapper<R> {}
328
329impl<R: RingStore> Hash for RingElementWrapper<R>
330 where R::Type: HashableElRing
331{
332 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
333 self.ring.hash(&self.element, state)
334 }
335}
336
337impl<R: RingStore> Display for RingElementWrapper<R> {
338
339 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340 self.ring.get_ring().dbg(&self.element, f)
341 }
342}
343
344impl<R: RingStore> Debug for RingElementWrapper<R> {
345
346 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
347 self.ring.get_ring().dbg(&self.element, f)
348 }
349}
350
351impl<R: RingStore> Deref for RingElementWrapper<R> {
352 type Target = El<R>;
353
354 fn deref(&self) -> &Self::Target {
355 &self.element
356 }
357}
358
359#[cfg(test)]
360use crate::rings::finite::FiniteRingStore;
361#[cfg(test)]
362use crate::rings::zn::zn_64;
363
364#[test]
365fn test_arithmetic_expression() {
366 let ring = zn_64::Zn::new(17);
367
368 for x in ring.elements() {
369 for y in ring.elements() {
370 for z in ring.elements() {
371 let expected = ring.add(ring.mul(x, y), ring.mul(ring.add(x, z), ring.sub(y, z)));
372 let x = RingElementWrapper::new(&ring, x);
373 let y = RingElementWrapper::new(&ring, y);
374 let z = RingElementWrapper::new(&ring, z);
375 assert_el_eq!(ring, expected, (x * y + (x + z) * (y - z)).unwrap());
376 }
377 }
378 }
379}
380
381#[test]
382fn test_arithmetic_expression_int() {
383 let ring = zn_64::Zn::new(17);
384
385 for x in ring.elements() {
386 for y in ring.elements() {
387 for z in ring.elements() {
388 let expected = ring.add(ring.add(ring.int_hom().mul_map(ring.mul(x, y), 8), ring.mul(ring.add(ring.add(ring.one(), x), ring.int_hom().mul_map(z, 2)), ring.sub(y, ring.int_hom().mul_map(z, 2)))), ring.int_hom().map(5));
389 let x = RingElementWrapper::new(&ring, x);
390 let y = RingElementWrapper::new(&ring, y);
391 let z = RingElementWrapper::new(&ring, z);
392 assert_el_eq!(ring, expected, (x * 8 * y + (1 + x + 2 * z) * (y - z * 2) + 5).unwrap());
393 }
394 }
395 }
396}
397
398#[test]
399fn test_arithmetic_expression_ref() {
400 let ring = zn_64::Zn::new(17);
401
402 for x in ring.elements() {
403 for y in ring.elements() {
404 for z in ring.elements() {
405 let expected = ring.add(ring.mul(x, y), ring.mul(ring.add(x, z), ring.sub(y, z)));
406 let x = RingElementWrapper::new(&ring, x);
407 let y = RingElementWrapper::new(&ring, y);
408 let z = RingElementWrapper::new(&ring, z);
409 assert_el_eq!(ring, expected, (x * &y + (&x + &z) * (&y - z)).unwrap());
410 }
411 }
412 }
413}
414
415#[test]
416fn test_arithmetic_expression_int_ref() {
417 let ring = zn_64::Zn::new(17);
418
419 for x in ring.elements() {
420 for y in ring.elements() {
421 for z in ring.elements() {
422 let expected = ring.add(ring.add(ring.int_hom().mul_map(ring.mul(x, y), 8), ring.mul(ring.add(ring.add(ring.one(), x), ring.int_hom().mul_map(z, 2)), ring.sub(y, ring.int_hom().mul_map(z, 2)))), ring.int_hom().map(5));
423 let x = RingElementWrapper::new(&ring, x);
424 let y = RingElementWrapper::new(&ring, y);
425 let z = RingElementWrapper::new(&ring, z);
426 assert_el_eq!(ring, expected, (x * 8 * &y + (1 + &x + 2 * &z) * (&y - z * 2) + 5).unwrap());
427 }
428 }
429 }
430}