1use std::fmt::Debug;
2use std::hash::{Hash, Hasher};
3use std::ops::Deref;
4
5use feanor_serde::newtype_struct::{DeserializeSeedNewtypeStruct, SerializableNewtypeStruct};
6use serde::de::DeserializeSeed;
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8
9use crate::algorithms::sqr_mul::generic_abs_square_and_multiply;
10use crate::divisibility::{DivisibilityRing, DivisibilityRingStore};
11use crate::integer::BigIntRing;
12use crate::ring::*;
13use crate::ordered::OrderedRingStore;
14use crate::serialization::{DeserializeWithRing, SerializableElementRing, SerializeWithRing};
15
16#[stability::unstable(feature = "enable")]
29pub trait AbelianGroupBase: PartialEq {
30
31 type Element;
35
36 fn clone_el(&self, x: &Self::Element) -> Self::Element;
40
41 fn eq_el(&self, lhs: &Self::Element, rhs: &Self::Element) -> bool;
45
46 fn op(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element;
50
51 fn op_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
57 self.op(self.clone_el(lhs), self.clone_el(rhs))
58 }
59
60 fn op_ref_snd(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
66 self.op(lhs, self.clone_el(rhs))
67 }
68
69 fn inv(&self, x: &Self::Element) -> Self::Element;
74
75 fn identity(&self) -> Self::Element;
80
81 fn hash<H: Hasher>(&self, x: &Self::Element, hasher: &mut H);
88
89 fn pow(&self, x: &Self::Element, e: &El<BigIntRing>) -> Self::Element {
94 let res = generic_abs_square_and_multiply(
95 self.clone_el(x),
96 e,
97 BigIntRing::RING,
98 |a| self.op_ref(&a, &a),
99 |a, b| self.op_ref_snd(b, &a),
100 self.identity()
101 );
102 if !BigIntRing::RING.is_neg(e) { res } else { self.inv(&res) }
103 }
104
105 fn is_identity(&self, x: &Self::Element) -> bool {
111 self.eq_el(x, &self.identity())
112 }
113}
114
115#[stability::unstable(feature = "enable")]
119#[allow(type_alias_bounds)]
120pub type GroupEl<G: AbelianGroupStore> = <G::Type as AbelianGroupBase>::Element;
121
122#[macro_export]
126macro_rules! delegate_group {
127 ($base_trait:ty, fn $name:ident (&self, $($pname:ident: $ptype:ty),*) -> $rtype:ty) => {
128 #[doc = concat!(" See [`", stringify!($base_trait), "::", stringify!($name), "()`]")]
129 fn $name (&self, $($pname: $ptype),*) -> $rtype {
130 <Self::Type as $base_trait>::$name(self.get_group(), $($pname),*)
131 }
132 };
133 ($base_trait:ty, fn $name:ident (&self) -> $rtype:ty) => {
134 #[doc = concat!(" See [`", stringify!($base_trait), "::", stringify!($name), "()`]")]
135 fn $name (&self) -> $rtype {
136 <Self::Type as $base_trait>::$name(self.get_group())
137 }
138 };
139}
140
141#[stability::unstable(feature = "enable")]
148pub trait AbelianGroupStore {
149 type Type: AbelianGroupBase;
150
151 fn get_group(&self) -> &Self::Type;
152
153 delegate_group!{ AbelianGroupBase, fn clone_el(&self, el: &GroupEl<Self>) -> GroupEl<Self> }
154 delegate_group!{ AbelianGroupBase, fn eq_el(&self, lhs: &GroupEl<Self>, rhs: &GroupEl<Self>) -> bool }
155 delegate_group!{ AbelianGroupBase, fn op(&self, lhs: GroupEl<Self>, rhs: GroupEl<Self>) -> GroupEl<Self> }
156 delegate_group!{ AbelianGroupBase, fn op_ref(&self, lhs: &GroupEl<Self>, rhs: &GroupEl<Self>) -> GroupEl<Self> }
157 delegate_group!{ AbelianGroupBase, fn op_ref_snd(&self, lhs: GroupEl<Self>, rhs: &GroupEl<Self>) -> GroupEl<Self> }
158 delegate_group!{ AbelianGroupBase, fn inv(&self, x: &GroupEl<Self>) -> GroupEl<Self> }
159 delegate_group!{ AbelianGroupBase, fn identity(&self) -> GroupEl<Self> }
160 delegate_group!{ AbelianGroupBase, fn pow(&self, x: &GroupEl<Self>, e: &El<BigIntRing>) -> GroupEl<Self> }
161 delegate_group!{ AbelianGroupBase, fn is_identity(&self, x: &GroupEl<Self>) -> bool }
162
163 fn hash<H: Hasher>(&self, x: &GroupEl<Self>, hasher: &mut H) {
164 self.get_group().hash(x, hasher)
165 }
166}
167
168impl<G> AbelianGroupStore for G
169 where G: Deref,
170 G::Target: AbelianGroupStore
171{
172 type Type = <G::Target as AbelianGroupStore>::Type;
173
174 fn get_group(&self) -> &Self::Type {
175 (**self).get_group()
176 }
177}
178
179#[stability::unstable(feature = "enable")]
183#[repr(transparent)]
184#[derive(Serialize, Deserialize)]
185pub struct GroupValue<G: AbelianGroupBase> {
186 group: G
187}
188
189impl<G: AbelianGroupBase> From<G> for GroupValue<G> {
190
191 fn from(value: G) -> Self {
192 Self { group: value }
193 }
194}
195
196impl<G: AbelianGroupBase + Sized> GroupValue<G> {
197
198 #[stability::unstable(feature = "enable")]
199 pub fn into(self) -> G {
200 self.group
201 }
202
203 #[stability::unstable(feature = "enable")]
204 pub fn from_ref<'a>(group: &'a G) -> &'a Self {
205 unsafe { std::mem::transmute(group) }
206 }
207}
208
209impl<G: AbelianGroupBase> AbelianGroupStore for GroupValue<G> {
210 type Type = G;
211
212 fn get_group(&self) -> &Self::Type {
213 &self.group
214 }
215}
216
217impl<G: AbelianGroupBase + Clone> Clone for GroupValue<G> {
218 fn clone(&self) -> Self {
219 Self { group: self.group.clone() }
220 }
221}
222
223impl<G: AbelianGroupBase + Copy> Copy for GroupValue<G> {}
224
225#[stability::unstable(feature = "enable")]
238pub struct AddGroupBase<R: RingStore>(pub R);
239
240#[stability::unstable(feature = "enable")]
244#[allow(type_alias_bounds)]
245pub type AddGroup<R: RingStore> = GroupValue<AddGroupBase<R>>;
246
247#[stability::unstable(feature = "enable")]
251#[derive(Serialize, Deserialize)]
252pub struct MultGroupBase<R: RingStore>(R);
253
254#[stability::unstable(feature = "enable")]
258#[allow(type_alias_bounds)]
259pub type MultGroup<R: RingStore> = GroupValue<MultGroupBase<R>>;
260
261#[stability::unstable(feature = "enable")]
265pub struct MultGroupEl<R: RingStore>(El<R>);
266
267impl<R: RingStore> PartialEq for AddGroupBase<R>
268 where R::Type: HashableElRing
269{
270 fn eq(&self, other: &Self) -> bool {
271 self.0.get_ring() == other.0.get_ring()
272 }
273}
274
275impl<R: RingStore> AbelianGroupBase for AddGroupBase<R>
276 where R::Type: HashableElRing
277{
278 type Element = El<R>;
279
280 fn clone_el(&self, x: &Self::Element) -> Self::Element { self.0.clone_el(x) }
281 fn eq_el(&self, lhs: &Self::Element, rhs: &Self::Element) -> bool { self.0.eq_el(lhs, rhs) }
282 fn op(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element { self.0.add(lhs, rhs)}
283 fn inv(&self, x: &Self::Element) -> Self::Element { self.0.negate(self.0.clone_el(x)) }
284 fn identity(&self) -> Self::Element { self.0.zero() }
285 fn hash<H: Hasher>(&self, x: &Self::Element, hasher: &mut H) { self.0.hash(x, hasher) }
286}
287
288impl<R: RingStore> AddGroup<R>
289 where R::Type: HashableElRing
290{
291 #[stability::unstable(feature = "enable")]
292 pub fn new(ring: R) -> Self {
293 Self::from(AddGroupBase(ring))
294 }
295}
296
297impl<R: RingStore + Clone> Clone for AddGroupBase<R>
298 where R::Type: HashableElRing
299{
300 fn clone(&self) -> Self {
301 Self(self.0.clone())
302 }
303}
304
305impl<R: RingStore> PartialEq for MultGroupBase<R>
306 where R::Type: HashableElRing + DivisibilityRing
307{
308 fn eq(&self, other: &Self) -> bool {
309 self.0.get_ring() == other.0.get_ring()
310 }
311}
312
313impl<R: RingStore> AbelianGroupBase for MultGroupBase<R>
314 where R::Type: HashableElRing + DivisibilityRing
315{
316 type Element = MultGroupEl<R>;
317
318 fn clone_el(&self, x: &Self::Element) -> Self::Element { MultGroupEl(self.0.clone_el(&x.0)) }
319 fn eq_el(&self, lhs: &Self::Element, rhs: &Self::Element) -> bool { self.0.eq_el(&lhs.0, &rhs.0) }
320 fn inv(&self, x: &Self::Element) -> Self::Element { MultGroupEl(self.0.invert(&x.0).unwrap()) }
321 fn identity(&self) -> Self::Element { MultGroupEl(self.0.one()) }
322 fn hash<H: Hasher>(&self, x: &Self::Element, hasher: &mut H) { self.0.hash(&x.0, hasher) }
323 fn op(&self, lhs: Self::Element, rhs: Self::Element) -> Self::Element { MultGroupEl(self.0.mul(lhs.0, rhs.0)) }
324}
325
326impl<R: RingStore> SerializableElementGroup for MultGroupBase<R>
327 where R::Type: HashableElRing + DivisibilityRing + SerializableElementRing
328{
329 fn serialize<S>(&self, el: &Self::Element, serializer: S) -> Result<S::Ok, S::Error>
330 where S: Serializer
331 {
332 SerializableNewtypeStruct::new("MultGroupEl", SerializeWithRing::new(&el.0, &self.0)).serialize(serializer)
333 }
334
335 fn deserialize<'de, D>(&self, deserializer: D) -> Result<Self::Element, D::Error>
336 where D: Deserializer<'de>
337 {
338 DeserializeSeedNewtypeStruct::new("MultGroupEl", DeserializeWithRing::new(&self.0)).deserialize(deserializer).map(|x| MultGroupEl(x))
339 }
340}
341
342impl<R: RingStore> Clone for MultGroupBase<R>
343 where R: Clone, R::Type: HashableElRing + DivisibilityRing
344{
345 fn clone(&self) -> Self {
346 Self(self.0.clone())
347 }
348}
349
350impl<R: RingStore> Copy for MultGroupBase<R>
351 where R: Copy, R::Type: HashableElRing + DivisibilityRing
352{}
353
354impl<R: RingStore> Debug for MultGroupBase<R>
355 where R::Type: Debug + HashableElRing + DivisibilityRing
356{
357 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358 write!(f, "({:?})*", self.0.get_ring())
359 }
360}
361
362impl<R: RingStore> Clone for MultGroupEl<R>
363 where R::Type: HashableElRing + DivisibilityRing,
364 El<R>: Clone
365{
366 fn clone(&self) -> Self {
367 Self(self.0.clone())
368 }
369}
370
371impl<R: RingStore> Debug for MultGroupEl<R>
372 where R::Type: HashableElRing + DivisibilityRing,
373 El<R>: Debug
374{
375 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
376 write!(f, "{:?}", self.0)
377 }
378}
379
380impl<R: RingStore> MultGroupBase<R>
381 where R::Type: HashableElRing + DivisibilityRing
382{
383 #[stability::unstable(feature = "enable")]
384 pub fn new(ring: R) -> Self {
385 assert!(ring.is_commutative());
386 return Self(ring);
387 }
388
389 #[stability::unstable(feature = "enable")]
390 pub fn underlying_ring(&self) -> &R {
391 &self.0
392 }
393
394 #[stability::unstable(feature = "enable")]
399 pub fn from_ring_el(&self, x: El<R>) -> Option<MultGroupEl<R>> {
400 if self.0.is_unit(&x) {
401 Some(MultGroupEl(x))
402 } else {
403 None
404 }
405 }
406
407 #[stability::unstable(feature = "enable")]
411 pub fn as_ring_el<'a>(&self, x: &'a MultGroupEl<R>) -> &'a El<R> {
412 &x.0
413 }
414}
415
416impl<R: RingStore> MultGroup<R>
417 where R::Type: HashableElRing + DivisibilityRing
418{
419 #[stability::unstable(feature = "enable")]
420 pub fn new(ring: R) -> Self {
421 Self::from(MultGroupBase::new(ring))
422 }
423
424 #[stability::unstable(feature = "enable")]
425 pub fn underlying_ring(&self) -> &R {
426 self.get_group().underlying_ring()
427 }
428
429 #[stability::unstable(feature = "enable")]
434 pub fn from_ring_el(&self, x: El<R>) -> Option<MultGroupEl<R>> {
435 self.get_group().from_ring_el(x)
436 }
437
438 #[stability::unstable(feature = "enable")]
442 pub fn as_ring_el<'a>(&self, x: &'a MultGroupEl<R>) -> &'a El<R> {
443 self.get_group().as_ring_el(x)
444 }
445}
446
447#[stability::unstable(feature = "enable")]
448pub struct HashableGroupEl<G: AbelianGroupStore> {
449 group: G,
450 el: GroupEl<G>
451}
452
453impl<G: AbelianGroupStore> HashableGroupEl<G> {
454
455 #[stability::unstable(feature = "enable")]
456 pub fn new(group: G, el: GroupEl<G>) -> Self {
457 Self { group, el }
458 }
459}
460
461impl<G: AbelianGroupStore> PartialEq for HashableGroupEl<G> {
462 fn eq(&self, other: &Self) -> bool {
463 self.group.eq_el(&self.el, &other.el)
464 }
465}
466
467impl<G: AbelianGroupStore> Eq for HashableGroupEl<G> {}
468
469impl<G: AbelianGroupStore> Hash for HashableGroupEl<G> {
470 fn hash<H: Hasher>(&self, state: &mut H) {
471 self.group.hash(&self.el, state)
472 }
473}
474
475#[stability::unstable(feature = "enable")]
483pub trait SerializableElementGroup: AbelianGroupBase {
484
485 fn deserialize<'de, D>(&self, deserializer: D) -> Result<Self::Element, D::Error>
489 where D: Deserializer<'de>;
490
491 fn serialize<S>(&self, el: &Self::Element, serializer: S) -> Result<S::Ok, S::Error>
495 where S: Serializer;
496}
497
498#[stability::unstable(feature = "enable")]
503#[derive(Clone)]
504pub struct DeserializeWithGroup<G: AbelianGroupStore>
505 where G::Type: SerializableElementGroup
506{
507 group: G
508}
509
510impl<G> DeserializeWithGroup<G>
511 where G: AbelianGroupStore,
512 G::Type: SerializableElementGroup
513{
514 #[stability::unstable(feature = "enable")]
515 pub fn new(group: G) -> Self {
516 Self { group }
517 }
518}
519
520impl<'de, G> DeserializeSeed<'de> for DeserializeWithGroup<G>
521 where G: AbelianGroupStore,
522 G::Type: SerializableElementGroup
523{
524 type Value = GroupEl<G>;
525
526 fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
527 where D: Deserializer<'de>
528 {
529 self.group.get_group().deserialize(deserializer)
530 }
531}
532
533#[stability::unstable(feature = "enable")]
538pub struct SerializeWithGroup<'a, G: AbelianGroupStore>
539 where G::Type: SerializableElementGroup
540{
541 group: G,
542 el: &'a GroupEl<G>
543}
544
545impl<'a, G: AbelianGroupStore> SerializeWithGroup<'a, G>
546 where G::Type: SerializableElementGroup
547{
548 #[stability::unstable(feature = "enable")]
549 pub fn new(el: &'a GroupEl<G>, group: G) -> Self {
550 Self { el, group }
551 }
552}
553
554impl<'a, G: AbelianGroupStore> Serialize for SerializeWithGroup<'a, G>
555 where G::Type: SerializableElementGroup
556{
557 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
558 where S: Serializer
559 {
560 self.group.get_group().serialize(self.el, serializer)
561 }
562}
563
564#[stability::unstable(feature = "enable")]
569pub struct SerializeOwnedWithGroup<G: AbelianGroupStore>
570 where G::Type: SerializableElementGroup
571{
572 group: G,
573 el: GroupEl<G>
574}
575
576impl<G: AbelianGroupStore> SerializeOwnedWithGroup<G>
577 where G::Type: SerializableElementGroup
578{
579 #[stability::unstable(feature = "enable")]
580 pub fn new(el: GroupEl<G>, group: G) -> Self {
581 Self { el, group }
582 }
583}
584
585impl<G: AbelianGroupStore> Serialize for SerializeOwnedWithGroup<G>
586 where G::Type: SerializableElementGroup
587{
588 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
589 where S: Serializer
590 {
591 self.group.get_group().serialize(&self.el, serializer)
592 }
593}