1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use crate::fst_properties::FstProperties;
use crate::fst_traits::MutableFst;
use crate::semirings::Semiring;
pub fn tr_sum<W: Semiring, F: MutableFst<W>>(ifst: &mut F) {
let props = ifst.properties();
unsafe {
for s in 0..ifst.num_states() {
ifst.sum_trs_unchecked(s);
}
}
let mut outprops = props
& FstProperties::arcsort_properties()
& FstProperties::delete_arcs_properties()
& FstProperties::weight_invariant_properties();
if ifst.num_states() == 0 {
outprops |= FstProperties::null_properties();
}
ifst.set_properties_with_mask(outprops, FstProperties::all_properties());
}
#[cfg(test)]
mod test {
use crate::fst_impls::VectorFst;
use crate::fst_traits::MutableFst;
use crate::semirings::{ProbabilityWeight, Semiring};
use crate::Tr;
use anyhow::Result;
use super::*;
#[test]
fn test_tr_map_sum() -> Result<()> {
let mut fst_in = VectorFst::<ProbabilityWeight>::new();
let s1 = fst_in.add_state();
let s2 = fst_in.add_state();
fst_in.add_tr(s1, Tr::new(0, 0, ProbabilityWeight::new(0.3), s2))?;
fst_in.add_tr(s1, Tr::new(0, 1, ProbabilityWeight::new(0.3), s2))?;
fst_in.add_tr(s1, Tr::new(1, 0, ProbabilityWeight::new(0.3), s2))?;
fst_in.add_tr(s1, Tr::new(0, 0, ProbabilityWeight::new(0.3), s2))?;
fst_in.add_tr(s1, Tr::new(0, 0, ProbabilityWeight::new(0.1), s2))?;
fst_in.set_start(s1)?;
fst_in.set_final(s2, ProbabilityWeight::one())?;
let mut fst_out = VectorFst::<ProbabilityWeight>::new();
let s1 = fst_out.add_state();
let s2 = fst_out.add_state();
fst_out.add_tr(s1, Tr::new(0, 0, ProbabilityWeight::new(0.7), s2))?;
fst_out.add_tr(s1, Tr::new(0, 1, ProbabilityWeight::new(0.3), s2))?;
fst_out.add_tr(s1, Tr::new(1, 0, ProbabilityWeight::new(0.3), s2))?;
fst_out.set_start(s1)?;
fst_out.set_final(s2, ProbabilityWeight::one())?;
tr_sum(&mut fst_in);
assert_eq!(fst_in, fst_out);
Ok(())
}
}