rustfst/algorithms/encode/
decode_static.rs

1use anyhow::{Context, Result};
2
3use crate::algorithms::{encode::EncodeTable, rm_final_epsilon};
4use crate::algorithms::{FinalTr, MapFinalAction, TrMapper};
5use crate::fst_properties::FstProperties;
6use crate::fst_traits::MutableFst;
7use crate::{Semiring, Tr};
8
9struct DecodeMapper<W: Semiring> {
10    encode_table: EncodeTable<W>,
11}
12
13impl<W: Semiring> DecodeMapper<W> {
14    pub fn new(encode_table: EncodeTable<W>) -> Self {
15        DecodeMapper { encode_table }
16    }
17
18    pub fn encode_weights(&self) -> bool {
19        self.encode_table.0.borrow().encode_type.encode_weights()
20    }
21
22    pub fn encode_labels(&self) -> bool {
23        self.encode_table.0.borrow().encode_type.encode_labels()
24    }
25}
26
27impl<W: Semiring> TrMapper<W> for DecodeMapper<W> {
28    fn tr_map(&self, tr: &mut Tr<W>) -> Result<()> {
29        let tuple = self
30            .encode_table
31            .0
32            .borrow_mut()
33            .decode(tr.ilabel as usize)
34            .ok_or_else(|| format_err!("Can't decode ilabel : {:?}", tr.ilabel))?
35            .clone();
36        tr.ilabel = tuple.ilabel;
37        if self.encode_labels() {
38            tr.olabel = tuple.olabel;
39        }
40        if self.encode_weights() {
41            tr.weight = tuple.weight;
42        }
43        Ok(())
44    }
45
46    fn final_tr_map(&self, _final_tr: &mut FinalTr<W>) -> Result<()> {
47        Ok(())
48    }
49
50    fn final_action(&self) -> MapFinalAction {
51        MapFinalAction::MapNoSuperfinal
52    }
53
54    fn properties(&self, inprops: FstProperties) -> FstProperties {
55        let outprops = inprops;
56        let mut mask = FstProperties::all_properties();
57        if self.encode_labels() {
58            mask &= FstProperties::i_label_invariant_properties()
59                & FstProperties::o_label_invariant_properties();
60        }
61        if self.encode_weights() {
62            mask &= FstProperties::i_label_invariant_properties()
63                & FstProperties::weight_invariant_properties()
64                & FstProperties::rm_super_final_properties()
65        }
66        outprops & mask
67    }
68}
69
70/// The `decode` operation takes as input an encoded FST and the corresponding `EncodeTable` object
71/// and reverts the encoding.
72pub fn decode<W, F>(fst: &mut F, encode_table: EncodeTable<W>) -> Result<()>
73where
74    W: Semiring,
75    F: MutableFst<W>,
76{
77    let mut decode_mapper = DecodeMapper::new(encode_table);
78    fst.tr_map(&mut decode_mapper)
79        .with_context(|| format_err!("Error calling TrMap with EncodeMapper."))?;
80    rm_final_epsilon(fst)?;
81    Ok(())
82}