Crate abstract_integers
source ·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
- Defines a bounded natural integer with regular arithmetic operations, checked for overflow and underflow.
- Defines a bounded natural integer with modular arithmetic operations
Structs
- A big signed integer type.
- A big unsigned integer type.
- YeetExperimentalImplement
FromResidual<Yeet<T>>
on your type to enabledo 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
- GeneratorStateExperimentalThe 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
- CoerceUnsizedExperimentalTrait 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. - FromResidualExperimentalUsed to specify which residuals can be converted into which
crate::ops::Try
types. - GeneratorExperimentalThe 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
implementOneSidedRange
, but..
,d..e
, andf..=g
do not. - ResidualExperimentalAllows retrieving the canonical type implementing
Try
that has this type as its residual and allows it to hold anO
as its output. - TryExperimentalThe
?
operator andtry {}
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
, orf..=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 thougha << b
anda.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 thougha >> b
anda.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
.