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
14pub trait DelegateRing: PartialEq {
243 type Base: ?Sized + RingBase;
245
246 type Element;
249
250 fn get_delegate(&self) -> &Self::Base;
253
254 fn delegate_ref<'a>(&self, el: &'a Self::Element) -> &'a <Self::Base as RingBase>::Element;
257
258 fn delegate_mut<'a>(&self, el: &'a mut Self::Element) -> &'a mut <Self::Base as RingBase>::Element;
261
262 fn delegate(&self, el: Self::Element) -> <Self::Base as RingBase>::Element;
264
265 fn rev_delegate(&self, el: <Self::Base as RingBase>::Element) -> Self::Element;
267
268 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 fn element_cast(&self, el: Self::Element) -> <Self as RingBase>::Element { el }
279
280 fn rev_element_cast(&self, el: <Self as RingBase>::Element) -> Self::Element { el }
282
283 fn rev_element_cast_ref<'a>(&self, el: &'a <Self as RingBase>::Element) -> &'a Self::Element { el }
285
286 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
571pub 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
604pub 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
648pub 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
833pub 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 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 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
883pub 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 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 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}