Expand description

This crate defines specification-friendly natural integers with an upper bound. Operations on these integers can be defined as modular (modulo the upper bound) or regular (with a panic on underflow or overflow).

As each integer gets its own Rust type, the compiler detects and prevent any mixing between all the diffent integers you would have defined.

Defining a new integer type

Here is the macro used to defined the SizeNatExample type of this crate:

define_abstract_integer_checked!(SizeNatExample, 64);

SizeNat is the name of the newly-created type. 64 is the number of bits of the machine representation of the type. From the number of bits is derived an upper bound for the integer for which all operations are checked for overflow.

The resulting integer type is copyable, and supports addition, substraction, multiplication, integer division, remainder, comparison and equality. The from_literal method allows you to convert integer literals into your new type.

Refining an integer type for modular arithmetic

On top of a previously defined abstract integer, you can define another type that lets you implement modular arithmetic. For instance, this crate defines the arithmetic field over the 9th Mersenne prime with:

define_refined_modular_integer!(
   SizeNatFieldExample,
   SizeNatExample,
   SizeNatExample::pow2(61) - SizeNatExample::from_literal(1)
);

The first argument of this new macro is the name of the newly defined refined type. The second argument is the name of the base abstract integer that will act as the representation. The third example is the modulo for all operations, defined as a value of the base type.

Example

use abstract_integers::*;

abstract_public_nat_mod!(SizeNatFieldExample, SizeNatExample, 64, "1fffffffffffffff");

let x1 = SizeNatExample::from_literal(687165654266415);
let x2 = SizeNatExample::from_literal(4298832000156);
let x3 = x1 + x2;
assert_eq!(SizeNatExample::from_literal(691464486266571), x3);
let x4 = SizeNatExample::from_literal(8151084996540);
let x5 = x3 - x4;
assert_eq!(SizeNatExample::from_literal(683313401270031), x5.into());
let x6 = x5 / SizeNatExample::from_literal(1541654268);
assert_eq!(SizeNatExample::from_literal(443233), x6.into());
let x7 : SizeNatFieldExample = SizeNatFieldExample::from_literal(2305843009213693951) + x6.into();
assert_eq!(x7, x6.into());

Modules

Macros

Structs

  • A big signed integer type.
  • A big unsigned integer type.
  • YeetExperimental
    Implement FromResidual<Yeet<T>> on your type to enable do yeet expr syntax in functions returning your type.
  • An error which can be returned when parsing an integer.
  • A (half-open) range bounded inclusively below and exclusively above (start..end).
  • A range only bounded inclusively below (start..).
  • An unbounded range (..).
  • A range bounded inclusively below and above (start..=end).
  • A range only bounded exclusively above (..end).
  • A range only bounded inclusively above (..=end).

Enums

  • GeneratorStateExperimental
    The result of a generator resumption.
  • An endpoint of a range of keys.
  • Used to tell an operation whether it should exit early or go on as usual.
  • An Ordering is the result of a comparison between two values.
  • A Sign is a BigInt’s composing element.

Traits

  • CoerceUnsizedExperimental
    Trait that indicates that this is a pointer or a wrapper for one, where unsizing can be performed on the pointee.
  • DispatchFromDynExperimental
    DispatchFromDyn is used in the implementation of object safety checks (specifically allowing arbitrary self types), to guarantee that a method’s receiver type can be dispatched on.
  • FromResidualExperimental
    Used to specify which residuals can be converted into which crate::ops::Try types.
  • GeneratorExperimental
    The trait implemented by builtin generator types.
  • Defines a multiplicative identity element for Self.
  • OneSidedRangeExperimental
    OneSidedRange is implemented for built-in range types that are unbounded on one side. For example, a.., ..b and ..=c implement OneSidedRange, but .., d..e, and f..=g do not.
  • ResidualExperimental
    Allows retrieving the canonical type implementing Try that has this type as its residual and allows it to hold an O as its output.
  • TryExperimental
    The ? operator and try {} blocks.
  • The addition operator +.
  • The addition assignment operator +=.
  • The bitwise AND operator &.
  • The bitwise AND assignment operator &=.
  • The bitwise OR operator |.
  • The bitwise OR assignment operator |=.
  • The bitwise XOR operator ^.
  • The bitwise XOR assignment operator ^=.
  • Performs subtraction that returns None instead of wrapping around on underflow.
  • Used for immutable dereferencing operations, like *v.
  • Used for mutable dereferencing operations, like in *v = 1;.
  • The division operator /.
  • The division assignment operator /=.
  • Custom code within the destructor.
  • The version of the call operator that takes an immutable receiver.
  • The version of the call operator that takes a mutable receiver.
  • The version of the call operator that takes a by-value receiver.
  • Used for indexing operations (container[index]) in immutable contexts.
  • Used for indexing operations (container[index]) in mutable contexts.
  • The multiplication operator *.
  • The multiplication assignment operator *=.
  • The unary negation operator -.
  • The unary logical negation operator !.
  • RangeBounds is implemented by Rust’s built-in range types, produced by range syntax like .., a.., ..b, ..=c, d..e, or f..=g.
  • The remainder operator %.
  • The remainder assignment operator %=.
  • The left shift operator <<. Note that because this trait is implemented for all integer types with multiple right-hand-side types, Rust’s type checker has special handling for _ << _, setting the result type for integer operations to the type of the left-hand-side operand. This means that though a << b and a.shl(b) are one and the same from an evaluation standpoint, they are different when it comes to type inference.
  • The left shift assignment operator <<=.
  • The right shift operator >>. Note that because this trait is implemented for all integer types with multiple right-hand-side types, Rust’s type checker has special handling for _ >> _, setting the result type for integer operations to the type of the left-hand-side operand. This means that though a >> b and a.shr(b) are one and the same from an evaluation standpoint, they are different when it comes to type inference.
  • The right shift assignment operator >>=.
  • The subtraction operator -.
  • The subtraction assignment operator -=.
  • Defines an additive identity element for Self.

Functions

  • Returns the multiplicative identity, 1.
  • Returns the additive identity, 0.