Skip to main content

feanor_math/
delegate.rs

1use std::marker::PhantomData;
2
3use crate::divisibility::DivisibilityRing;
4use crate::homomorphism::*;
5use crate::integer::{IntegerRing, IntegerRingStore};
6use crate::pid::{EuclideanRing, PrincipalIdealRing};
7use crate::ring::*;
8use crate::rings::extension::FreeAlgebra;
9use crate::rings::finite::FiniteRing;
10use crate::rings::zn::ZnRing;
11use crate::serialization::SerializableElementRing;
12use crate::specialization::*;
13
14/// Trait to simplify implementing newtype-pattern for rings.
15/// When you want to create a ring that just wraps another ring,
16/// possibly adding some functionality, you can implement `DelegateRing`
17/// instead of `RingBase`, and just provide how to map elements in the new
18/// ring to the wrapped ring and vice versa.
19///
20/// # Conditional Implementations
21///
22/// Some special ring traits (e.g. [`DivisibilityRing`]) are immediately implemented
23/// for `R: DelegateRing` as soon as `R::Base: SpecialRingTrait`. However, this
24/// of course prevents any implementation fo [`DelegateRing`] to provide a custom
25/// implementation (except for specialization in some cases), due to conflicting
26/// trait impls. Hence, for other traits, we use marker traits to mark an implementation
27/// `R` of [`DelegateRing`] to also automatically implement a special ring trait as soon
28/// as `R::Base: SpecialRingTrait`. These cases are currently
29///  - [`DelegateRingImplFiniteRing`] for automatic implementations of [`FiniteRing`] and
30///    [`FiniteRingSpecializable`].
31///  - [`DelegateRingImplEuclideanRing`] for automatic implementations of [`PrincipalIdealRing`] and
32///    [`EuclideanRing`]
33///
34/// # Example
35///
36/// ```rust
37/// # use feanor_math::ring::*;
38/// # use feanor_math::homomorphism::*;
39/// # use feanor_math::primitive_int::*;
40/// # use feanor_math::delegate::*;
41/// # use feanor_math::{assert_el_eq, impl_eq_based_self_iso};
42///
43/// #[derive(PartialEq, Clone)]
44/// struct MyI32Ring;
45/// struct MyI32RingEl(i32);
46///
47/// impl DelegateRing for MyI32Ring {
48///     type Base = StaticRingBase<i32>;
49///     type Element = MyI32RingEl;
50///
51///     fn get_delegate(&self) -> &Self::Base { StaticRing::<i32>::RING.get_ring() }
52///
53///     fn delegate_ref<'a>(&self, MyI32RingEl(el): &'a MyI32RingEl) -> &'a i32 { el }
54///
55///     fn delegate_mut<'a>(&self, MyI32RingEl(el): &'a mut MyI32RingEl) -> &'a mut i32 { el }
56///
57///     fn delegate(&self, MyI32RingEl(el): MyI32RingEl) -> i32 { el }
58///
59///     fn postprocess_delegate_mut(&self, _: &mut MyI32RingEl) {
60///         // sometimes it might be necessary to fix some data of `Self::Element`
61///         // if the underlying `Self::Base::Element` was modified via `delegate_mut()`;
62///         // this is not the case here, so leave empty
63///     }
64///
65///     fn rev_delegate(&self, el: i32) -> MyI32RingEl { MyI32RingEl(el) }
66/// }
67///
68/// // you will have to implement `CanIsoFromTo<Self>`
69/// impl_eq_based_self_iso! { MyI32Ring }
70///
71/// let ring = RingValue::from(MyI32Ring);
72/// assert_el_eq!(ring, ring.int_hom().map(1), ring.one());
73/// ```
74/// An example when special ring traits are automatically implemented is
75/// given by the following.
76/// ```rust
77/// # use feanor_math::ring::*;
78/// # use feanor_math::homomorphism::*;
79/// # use feanor_math::delegate::*;
80/// # use feanor_math::{assert_el_eq, impl_eq_based_self_iso};
81///
82/// struct BoringRingWrapper<R>(R);
83///
84/// impl<R> PartialEq for BoringRingWrapper<R>
85/// where
86///     R: RingStore,
87/// {
88///     fn eq(&self, other: &Self) -> bool { self.0.get_ring() == other.0.get_ring() }
89/// }
90///
91/// impl<R> DelegateRing for BoringRingWrapper<R>
92/// where
93///     R: RingStore,
94/// {
95///     type Base = R::Type;
96///     type Element = El<R>;
97///
98///     fn get_delegate(&self) -> &Self::Base { self.0.get_ring() }
99///
100///     fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element { el }
101///     fn delegate_mut<'a>(
102///         &self,
103///         el: &'a mut Self::Element,
104///     ) -> &'a mut <Self::Base as RingBase>::Element {
105///         el
106///     }
107///     fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element {
108///         el
109///     }
110///     fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element { el }
111/// }
112/// ```
113/// [`DivisibilityRing`] is automatically implemented (but can be specialized):
114/// ```rust
115/// # use feanor_math::ring::*;
116/// # use feanor_math::homomorphism::*;
117/// # use feanor_math::divisibility::*;
118/// # use feanor_math::delegate::*;
119/// # use feanor_math::{assert_el_eq, impl_eq_based_self_iso};
120/// #
121/// # struct BoringRingWrapper<R>(R);
122/// #
123/// # impl<R> PartialEq for BoringRingWrapper<R>
124/// #     where R: RingStore
125/// # {
126/// #     fn eq(&self, other: &Self) -> bool {
127/// #         self.0.get_ring() == other.0.get_ring()
128/// #     }
129/// # }
130/// #
131/// # impl<R> DelegateRing for BoringRingWrapper<R>
132/// #     where R: RingStore
133/// # {
134/// #     type Base = R::Type;
135/// #     type Element = El<R>;
136/// #
137/// #     fn get_delegate(&self) -> &Self::Base {
138/// #         self.0.get_ring()
139/// #     }
140/// #
141/// #     fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element { el }
142/// #     fn delegate_mut<'a>(&self, el: &'a mut Self::Element) -> &'a mut <Self::Base as RingBase>::Element { el }
143/// #     fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element { el }
144/// #     fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element { el }
145/// # }
146/// fn divide_in_wrapped_ring<R>(base_ring: R)
147///     where R: RingStore,
148///         R::Type: DivisibilityRing
149/// {
150///     let wrapped_ring = BoringRingWrapper(base_ring);
151///     assert!(wrapped_ring.checked_div(&wrapped_ring.one(), &wrapped_ring.one()).is_some());
152/// }
153/// ```
154/// [`FiniteRing`] for example is not automatically implemented:
155/// ```rust,compile_fail
156/// # use feanor_math::ring::*;
157/// # use feanor_math::homomorphism::*;
158/// # use feanor_math::rings::finite::*;
159/// # use feanor_math::integer::*;
160/// # use feanor_math::delegate::*;
161/// # use feanor_math::{assert_el_eq, impl_eq_based_self_iso};
162/// #
163/// # impl<R> PartialEq for BoringRingWrapper<R>
164/// #     where R: RingStore
165/// # {
166/// #     fn eq(&self, other: &Self) -> bool {
167/// #         self.0.get_ring() == other.0.get_ring()
168/// #     }
169/// # }
170/// #
171/// # struct BoringRingWrapper<R>(R);
172/// #
173/// # impl<R> DelegateRing for BoringRingWrapper<R>
174/// #     where R: RingStore
175/// # {
176/// #     type Base = R::Type;
177/// #     type Element = El<R>;
178/// #
179/// #     fn get_delegate(&self) -> &Self::Base {
180/// #         self.0.get_ring()
181/// #     }
182/// #
183/// #     fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element { el }
184/// #     fn delegate_mut<'a>(&self, el: &'a mut Self::Element) -> &'a mut <Self::Base as RingBase>::Element { el }
185/// #     fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element { el }
186/// #     fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element { el }
187/// # }
188/// fn size_of_wrapped_ring<R>(base_ring: R)
189///     where R: RingStore,
190///         R::Type: FiniteRing
191/// {
192///     let wrapped_ring = BoringRingWrapper(base_ring);
193///     assert!(wrapped_ring.size(BigIntRing::RING).is_some());
194/// }
195/// ```
196/// But we can add a delegate-implementation of [`FiniteRing`] by adding the marker trait
197/// [`DelegateRingImplFiniteRing`]: ```rust
198/// # use feanor_math::ring::*;
199/// # use feanor_math::homomorphism::*;
200/// # use feanor_math::rings::finite::*;
201/// # use feanor_math::integer::*;
202/// # use feanor_math::delegate::*;
203/// # use feanor_math::{assert_el_eq, impl_eq_based_self_iso};
204/// #
205/// # impl<R> PartialEq for BoringRingWrapper<R>
206/// #     where R: RingStore
207/// # {
208/// #     fn eq(&self, other: &Self) -> bool {
209/// #         self.0.get_ring() == other.0.get_ring()
210/// #     }
211/// # }
212/// #
213/// # struct BoringRingWrapper<R>(R);
214/// #
215/// # impl<R> DelegateRing for BoringRingWrapper<R>
216/// #     where R: RingStore
217/// # {
218/// #     type Base = R::Type;
219/// #     type Element = El<R>;
220/// #
221/// #     fn get_delegate(&self) -> &Self::Base {
222/// #         self.0.get_ring()
223/// #     }
224/// #
225/// #     fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element { el }
226/// #     fn delegate_mut<'a>(&self, el: &'a mut Self::Element) -> &'a mut <Self::Base as RingBase>::Element { el }
227/// #     fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element { el }
228/// #     fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element { el }
229/// # }
230/// impl<R> DelegateRingImplFiniteRing for BoringRingWrapper<R>
231///     where R: RingStore
232/// {}
233///
234/// fn size_of_wrapped_ring<R>(base_ring: R)
235///     where R: RingStore,
236///         R::Type: FiniteRing
237/// {
238///     let wrapped_ring = BoringRingWrapper(base_ring);
239///     assert!(wrapped_ring.size(BigIntRing::RING).is_some());
240/// }
241/// ```
242pub trait DelegateRing: PartialEq {
243    /// Type of the delegated-to ring.
244    type Base: ?Sized + RingBase;
245
246    /// Type of elements of this ring. These should always wrap elements from the delegated-to ring,
247    /// but may store additional data.
248    type Element;
249
250    /// Returns a reference to the delegated-to ring, which is used by all other default
251    /// implementations to actually implement arithmetic operations.
252    fn get_delegate(&self) -> &Self::Base;
253
254    /// Provides a reference to the delegated-to ring element stored in the given element from this
255    /// ring.
256    fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element;
257
258    /// Provides a mutable reference to the delegated-to ring element stored in the given element
259    /// from this ring.
260    fn delegate_mut<'a>(&self, el: &'a mut Self::Element) -> &'a mut <Self::Base as RingBase>::Element;
261
262    /// Creates an element of the delegated-to ring, representing the given element from this ring.
263    fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element;
264
265    /// Creates an element of this ring, representing the given element from the delegated-to ring.
266    fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element;
267
268    /// Called after every operation of the delegated-to ring that accepts a mutable reference
269    /// (which is acquired using [`DelegateRing::delegate_mut()`]).
270    ///
271    /// This can be used to update additional data, that is stored for every element in
272    /// addition to the delegated-to ring element. In many cases, this can be empty.
273    fn postprocess_delegate_mut(&self, el: &mut Self::Element) {
274        *el = self.rev_delegate(self.get_delegate().clone_el(self.delegate_ref(el)));
275    }
276
277    /// Necessary in some locations to satisfy the type system
278    fn element_cast(&self, el: Self::Element) -> <Self as RingBase>::Element { el }
279
280    /// Necessary in some locations to satisfy the type system
281    fn rev_element_cast(&self, el: <Self as RingBase>::Element) -> Self::Element { el }
282
283    /// Necessary in some locations to satisfy the type system
284    fn rev_element_cast_ref<'a>(&self, el: &'a <Self as RingBase>::Element) -> &'a Self::Element { el }
285
286    /// Necessary in some locations to satisfy the type system
287    fn rev_element_cast_mut<'a>(&self, el: &'a mut <Self as RingBase>::Element) -> &'a mut Self::Element { el }
288}
289
290impl<R: DelegateRing + PartialEq + ?Sized> RingBase for R {
291    type Element = <Self as DelegateRing>::Element;
292
293    default fn clone_el(&self, val: &Self::Element) -> Self::Element {
294        self.rev_delegate(self.get_delegate().clone_el(self.delegate_ref(val)))
295    }
296
297    default fn add_assign_ref(&self, lhs: &mut Self::Element, rhs: &Self::Element) {
298        self.get_delegate()
299            .add_assign_ref(self.delegate_mut(lhs), self.delegate_ref(rhs));
300        self.postprocess_delegate_mut(lhs);
301    }
302
303    default fn add_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
304        self.get_delegate()
305            .add_assign(self.delegate_mut(lhs), self.delegate(rhs));
306        self.postprocess_delegate_mut(lhs);
307    }
308
309    default fn sub_assign_ref(&self, lhs: &mut Self::Element, rhs: &Self::Element) {
310        self.get_delegate()
311            .sub_assign_ref(self.delegate_mut(lhs), self.delegate_ref(rhs));
312        self.postprocess_delegate_mut(lhs);
313    }
314
315    default fn sub_self_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
316        self.get_delegate()
317            .sub_self_assign(self.delegate_mut(lhs), self.delegate(rhs));
318        self.postprocess_delegate_mut(lhs);
319    }
320
321    default fn sub_self_assign_ref(&self, lhs: &mut Self::Element, rhs: &Self::Element) {
322        self.get_delegate()
323            .sub_self_assign_ref(self.delegate_mut(lhs), self.delegate_ref(rhs));
324        self.postprocess_delegate_mut(lhs);
325    }
326
327    default fn negate_inplace(&self, lhs: &mut Self::Element) {
328        self.get_delegate().negate_inplace(self.delegate_mut(lhs));
329        self.postprocess_delegate_mut(lhs);
330    }
331
332    default fn mul_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
333        self.get_delegate()
334            .mul_assign(self.delegate_mut(lhs), self.delegate(rhs));
335        self.postprocess_delegate_mut(lhs);
336    }
337
338    default fn mul_assign_ref(&self, lhs: &mut Self::Element, rhs: &Self::Element) {
339        self.get_delegate()
340            .mul_assign_ref(self.delegate_mut(lhs), self.delegate_ref(rhs));
341        self.postprocess_delegate_mut(lhs);
342    }
343
344    default fn square(&self, value: &mut Self::Element) {
345        self.get_delegate().square(self.delegate_mut(value));
346        self.postprocess_delegate_mut(value);
347    }
348
349    default fn eq_el(&self, lhs: &Self::Element, rhs: &Self::Element) -> bool {
350        self.get_delegate()
351            .eq_el(self.delegate_ref(lhs), self.delegate_ref(rhs))
352    }
353
354    default fn is_neg_one(&self, value: &Self::Element) -> bool {
355        self.get_delegate().is_neg_one(self.delegate_ref(value))
356    }
357
358    default fn zero(&self) -> Self::Element { self.rev_delegate(self.get_delegate().zero()) }
359
360    default fn one(&self) -> Self::Element { self.rev_delegate(self.get_delegate().one()) }
361
362    default fn neg_one(&self) -> Self::Element { self.rev_delegate(self.get_delegate().neg_one()) }
363
364    default fn from_int(&self, value: i32) -> Self::Element { self.rev_delegate(self.get_delegate().from_int(value)) }
365
366    default fn is_zero(&self, value: &Self::Element) -> bool { self.get_delegate().is_zero(self.delegate_ref(value)) }
367
368    default fn is_one(&self, value: &Self::Element) -> bool { self.get_delegate().is_one(self.delegate_ref(value)) }
369
370    default fn is_commutative(&self) -> bool { self.get_delegate().is_commutative() }
371
372    default fn is_noetherian(&self) -> bool { self.get_delegate().is_noetherian() }
373
374    default fn dbg<'a>(&self, value: &Self::Element, out: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
375        self.get_delegate().dbg(self.delegate_ref(value), out)
376    }
377
378    default fn dbg_within<'a>(
379        &self,
380        value: &Self::Element,
381        out: &mut std::fmt::Formatter<'a>,
382        env: EnvBindingStrength,
383    ) -> std::fmt::Result {
384        self.get_delegate().dbg_within(self.delegate_ref(value), out, env)
385    }
386
387    default fn negate(&self, value: Self::Element) -> Self::Element {
388        self.rev_delegate(self.get_delegate().negate(self.delegate(value)))
389    }
390
391    default fn sub_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
392        self.get_delegate()
393            .sub_assign(self.delegate_mut(lhs), self.delegate(rhs));
394        self.postprocess_delegate_mut(lhs);
395    }
396
397    default fn add_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
398        self.rev_delegate(
399            self.get_delegate()
400                .add_ref(self.delegate_ref(lhs), self.delegate_ref(rhs)),
401        )
402    }
403
404    default fn add_ref_fst(&self, lhs: &Self::Element, rhs: Self::Element) -> Self::Element {
405        self.rev_delegate(
406            self.get_delegate()
407                .add_ref_fst(self.delegate_ref(lhs), self.delegate(rhs)),
408        )
409    }
410
411    default fn add_ref_snd(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
412        self.rev_delegate(
413            self.get_delegate()
414                .add_ref_snd(self.delegate(lhs), self.delegate_ref(rhs)),
415        )
416    }
417
418    default fn add(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element {
419        self.rev_delegate(self.get_delegate().add(self.delegate(lhs), self.delegate(rhs)))
420    }
421
422    default fn sub_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
423        self.rev_delegate(
424            self.get_delegate()
425                .sub_ref(self.delegate_ref(lhs), self.delegate_ref(rhs)),
426        )
427    }
428
429    default fn sub_ref_fst(&self, lhs: &Self::Element, rhs: Self::Element) -> Self::Element {
430        self.rev_delegate(
431            self.get_delegate()
432                .sub_ref_fst(self.delegate_ref(lhs), self.delegate(rhs)),
433        )
434    }
435
436    default fn sub_ref_snd(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
437        self.rev_delegate(
438            self.get_delegate()
439                .sub_ref_snd(self.delegate(lhs), self.delegate_ref(rhs)),
440        )
441    }
442
443    default fn sub(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element {
444        self.rev_delegate(self.get_delegate().sub(self.delegate(lhs), self.delegate(rhs)))
445    }
446
447    default fn mul_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
448        self.rev_delegate(
449            self.get_delegate()
450                .mul_ref(self.delegate_ref(lhs), self.delegate_ref(rhs)),
451        )
452    }
453
454    default fn mul_ref_fst(&self, lhs: &Self::Element, rhs: Self::Element) -> Self::Element {
455        self.rev_delegate(
456            self.get_delegate()
457                .mul_ref_fst(self.delegate_ref(lhs), self.delegate(rhs)),
458        )
459    }
460
461    default fn mul_ref_snd(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
462        self.rev_delegate(
463            self.get_delegate()
464                .mul_ref_snd(self.delegate(lhs), self.delegate_ref(rhs)),
465        )
466    }
467
468    default fn mul(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element {
469        self.rev_delegate(self.get_delegate().mul(self.delegate(lhs), self.delegate(rhs)))
470    }
471
472    default fn is_approximate(&self) -> bool { self.get_delegate().is_approximate() }
473
474    default fn mul_assign_int(&self, lhs: &mut Self::Element, rhs: i32) {
475        self.get_delegate().mul_assign_int(self.delegate_mut(lhs), rhs);
476        self.postprocess_delegate_mut(lhs);
477    }
478
479    default fn mul_int(&self, lhs: Self::Element, rhs: i32) -> Self::Element {
480        self.rev_delegate(self.get_delegate().mul_int(self.delegate(lhs), rhs))
481    }
482
483    default fn mul_int_ref(&self, lhs: &Self::Element, rhs: i32) -> Self::Element {
484        self.rev_delegate(self.get_delegate().mul_int_ref(self.delegate_ref(lhs), rhs))
485    }
486
487    default fn pow_gen<S: IntegerRingStore>(&self, x: Self::Element, power: &El<S>, integers: S) -> Self::Element
488    where
489        S::Type: IntegerRing,
490    {
491        self.rev_delegate(self.get_delegate().pow_gen(self.delegate(x), power, integers))
492    }
493
494    default fn characteristic<I: IntegerRingStore + Copy>(&self, ZZ: I) -> Option<El<I>>
495    where
496        I::Type: IntegerRing,
497    {
498        self.get_delegate().characteristic(ZZ)
499    }
500}
501
502impl<R: DelegateRing + ?Sized> DivisibilityRing for R
503where
504    R::Base: DivisibilityRing,
505{
506    type PreparedDivisorData = <R::Base as DivisibilityRing>::PreparedDivisorData;
507
508    default fn checked_left_div(&self, lhs: &Self::Element, rhs: &Self::Element) -> Option<Self::Element> {
509        self.get_delegate()
510            .checked_left_div(self.delegate_ref(lhs), self.delegate_ref(rhs))
511            .map(|x| self.rev_delegate(x))
512    }
513
514    default fn balance_factor<'a, I>(&self, elements: I) -> Option<Self::Element>
515    where
516        I: Iterator<Item = &'a Self::Element>,
517        Self: 'a,
518    {
519        self.get_delegate()
520            .balance_factor(elements.map(|x| self.delegate_ref(x)))
521            .map(|c| self.rev_delegate(c))
522    }
523
524    fn prepare_divisor(&self, x: &Self::Element) -> Self::PreparedDivisorData {
525        self.get_delegate().prepare_divisor(self.delegate_ref(x))
526    }
527
528    default fn checked_left_div_prepared(
529        &self,
530        lhs: &Self::Element,
531        rhs: &Self::Element,
532        rhs_prep: &Self::PreparedDivisorData,
533    ) -> Option<Self::Element> {
534        self.get_delegate()
535            .checked_left_div_prepared(self.delegate_ref(lhs), self.delegate_ref(rhs), rhs_prep)
536            .map(|res| self.rev_delegate(res))
537    }
538
539    default fn divides_left_prepared(
540        &self,
541        lhs: &Self::Element,
542        rhs: &Self::Element,
543        rhs_prep: &Self::PreparedDivisorData,
544    ) -> bool {
545        self.get_delegate()
546            .divides_left_prepared(self.delegate_ref(lhs), self.delegate_ref(rhs), rhs_prep)
547    }
548}
549
550impl<R: DelegateRing + ?Sized> SerializableElementRing for R
551where
552    R::Base: DivisibilityRing + SerializableElementRing,
553{
554    default fn serialize<S>(&self, el: &Self::Element, serializer: S) -> Result<S::Ok, S::Error>
555    where
556        S: serde::Serializer,
557    {
558        self.get_delegate().serialize(self.delegate_ref(el), serializer)
559    }
560
561    default fn deserialize<'de, D>(&self, deserializer: D) -> Result<Self::Element, D::Error>
562    where
563        D: serde::Deserializer<'de>,
564    {
565        self.get_delegate()
566            .deserialize(deserializer)
567            .map(|x| self.rev_delegate(x))
568    }
569}
570
571/// Iterator over all elements of a finite [`DelegateRing`].
572pub struct DelegateFiniteRingElementsIter<'a, R: ?Sized>
573where
574    R: DelegateRing,
575    R::Base: FiniteRing,
576{
577    ring: &'a R,
578    base: <R::Base as FiniteRing>::ElementsIter<'a>,
579}
580
581impl<'a, R: ?Sized> Clone for DelegateFiniteRingElementsIter<'a, R>
582where
583    R: DelegateRing,
584    R::Base: FiniteRing,
585{
586    fn clone(&self) -> Self {
587        Self {
588            ring: self.ring,
589            base: self.base.clone(),
590        }
591    }
592}
593
594impl<'a, R: ?Sized> Iterator for DelegateFiniteRingElementsIter<'a, R>
595where
596    R: DelegateRing,
597    R::Base: FiniteRing,
598{
599    type Item = <R as RingBase>::Element;
600
601    fn next(&mut self) -> Option<Self::Item> { self.base.next().map(|x| self.ring.rev_delegate(x)) }
602}
603
604/// Marks a [`DelegateRing`] `R` to be considered in the blanket implementation
605/// `R: FiniteRing where R::Base: FiniteRing`.
606///
607/// We don't want to implement `R: FiniteRing` for any `DelegateRing` `R`, since
608/// some ring newtypes want to have control of when the ring is [`FiniteRing`].
609pub trait DelegateRingImplFiniteRing: DelegateRing {}
610
611impl<R: DelegateRingImplFiniteRing + ?Sized> FiniteRing for R
612where
613    R::Base: FiniteRing,
614{
615    type ElementsIter<'a>
616        = DelegateFiniteRingElementsIter<'a, R>
617    where
618        R: 'a;
619
620    fn elements<'a>(&'a self) -> Self::ElementsIter<'a> {
621        DelegateFiniteRingElementsIter {
622            ring: self,
623            base: self.get_delegate().elements(),
624        }
625    }
626
627    default fn random_element<G: FnMut() -> u64>(&self, rng: G) -> <R as RingBase>::Element {
628        self.element_cast(self.rev_delegate(self.get_delegate().random_element(rng)))
629    }
630
631    default fn size<I: IntegerRingStore + Copy>(&self, ZZ: I) -> Option<El<I>>
632    where
633        I::Type: IntegerRing,
634    {
635        self.get_delegate().size(ZZ)
636    }
637}
638
639impl<R: DelegateRing + ?Sized> HashableElRing for R
640where
641    R::Base: HashableElRing,
642{
643    default fn hash<H: std::hash::Hasher>(&self, el: &Self::Element, h: &mut H) {
644        self.get_delegate().hash(self.delegate_ref(el), h)
645    }
646}
647
648/// Marks a [`DelegateRing`] `R` to be considered in the blanket implementation
649/// `R: EuclideanRing where R::Base: EuclideanRing` and
650/// `R: PrincipalIdealRing where R::Base: PrincipalIdealRing`.
651///
652/// We don't want to implement `R: EuclideanRing` for any `DelegateRing` `R`, since
653/// some ring newtypes want to have control of when the ring is [`EuclideanRing`].
654pub trait DelegateRingImplEuclideanRing: DelegateRing {}
655
656impl<R: DelegateRingImplEuclideanRing + ?Sized> PrincipalIdealRing for R
657where
658    R::Base: PrincipalIdealRing,
659{
660    default fn checked_div_min(&self, lhs: &Self::Element, rhs: &Self::Element) -> Option<Self::Element> {
661        self.get_delegate()
662            .checked_div_min(self.delegate_ref(lhs), self.delegate_ref(rhs))
663            .map(|res| self.rev_delegate(res))
664    }
665
666    default fn extended_ideal_gen(
667        &self,
668        lhs: &Self::Element,
669        rhs: &Self::Element,
670    ) -> (Self::Element, Self::Element, Self::Element) {
671        let (s, t, d) = self.get_delegate().extended_ideal_gen(
672            self.delegate_ref(self.rev_element_cast_ref(lhs)),
673            self.delegate_ref(self.rev_element_cast_ref(rhs)),
674        );
675        return (
676            self.element_cast(self.rev_delegate(s)),
677            self.element_cast(self.rev_delegate(t)),
678            self.element_cast(self.rev_delegate(d)),
679        );
680    }
681
682    default fn ideal_gen(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
683        self.element_cast(self.rev_delegate(self.get_delegate().ideal_gen(
684            self.delegate_ref(self.rev_element_cast_ref(lhs)),
685            self.delegate_ref(self.rev_element_cast_ref(rhs)),
686        )))
687    }
688}
689
690impl<R: DelegateRingImplEuclideanRing + ?Sized> EuclideanRing for R
691where
692    R::Base: EuclideanRing,
693{
694    default fn euclidean_div_rem(&self, lhs: Self::Element, rhs: &Self::Element) -> (Self::Element, Self::Element) {
695        let (q, r) = self
696            .get_delegate()
697            .euclidean_div_rem(self.delegate(lhs), self.delegate_ref(rhs));
698        return (self.rev_delegate(q), self.rev_delegate(r));
699    }
700
701    fn euclidean_deg(&self, val: &Self::Element) -> Option<usize> {
702        self.get_delegate().euclidean_deg(self.delegate_ref(val))
703    }
704
705    fn euclidean_div(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
706        self.rev_delegate(
707            self.get_delegate()
708                .euclidean_div(self.delegate(lhs), self.delegate_ref(rhs)),
709        )
710    }
711
712    fn euclidean_rem(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
713        self.rev_delegate(
714            self.get_delegate()
715                .euclidean_rem(self.delegate(lhs), self.delegate_ref(rhs)),
716        )
717    }
718}
719
720impl<R> FiniteRingSpecializable for R
721where
722    R: DelegateRingImplFiniteRing + ?Sized,
723    R::Base: FiniteRingSpecializable,
724{
725    fn specialize<O: FiniteRingOperation<Self>>(op: O) -> O::Output {
726        struct OpWrapper<R, O>
727        where
728            R: DelegateRingImplFiniteRing + ?Sized,
729            R::Base: FiniteRingSpecializable,
730            O: FiniteRingOperation<R>,
731        {
732            operation: O,
733            ring: PhantomData<Box<R>>,
734        }
735
736        impl<R, O> FiniteRingOperation<R::Base> for OpWrapper<R, O>
737        where
738            R: DelegateRingImplFiniteRing + ?Sized,
739            R::Base: FiniteRingSpecializable,
740            O: FiniteRingOperation<R>,
741        {
742            type Output = O::Output;
743
744            fn execute(self) -> Self::Output
745            where
746                R::Base: FiniteRing,
747            {
748                self.operation.execute()
749            }
750
751            fn fallback(self) -> Self::Output { self.operation.fallback() }
752        }
753
754        <R::Base as FiniteRingSpecializable>::specialize(OpWrapper {
755            operation: op,
756            ring: PhantomData,
757        })
758    }
759}
760
761impl<R: DelegateRingImplFiniteRing + ?Sized> ZnRing for R
762where
763    R::Base: ZnRing,
764    Self: PrincipalIdealRing,
765    R: CanHomFrom<<R::Base as ZnRing>::IntegerRingBase>,
766{
767    type IntegerRingBase = <R::Base as ZnRing>::IntegerRingBase;
768    type IntegerRing = <R::Base as ZnRing>::IntegerRing;
769
770    default fn integer_ring(&self) -> &Self::IntegerRing { self.get_delegate().integer_ring() }
771
772    default fn modulus(&self) -> &El<Self::IntegerRing> { self.get_delegate().modulus() }
773
774    default fn smallest_positive_lift(&self, el: Self::Element) -> El<Self::IntegerRing> {
775        self.get_delegate()
776            .smallest_positive_lift(self.delegate(self.rev_element_cast(el)))
777    }
778
779    default fn smallest_lift(&self, el: Self::Element) -> El<Self::IntegerRing> {
780        self.get_delegate()
781            .smallest_lift(self.delegate(self.rev_element_cast(el)))
782    }
783
784    default fn from_int_promise_reduced(&self, x: El<Self::IntegerRing>) -> Self::Element {
785        self.element_cast(self.rev_delegate(self.get_delegate().from_int_promise_reduced(x)))
786    }
787}
788
789impl<R> RingExtension for R
790where
791    R: DelegateRing,
792    R::Base: RingExtension,
793{
794    type BaseRing = <R::Base as RingExtension>::BaseRing;
795
796    fn base_ring(&self) -> &Self::BaseRing { self.get_delegate().base_ring() }
797
798    fn from(&self, x: El<Self::BaseRing>) -> Self::Element { self.rev_delegate(self.get_delegate().from(x)) }
799}
800
801impl<R> FreeAlgebra for R
802where
803    R: DelegateRing,
804    <R as DelegateRing>::Base: FreeAlgebra,
805{
806    type VectorRepresentation<'a>
807        = <<R as DelegateRing>::Base as FreeAlgebra>::VectorRepresentation<'a>
808    where
809        Self: 'a;
810
811    default fn canonical_gen(&self) -> Self::Element { self.rev_delegate(self.get_delegate().canonical_gen()) }
812
813    default fn from_canonical_basis<V>(&self, vec: V) -> Self::Element
814    where
815        V: IntoIterator<Item = El<Self::BaseRing>>,
816        V::IntoIter: DoubleEndedIterator,
817    {
818        self.rev_delegate(self.get_delegate().from_canonical_basis(vec))
819    }
820
821    default fn rank(&self) -> usize { self.get_delegate().rank() }
822
823    default fn wrt_canonical_basis<'a>(&'a self, el: &'a Self::Element) -> Self::VectorRepresentation<'a> {
824        self.get_delegate().wrt_canonical_basis(self.delegate_ref(el))
825    }
826
827    default fn mul_assign_gen_power(&self, el: &mut Self::Element, power: usize) {
828        self.get_delegate().mul_assign_gen_power(self.delegate_mut(el), power);
829        self.postprocess_delegate_mut(el);
830    }
831}
832
833/// Homomorphism from a ring to a [`DelegateRing`] with the former ring
834/// as delegate target. An element is mapped by using [`DelegateRing::rev_delegate()`].
835pub struct WrapHom<R, S>
836where
837    R: RingStore,
838    S::Type: DelegateRing<Base = R::Type>,
839    S: RingStore,
840{
841    from: R,
842    to: S,
843}
844
845impl<R, S> WrapHom<R, S>
846where
847    R: RingStore,
848    S::Type: DelegateRing<Base = R::Type>,
849    S: RingStore,
850{
851    /// Creates a new [`WrapHom`] between the given rings.
852    pub fn new(from: R, to: S) -> Self { Self { from, to } }
853}
854
855impl<'a, R> WrapHom<RingRef<'a, R::Base>, RingRef<'a, R>>
856where
857    R: ?Sized + DelegateRing,
858{
859    /// Creates a new [`WrapHom`] from the given ring's delegate target
860    /// to the given ring.
861    ///
862    /// This function must take `to` by reference, since it must be able to
863    /// obtain a reference to its delegate target that lives long enough.
864    pub fn to_delegate_ring(to: &'a R) -> Self { Self::new(RingRef::new(to.get_delegate()), RingRef::new(to)) }
865}
866
867impl<R, S> Homomorphism<R::Type, S::Type> for WrapHom<R, S>
868where
869    R: RingStore,
870    S::Type: DelegateRing<Base = R::Type>,
871    S: RingStore,
872{
873    type DomainStore = R;
874    type CodomainStore = S;
875
876    fn domain(&self) -> &Self::DomainStore { &self.from }
877
878    fn codomain(&self) -> &Self::CodomainStore { &self.to }
879
880    fn map(&self, x: El<R>) -> El<S> { self.to.get_ring().element_cast(self.to.get_ring().rev_delegate(x)) }
881}
882
883/// Homomorphism from a [`DelegateRing`] to its delegate target. An element
884/// is mapped by using [`DelegateRing::delegate()`].
885pub struct UnwrapHom<R, S>
886where
887    R: RingStore,
888    R::Type: DelegateRing<Base = S::Type>,
889    S: RingStore,
890{
891    from: R,
892    to: S,
893}
894
895impl<R, S> UnwrapHom<R, S>
896where
897    R: RingStore,
898    R::Type: DelegateRing<Base = S::Type>,
899    S: RingStore,
900{
901    /// Creates a new [`UnwrapHom`] between the given rings.
902    pub fn new(from: R, to: S) -> Self { Self { from, to } }
903}
904
905impl<'a, R> UnwrapHom<RingRef<'a, R>, RingRef<'a, R::Base>>
906where
907    R: ?Sized + DelegateRing,
908{
909    /// Creates a new [`UnwrapHom`] from the given ring to its delegate target.
910    ///
911    /// This function must take `from` by reference, since it must be able to
912    /// obtain a reference to its delegate target that lives long enough.
913    pub fn from_delegate_ring(from: &'a R) -> Self { Self::new(RingRef::new(from), RingRef::new(from.get_delegate())) }
914}
915
916impl<R, S> Homomorphism<R::Type, S::Type> for UnwrapHom<R, S>
917where
918    R: RingStore,
919    R::Type: DelegateRing<Base = S::Type>,
920    S: RingStore,
921{
922    type DomainStore = R;
923    type CodomainStore = S;
924
925    fn domain(&self) -> &Self::DomainStore { &self.from }
926
927    fn codomain(&self) -> &Self::CodomainStore { &self.to }
928
929    fn map(&self, x: El<R>) -> El<S> { self.from.get_ring().delegate(self.from.get_ring().rev_element_cast(x)) }
930}