1use std::fmt::Debug;
2
3use crate::reduce_lift::poly_factor_gcd::IntegerPolyGCDRing;
4use crate::reduce_lift::poly_eval::EvalPolyLocallyRing;
5use crate::divisibility::*;
6use crate::ring::*;
7use crate::homomorphism::*;
8use crate::pid::*;
9use crate::ordered::*;
10
11#[cfg(feature = "mpir")]
18pub type BigIntRing = crate::rings::mpir::MPZ;
19#[cfg(not(feature = "mpir"))]
26pub type BigIntRing = crate::rings::rust_bigint::RustBigintRing;
27#[cfg(feature = "mpir")]
34pub type BigIntRingBase = crate::rings::mpir::MPZBase;
35#[cfg(not(feature = "mpir"))]
42pub type BigIntRingBase = crate::rings::rust_bigint::RustBigintRingBase;
43
44pub trait IntegerRing: Domain + EuclideanRing + OrderedRing + HashableElRing + IntegerPolyGCDRing + EvalPolyLocallyRing + Debug {
59
60 fn to_float_approx(&self, value: &Self::Element) -> f64;
97
98 fn from_float_approx(&self, value: f64) -> Option<Self::Element>;
108
109 fn abs_is_bit_set(&self, value: &Self::Element, i: usize) -> bool;
124
125 fn abs_highest_set_bit(&self, value: &Self::Element) -> Option<usize>;
140
141 fn abs_lowest_set_bit(&self, value: &Self::Element) -> Option<usize>;
157
158 fn euclidean_div_pow_2(&self, value: &mut Self::Element, power: usize);
174
175 fn mul_pow_2(&self, value: &mut Self::Element, power: usize);
179
180 fn get_uniformly_random_bits<G: FnMut() -> u64>(&self, log2_bound_exclusive: usize, rng: G) -> Self::Element;
185
186 fn rounded_div(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
212 let mut rhs_half = self.abs(self.clone_el(rhs));
213 self.euclidean_div_pow_2(&mut rhs_half, 1);
214 if self.is_neg(&lhs) {
215 return self.euclidean_div(self.sub(lhs, rhs_half), rhs);
216 } else {
217 return self.euclidean_div(self.add(lhs, rhs_half), rhs);
218 }
219 }
220
221 fn ceil_div(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
241 assert!(!self.is_zero(rhs));
242 if self.is_zero(&lhs) {
243 return self.zero();
244 }
245 let one = self.one();
246 return match (self.is_pos(&lhs), self.is_pos(rhs)) {
247 (true, true) => self.add(self.euclidean_div(self.sub_ref_snd(lhs, &one), rhs), one),
248 (false, true) => self.euclidean_div(lhs, rhs),
249 (true, false) => self.euclidean_div(lhs, rhs),
250 (false, false) => self.add(self.euclidean_div(self.add_ref_snd(lhs, &one), rhs), one)
251 };
252 }
253
254 fn floor_div(&self, lhs: Self::Element, rhs: &Self::Element) -> Self::Element {
274 self.negate(self.ceil_div(self.negate(lhs), rhs))
275 }
276
277 fn power_of_two(&self, power: usize) -> Self::Element {
281 let mut result = self.one();
282 self.mul_pow_2(&mut result, power);
283 return result;
284 }
285
286 fn representable_bits(&self) -> Option<usize>;
291
292 fn parse(&self, string: &str, base: u32) -> Result<Self::Element, ()> {
301 generic_impls::parse(RingRef::new(self), string, base)
302 }
303}
304
305impl<I, J> CanHomFrom<I> for J
306 where I: ?Sized + IntegerRing, J: ?Sized + IntegerRing
307{
308 type Homomorphism = ();
309
310 fn has_canonical_hom(&self, _: &I) -> Option<Self::Homomorphism> {
311 Some(())
312 }
313
314 fn map_in(&self, from: &I, el: <I as RingBase>::Element, _: &Self::Homomorphism) -> Self::Element {
315 int_cast(el, &RingRef::new(self), &RingRef::new(from))
316 }
317
318 default fn map_in_ref(&self, from: &I, el: &<I as RingBase>::Element, hom: &Self::Homomorphism) -> Self::Element {
319 <J as CanHomFrom<I>>::map_in(self, from, from.clone_el(el), hom)
320 }
321}
322
323impl<I, J> CanIsoFromTo<I> for J
324 where I: ?Sized + IntegerRing, J: ?Sized + IntegerRing
325{
326 type Isomorphism = ();
327
328 fn has_canonical_iso(&self, _: &I) -> Option<Self::Isomorphism> {
329 Some(())
330 }
331
332 fn map_out(&self, from: &I, el: Self::Element, _: &Self::Isomorphism) -> <I as RingBase>::Element {
333 int_cast(el, &RingRef::new(from), &RingRef::new(self))
334 }
335}
336
337pub trait IntCast<F: ?Sized + IntegerRing>: IntegerRing {
356
357 fn cast(&self, from: &F, value: F::Element) -> Self::Element;
364}
365
366impl<F: ?Sized + IntegerRing, T: ?Sized + IntegerRing> IntCast<F> for T {
367
368 default fn cast(&self, from: &F, value: F::Element) -> Self::Element {
369 generic_impls::map_from_integer_ring(RingRef::new(from), RingRef::new(self), value)
370 }
371}
372
373pub fn int_cast<T: RingStore, F: RingStore>(value: El<F>, to: T, from: F) -> El<T>
395 where T::Type: IntegerRing, F::Type: IntegerRing
396{
397 <T::Type as IntCast<F::Type>>::cast(to.get_ring(), from.get_ring(), value)
398}
399
400#[stability::unstable(feature = "enable")]
421pub fn binomial<I>(n: El<I>, k: &El<I>, ring: I) -> El<I>
422 where I: RingStore + Copy,
423 I::Type: IntegerRing
424{
425 if ring.is_neg(&n) {
426 let mut result = binomial(ring.sub(ring.sub_ref_fst(&k, n), ring.one()), k, ring);
427 if !ring.is_even(k) {
428 ring.negate_inplace(&mut result);
429 }
430 return result;
431 } else if ring.is_neg(k) || ring.is_gt(k, &n) {
432 return ring.zero();
433 } else {
434 let n_neg_k = ring.sub_ref(&n, &k);
437 if ring.is_lt(&n_neg_k, k) {
438 return binomial(n, &n_neg_k, ring);
439 }
440 let mut result = ring.one();
441 let mut i = ring.one();
442 while ring.is_leq(&i, &k) {
443 ring.mul_assign(&mut result, ring.sub_ref_snd(ring.add_ref_fst(&n, ring.one()), &i));
444 result = ring.checked_div(&result, &i).unwrap();
445 ring.add_assign(&mut i, ring.one());
446 }
447 return result;
448 }
449}
450
451#[stability::unstable(feature = "enable")]
452pub fn factorial<I>(n: &El<I>, ring: I) -> El<I>
453 where I: RingStore + Copy,
454 I::Type: IntegerRing
455{
456 let mut current = ring.zero();
457 let one = ring.one();
458 return ring.prod((0..).map_while(|_| {
459 if ring.is_lt(¤t, &n) {
460 ring.add_assign_ref(&mut current, &one);
461 return Some(ring.clone_el(¤t));
462 } else {
463 return None;
464 }
465 }));
466}
467
468pub trait IntegerRingStore: RingStore
473 where Self::Type: IntegerRing
474{
475 delegate!{ IntegerRing, fn to_float_approx(&self, value: &El<Self>) -> f64 }
476 delegate!{ IntegerRing, fn from_float_approx(&self, value: f64) -> Option<El<Self>> }
477 delegate!{ IntegerRing, fn abs_is_bit_set(&self, value: &El<Self>, i: usize) -> bool }
478 delegate!{ IntegerRing, fn abs_highest_set_bit(&self, value: &El<Self>) -> Option<usize> }
479 delegate!{ IntegerRing, fn abs_lowest_set_bit(&self, value: &El<Self>) -> Option<usize> }
480 delegate!{ IntegerRing, fn euclidean_div_pow_2(&self, value: &mut El<Self>, power: usize) -> () }
481 delegate!{ IntegerRing, fn mul_pow_2(&self, value: &mut El<Self>, power: usize) -> () }
482 delegate!{ IntegerRing, fn power_of_two(&self, power: usize) -> El<Self> }
483 delegate!{ IntegerRing, fn rounded_div(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> }
484 delegate!{ IntegerRing, fn floor_div(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> }
485 delegate!{ IntegerRing, fn ceil_div(&self, lhs: El<Self>, rhs: &El<Self>) -> El<Self> }
486 delegate!{ IntegerRing, fn parse(&self, string: &str, base: u32) -> Result<El<Self>, ()> }
487
488 fn get_uniformly_random<G: FnMut() -> u64>(&self, bound_exclusive: &El<Self>, mut rng: G) -> El<Self> {
495 assert!(self.is_gt(bound_exclusive, &self.zero()));
496 let log2_ceil_bound = self.abs_highest_set_bit(bound_exclusive).unwrap() + 1;
497 let mut result = self.get_ring().get_uniformly_random_bits(log2_ceil_bound, || rng());
498 while self.is_geq(&result, bound_exclusive) {
499 result = self.get_ring().get_uniformly_random_bits(log2_ceil_bound, || rng());
500 }
501 return result;
502 }
503
504 fn abs_log2_floor(&self, value: &El<Self>) -> Option<usize> {
510 self.abs_highest_set_bit(value)
511 }
512
513 fn abs_log2_ceil(&self, value: &El<Self>) -> Option<usize> {
517 let highest_bit = self.abs_highest_set_bit(value)?;
518 if self.abs_lowest_set_bit(value).unwrap() == highest_bit {
519 return Some(highest_bit);
520 } else {
521 return Some(highest_bit + 1);
522 }
523 }
524
525 fn is_even(&self, value: &El<Self>) -> bool {
529 !self.abs_is_bit_set(value, 0)
530 }
531
532 fn is_odd(&self, value: &El<Self>) -> bool {
536 !self.is_even(value)
537 }
538
539 fn half_exact(&self, mut value: El<Self>) -> El<Self> {
543 assert!(self.is_even(&value));
544 self.euclidean_div_pow_2(&mut value, 1);
545 return value;
546 }
547}
548
549impl<R> IntegerRingStore for R
550 where R: RingStore,
551 R::Type: IntegerRing
552{}
553
554pub mod generic_impls {
560 use crate::ring::*;
561 use crate::primitive_int::*;
562 use super::*;
563
564 #[stability::unstable(feature = "enable")]
565 pub fn map_from_integer_ring<I, R>(from: I, to: R, mut x: El<I>) -> El<R>
566 where I: RingStore,
567 I::Type: IntegerRing,
568 R: RingStore
569 {
570 let basis = to.int_hom().map(1 << 16);
571 let is_neg = if from.is_neg(&x) {
572 from.negate_inplace(&mut x);
573 true
574 } else {
575 false
576 };
577 let mut current = to.zero();
578 let mut current_pow = to.one();
579 while !from.is_zero(&x) {
580 let mut quo = from.clone_el(&x);
581 from.euclidean_div_pow_2(&mut quo, 16);
582 let mut rem = from.clone_el(&quo);
583 from.mul_pow_2(&mut rem, 16);
584 from.sub_self_assign(&mut rem, x);
585 let rem = int_cast(rem, StaticRing::<i32>::RING, &from);
586 to.add_assign(&mut current, to.mul_ref_snd(to.int_hom().map(rem), ¤t_pow));
587 x = quo;
588 to.mul_assign_ref(&mut current_pow, &basis);
589 }
590 if is_neg {
591 return to.negate(current);
592 } else {
593 return current;
594 }
595 }
596
597 #[stability::unstable(feature = "enable")]
598 pub fn parse<I>(ring: I, string: &str, base: u32) -> Result<El<I>, ()>
599 where I: RingStore, I::Type: IntegerRing
600 {
601 let (negative, rest) = if string.chars().next() == Some('-') {
602 (true, string.split_at(1).1)
603 } else if string.chars().next() == Some('+') {
604 (false, string.split_at(1).1)
605 } else {
606 (false, string)
607 };
608 assert!(base >= 2);
609
610 let bits_per_chunk = u32::BITS as usize;
611 assert!(bits_per_chunk <= i64::BITS as usize - 2);
612 let chunk_size = (bits_per_chunk as f32 / (base as f32).log2()).floor() as usize;
613 let it = <str as AsRef<[u8]>>::as_ref(rest)
614 .rchunks(chunk_size)
615 .rev()
616 .map(std::str::from_utf8)
617 .map(|chunk| chunk.map_err(|_| ()))
618 .map(|chunk| chunk.and_then(|n|
619 u64::from_str_radix(n, base).map_err(|_| ()))
620 );
621 let chunk_base = ring.pow(int_cast(base as i64, &ring, StaticRing::<i64>::RING), chunk_size);
622 let result = it.fold(Ok(ring.zero()), |current, next| {
623 current.and_then(|mut current| next.map(|next| {
624 ring.mul_assign_ref(&mut current, &chunk_base);
625 ring.add(current, int_cast(next as i64, &ring, StaticRing::<i64>::RING))
626 }))
627 });
628 if negative {
629 return result.map(|result| ring.negate(result));
630 } else {
631 return result;
632 }
633 }
634}
635
636#[cfg(test)]
637use crate::primitive_int::*;
638#[cfg(test)]
639use generic_impls::map_from_integer_ring;
640
641#[allow(missing_docs)]
642#[cfg(any(test, feature = "generic_tests"))]
643pub mod generic_tests {
644
645 use crate::ring::El;
646 use super::*;
647
648 pub fn test_integer_get_uniformly_random<R: RingStore>(ring: R)
649 where R::Type: IntegerRing
650 {
651 for b in [15, 16] {
652 let bound = ring.int_hom().map(b);
653 let mut rng = oorandom::Rand64::new(1);
654 let elements: Vec<El<R>> = (0..1000).map(|_| ring.get_uniformly_random(&bound, || rng.rand_u64())).collect();
655 for i in 0..b {
656 assert!(elements.iter().any(|x| ring.eq_el(x, &ring.int_hom().map(i))))
657 }
658 for x in &elements {
659 assert!(ring.is_lt(x, &bound));
660 }
661 }
662 }
663
664 pub fn test_integer_axioms<R: IntegerRingStore, I: Iterator<Item = El<R>>>(ring: R, edge_case_elements: I)
665 where R::Type: IntegerRing
666 {
667 let elements = edge_case_elements.collect::<Vec<_>>();
668
669 assert_eq!(None, ring.abs_highest_set_bit(&ring.int_hom().map(0)));
671 assert_eq!(Some(0), ring.abs_highest_set_bit(&ring.int_hom().map(1)));
672 assert_eq!(Some(1), ring.abs_highest_set_bit(&ring.int_hom().map(2)));
673
674 for a in &elements {
676 let mut ceil_pow_2 = ring.int_hom().map(2);
677 ring.mul_pow_2(&mut ceil_pow_2, ring.abs_highest_set_bit(a).unwrap_or(0));
678 assert!(ring.is_lt(a, &ceil_pow_2));
679 assert!(ring.is_lt(&ring.negate(ring.clone_el(a)), &ceil_pow_2));
680
681 for i in 0..ring.abs_highest_set_bit(a).unwrap_or(0) {
682 let mut pow_2 = ring.one();
683 ring.mul_pow_2(&mut pow_2, i);
684 let mut b = ring.clone_el(a);
685 ring.mul_pow_2(&mut b, i);
686 assert_el_eq!(ring, b, ring.mul(ring.clone_el(a), ring.clone_el(&pow_2)));
687 ring.euclidean_div_pow_2(&mut b, i);
688 assert_el_eq!(ring, b, a);
689 ring.euclidean_div_pow_2(&mut b, i);
690 assert_el_eq!(ring, b, ring.euclidean_div(ring.clone_el(a), &pow_2));
691 }
692 }
693
694 let d = ring.int_hom().map(8);
696 for k in -10..=10 {
697 let mut a = ring.int_hom().map(k);
698 assert_el_eq!(ring, ring.int_hom().map(k / 8), ring.euclidean_div(ring.clone_el(&a), &d));
699 ring.euclidean_div_pow_2(&mut a, 3);
700 assert_el_eq!(ring, ring.int_hom().map(k / 8), a);
701 }
702 let d = ring.int_hom().map(-8);
703 for k in -10..=10 {
704 let a = ring.int_hom().map(k);
705 assert_el_eq!(ring, ring.int_hom().map(k / -8), ring.euclidean_div(ring.clone_el(&a), &d));
706 }
707
708 assert_el_eq!(ring, ring.int_hom().map(2), ring.rounded_div(ring.int_hom().map(7), &ring.int_hom().map(3)));
710 assert_el_eq!(ring, ring.int_hom().map(-2), ring.rounded_div(ring.int_hom().map(-7), &ring.int_hom().map(3)));
711 assert_el_eq!(ring, ring.int_hom().map(-2), ring.rounded_div(ring.int_hom().map(7), &ring.int_hom().map(-3)));
712 assert_el_eq!(ring, ring.int_hom().map(2), ring.rounded_div(ring.int_hom().map(-7), &ring.int_hom().map(-3)));
713
714 assert_el_eq!(ring, ring.int_hom().map(3), ring.rounded_div(ring.int_hom().map(8), &ring.int_hom().map(3)));
715 assert_el_eq!(ring, ring.int_hom().map(-3), ring.rounded_div(ring.int_hom().map(-8), &ring.int_hom().map(3)));
716 assert_el_eq!(ring, ring.int_hom().map(-3), ring.rounded_div(ring.int_hom().map(8), &ring.int_hom().map(-3)));
717 assert_el_eq!(ring, ring.int_hom().map(3), ring.rounded_div(ring.int_hom().map(-8), &ring.int_hom().map(-3)));
718
719 assert_el_eq!(ring, ring.int_hom().map(4), ring.rounded_div(ring.int_hom().map(7), &ring.int_hom().map(2)));
720 assert_el_eq!(ring, ring.int_hom().map(-4), ring.rounded_div(ring.int_hom().map(-7), &ring.int_hom().map(2)));
721 assert_el_eq!(ring, ring.int_hom().map(-4), ring.rounded_div(ring.int_hom().map(7), &ring.int_hom().map(-2)));
722 assert_el_eq!(ring, ring.int_hom().map(4), ring.rounded_div(ring.int_hom().map(-7), &ring.int_hom().map(-2)));
723 }
724}
725
726#[test]
727fn test_int_div_assumption() {
728 assert_eq!(-1, -10 / 8);
729 assert_eq!(-1, 10 / -8);
730 assert_eq!(1, 10 / 8);
731 assert_eq!(1, -10 / -8);
732}
733
734#[test]
735fn test_rounded_div() {
736 let ZZ = StaticRing::<i32>::RING;
737 assert_el_eq!(ZZ, 3, ZZ.rounded_div(20, &7));
738 assert_el_eq!(ZZ, -3, ZZ.rounded_div(-20, &7));
739 assert_el_eq!(ZZ, -3, ZZ.rounded_div(20, &-7));
740 assert_el_eq!(ZZ, 3, ZZ.rounded_div(-20, &-7));
741 assert_el_eq!(ZZ, 3, ZZ.rounded_div(22, &7));
742 assert_el_eq!(ZZ, -3, ZZ.rounded_div(-22, &7));
743 assert_el_eq!(ZZ, -3, ZZ.rounded_div(22, &-7));
744 assert_el_eq!(ZZ, 3, ZZ.rounded_div(-22, &-7));
745}
746
747#[test]
748fn test_binomial() {
749 let ZZ = StaticRing::<i32>::RING;
750 assert_eq!(0, binomial(-4, &-1, ZZ));
751 assert_eq!(1, binomial(-4, &0, ZZ));
752 assert_eq!(-4, binomial(-4, &1, ZZ));
753 assert_eq!(10, binomial(-4, &2, ZZ));
754 assert_eq!(-20, binomial(-4, &3, ZZ));
755 assert_eq!(35, binomial(-4, &4, ZZ));
756 assert_eq!(-56, binomial(-4, &5, ZZ));
757
758 assert_eq!(0, binomial(3, &-1, ZZ));
759 assert_eq!(1, binomial(3, &0, ZZ));
760 assert_eq!(3, binomial(3, &1, ZZ));
761 assert_eq!(3, binomial(3, &2, ZZ));
762 assert_eq!(1, binomial(3, &3, ZZ));
763 assert_eq!(0, binomial(3, &4, ZZ));
764
765 assert_eq!(0, binomial(8, &-1, ZZ));
766 assert_eq!(1, binomial(8, &0, ZZ));
767 assert_eq!(8, binomial(8, &1, ZZ));
768 assert_eq!(28, binomial(8, &2, ZZ));
769 assert_eq!(56, binomial(8, &3, ZZ));
770 assert_eq!(70, binomial(8, &4, ZZ));
771
772 assert_eq!(145422675, binomial(30, &14, ZZ));
774}
775
776#[test]
777fn test_factorial() {
778 let ZZ = StaticRing::<i32>::RING;
779 assert_eq!(1, factorial(&0, ZZ));
780 assert_eq!(1, factorial(&1, ZZ));
781 assert_eq!(2, factorial(&2, ZZ));
782 assert_eq!(6, factorial(&3, ZZ));
783 assert_eq!(24, factorial(&4, ZZ));
784}
785
786#[test]
787fn test_ceil_floor_div() {
788 let ZZ = StaticRing::<i32>::RING;
789 for rhs in [-10, -3, -2, -1, 1, 2, 3, 10] {
790 for lhs in [-10, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 10] {
791 let result = ZZ.ceil_div(lhs, &rhs);
792 assert_eq!(i32::div_ceil(lhs, rhs), result);
793 assert_eq!((lhs as f64 / rhs as f64).ceil() as i32, result);
794
795 let result = ZZ.floor_div(lhs, &rhs);
796 assert_eq!(i32::div_floor(lhs, rhs), result);
797 assert_eq!((lhs as f64 / rhs as f64).floor() as i32, result);
798 }
799 }
800}
801
802#[test]
803fn test_parse() {
804 let ZZbig = BigIntRing::RING;
805 assert_el_eq!(&ZZbig, &ZZbig.int_hom().map(3), ZZbig.parse("3", 10).unwrap());
806 assert_el_eq!(&ZZbig, &ZZbig.power_of_two(100), ZZbig.parse("1267650600228229401496703205376", 10).unwrap());
807 assert_el_eq!(&ZZbig, &ZZbig.power_of_two(100), ZZbig.parse("+1267650600228229401496703205376", 10).unwrap());
808 assert_el_eq!(&ZZbig, &ZZbig.negate(ZZbig.power_of_two(100)), ZZbig.parse("-1267650600228229401496703205376", 10).unwrap());
809 assert_el_eq!(&ZZbig, &ZZbig.mul(ZZbig.pow(ZZbig.int_hom().map(11), 26), ZZbig.int_hom().map(10)), ZZbig.parse("a00000000000000000000000000", 11).unwrap());
810 assert!(ZZbig.parse("238597a", 10).is_err());
811}
812
813#[test]
814fn test_map_from_integer() {
815 let ZZbig = BigIntRing::RING;
816 assert_el_eq!(&ZZbig, ZZbig.parse("0", 10).unwrap(), map_from_integer_ring(ZZbig, ZZbig, ZZbig.parse("0", 10).unwrap()));
817 assert_el_eq!(&ZZbig, ZZbig.parse("-1", 10).unwrap(), map_from_integer_ring(ZZbig, ZZbig, ZZbig.parse("-1", 10).unwrap()));
818 assert_el_eq!(&ZZbig, ZZbig.parse("80934517340527398320561", 10).unwrap(), map_from_integer_ring(ZZbig, ZZbig, ZZbig.parse("80934517340527398320561", 10).unwrap()));
819 assert_el_eq!(&ZZbig, ZZbig.parse("-4861235897136598713465987138952643", 10).unwrap(), map_from_integer_ring(ZZbig, ZZbig, ZZbig.parse("-4861235897136598713465987138952643", 10).unwrap()));
820}