Skip to main content

rustfst/semirings/
integer_weight.rs

1use nom::character::complete::i32;
2use std::{borrow::Borrow, io::Write};
3
4use anyhow::Result;
5use nom::IResult;
6
7use crate::{
8    parsers::{parse_bin_i32, write_bin_i32},
9    semirings::{CompleteSemiring, ReverseBack, Semiring, SemiringProperties, StarSemiring},
10    NomCustomError,
11};
12
13use super::SerializableSemiring;
14
15/// Probability semiring: (x, +, 0.0, 1.0).
16#[derive(Clone, Debug, PartialEq, PartialOrd, Default, Hash, Eq, Copy)]
17pub struct IntegerWeight {
18    value: i32,
19}
20
21impl Semiring for IntegerWeight {
22    type Type = i32;
23    type ReverseWeight = IntegerWeight;
24
25    fn zero() -> Self {
26        Self { value: 0 }
27    }
28    fn one() -> Self {
29        Self { value: 1 }
30    }
31
32    fn new(value: <Self as Semiring>::Type) -> Self {
33        IntegerWeight { value }
34    }
35
36    fn plus_assign<P: Borrow<Self>>(&mut self, rhs: P) -> Result<()> {
37        self.value += rhs.borrow().value;
38        Ok(())
39    }
40
41    fn times_assign<P: Borrow<Self>>(&mut self, rhs: P) -> Result<()> {
42        self.value *= rhs.borrow().value;
43        Ok(())
44    }
45
46    fn approx_equal<P: Borrow<Self>>(&self, rhs: P, _delta: f32) -> bool {
47        self.value == rhs.borrow().value
48    }
49
50    fn value(&self) -> &Self::Type {
51        &self.value
52    }
53
54    fn take_value(self) -> Self::Type {
55        self.value
56    }
57
58    fn set_value(&mut self, value: <Self as Semiring>::Type) {
59        self.value = value
60    }
61
62    fn reverse(&self) -> Result<Self::ReverseWeight> {
63        Ok(*self)
64    }
65
66    fn properties() -> SemiringProperties {
67        SemiringProperties::LEFT_SEMIRING
68            | SemiringProperties::RIGHT_SEMIRING
69            | SemiringProperties::COMMUTATIVE
70    }
71}
72
73impl ReverseBack<IntegerWeight> for IntegerWeight {
74    fn reverse_back(&self) -> Result<IntegerWeight> {
75        Ok(*self)
76    }
77}
78
79impl AsRef<IntegerWeight> for IntegerWeight {
80    fn as_ref(&self) -> &IntegerWeight {
81        self
82    }
83}
84
85display_semiring!(IntegerWeight);
86
87impl CompleteSemiring for IntegerWeight {}
88
89impl StarSemiring for IntegerWeight {
90    fn closure(&self) -> Self {
91        if self.value == 0 {
92            return Self::new(1);
93        }
94        Self::new(i32::MAX)
95    }
96}
97
98impl From<i32> for IntegerWeight {
99    fn from(i: i32) -> Self {
100        Self::new(i)
101    }
102}
103
104impl SerializableSemiring for IntegerWeight {
105    fn weight_type() -> String {
106        "integer".to_string()
107    }
108
109    fn parse_binary(i: &[u8]) -> IResult<&[u8], Self, NomCustomError<&[u8]>> {
110        let (i, weight) = parse_bin_i32(i)?;
111        Ok((i, Self::new(weight)))
112    }
113
114    fn write_binary<F: Write>(&self, file: &mut F) -> Result<()> {
115        write_bin_i32(file, *self.value())
116    }
117
118    fn parse_text(i: &str) -> IResult<&str, Self> {
119        let (i, f) = i32(i)?;
120        Ok((i, Self::new(f)))
121    }
122}
123
124test_semiring_serializable!(
125    tests_integer_weight_serializable,
126    IntegerWeight,
127    IntegerWeight::one() IntegerWeight::zero() IntegerWeight::new(3) IntegerWeight::new(5) IntegerWeight::new(10) IntegerWeight::new(100)
128);