diff --git a/Cargo.toml b/Cargo.toml index 8c5c90cb..0e03178f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ segment-tree = "2.0.0" bumpalo = "3.11.1" petgraph = "0.6.2" rand_chacha = "0.3.1" +rational = "1.2.2" # optional: only used to build [[bin]] clap = { version = "4.2.1", features = ["derive"], optional = true } serde_json = { version = "1.0.81", optional = true } diff --git a/src/util/semirings/mod.rs b/src/util/semirings/mod.rs index 1a7d7747..53e5662b 100644 --- a/src/util/semirings/mod.rs +++ b/src/util/semirings/mod.rs @@ -1,6 +1,7 @@ mod boolean; mod expectation; mod finitefield; +mod rational; mod realsemiring; mod semiring_traits; mod tropical; @@ -8,6 +9,7 @@ mod tropical; pub use self::boolean::*; pub use self::expectation::*; pub use self::finitefield::*; +pub use self::rational::*; pub use self::realsemiring::*; pub use self::semiring_traits::*; pub use self::tropical::*; diff --git a/src/util/semirings/rational.rs b/src/util/semirings/rational.rs new file mode 100644 index 00000000..c6a370bf --- /dev/null +++ b/src/util/semirings/rational.rs @@ -0,0 +1,39 @@ +use rational::Rational; +use std::{fmt::Display, ops}; + +use super::semiring_traits::Semiring; + +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] +pub struct RationalSemiring(Rational); + +impl Semiring for RationalSemiring { + fn one() -> Self { + RationalSemiring(Rational::new(1, 1)) + } + + fn zero() -> Self { + RationalSemiring(Rational::new(0, 1)) + } +} + +impl Display for RationalSemiring { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}/{}", self.0.numerator(), self.0.denominator()) + } +} + +impl ops::Add for RationalSemiring { + type Output = RationalSemiring; + + fn add(self, rhs: RationalSemiring) -> Self::Output { + RationalSemiring(self.0 + rhs.0) + } +} + +impl ops::Mul for RationalSemiring { + type Output = RationalSemiring; + + fn mul(self, rhs: RationalSemiring) -> Self::Output { + RationalSemiring(self.0 * rhs.0) + } +}