rustfst/algorithms/compose/compose_filters/
null_compose_filter.rs

1use std::borrow::Borrow;
2use std::fmt::Debug;
3use std::marker::PhantomData;
4use std::sync::Arc;
5
6use anyhow::Result;
7
8use crate::algorithms::compose::compose_filters::{ComposeFilter, ComposeFilterBuilder};
9use crate::algorithms::compose::filter_states::{FilterState, TrivialFilterState};
10use crate::algorithms::compose::matchers::{MatchType, Matcher};
11use crate::fst_properties::FstProperties;
12use crate::fst_traits::Fst;
13use crate::semirings::Semiring;
14use crate::{StateId, Tr, NO_LABEL};
15
16#[derive(Debug, Clone)]
17pub struct NullComposeFilter<W, F1, F2, B1, B2, M1, M2>
18where
19    W: Semiring,
20    F1: Fst<W>,
21    F2: Fst<W>,
22    B1: Borrow<F1> + Debug,
23    B2: Borrow<F2> + Debug,
24    M1: Matcher<W, F1, B1>,
25    M2: Matcher<W, F2, B2>,
26{
27    matcher1: Arc<M1>,
28    matcher2: Arc<M2>,
29    ghost: PhantomData<(W, F1, F2, B1, B2)>,
30}
31
32#[derive(Debug)]
33pub struct NullComposeFilterBuilder<W, F1, F2, B1, B2, M1, M2>
34where
35    W: Semiring,
36    F1: Fst<W>,
37    F2: Fst<W>,
38    B1: Borrow<F1> + Debug,
39    B2: Borrow<F2> + Debug,
40    M1: Matcher<W, F1, B1>,
41    M2: Matcher<W, F2, B2>,
42{
43    matcher1: Arc<M1>,
44    matcher2: Arc<M2>,
45    ghost: PhantomData<(W, F1, F2, B1, B2)>,
46}
47
48impl<W, F1, F2, B1, B2, M1, M2> Clone for NullComposeFilterBuilder<W, F1, F2, B1, B2, M1, M2>
49where
50    W: Semiring,
51    F1: Fst<W>,
52    F2: Fst<W>,
53    B1: Borrow<F1> + Debug,
54    B2: Borrow<F2> + Debug,
55    M1: Matcher<W, F1, B1>,
56    M2: Matcher<W, F2, B2>,
57{
58    fn clone(&self) -> Self {
59        NullComposeFilterBuilder {
60            matcher1: self.matcher1.clone(),
61            matcher2: self.matcher2.clone(),
62            ghost: PhantomData,
63        }
64    }
65}
66
67impl<W: Semiring, F1, F2, B1, B2, M1, M2> ComposeFilterBuilder<W, F1, F2, B1, B2, M1, M2>
68    for NullComposeFilterBuilder<W, F1, F2, B1, B2, M1, M2>
69where
70    W: Semiring,
71    F1: Fst<W>,
72    F2: Fst<W>,
73    B1: Borrow<F1> + Debug,
74    B2: Borrow<F2> + Debug,
75    M1: Matcher<W, F1, B1>,
76    M2: Matcher<W, F2, B2>,
77{
78    type IM1 = M1;
79    type IM2 = M2;
80    type CF = NullComposeFilter<W, F1, F2, B1, B2, M1, M2>;
81
82    fn new(fst1: B1, fst2: B2, matcher1: Option<M1>, matcher2: Option<M2>) -> Result<Self> {
83        let matcher1 = matcher1.unwrap_or_else(|| M1::new(fst1, MatchType::MatchOutput).unwrap());
84        let matcher2 = matcher2.unwrap_or_else(|| M2::new(fst2, MatchType::MatchInput).unwrap());
85        Ok(Self {
86            matcher1: Arc::new(matcher1),
87            matcher2: Arc::new(matcher2),
88            ghost: PhantomData,
89        })
90    }
91
92    fn build(&self) -> Result<Self::CF> {
93        Ok(NullComposeFilter::<W, F1, F2, B1, B2, M1, M2> {
94            matcher1: Arc::clone(&self.matcher1),
95            matcher2: Arc::clone(&self.matcher2),
96            ghost: PhantomData,
97        })
98    }
99}
100
101impl<W, F1, F2, B1, B2, M1, M2> ComposeFilter<W, F1, F2, B1, B2, M1, M2>
102    for NullComposeFilter<W, F1, F2, B1, B2, M1, M2>
103where
104    W: Semiring,
105    F1: Fst<W>,
106    F2: Fst<W>,
107    B1: Borrow<F1> + Debug,
108    B2: Borrow<F2> + Debug,
109    M1: Matcher<W, F1, B1>,
110    M2: Matcher<W, F2, B2>,
111{
112    type FS = TrivialFilterState;
113
114    fn start(&self) -> Self::FS {
115        Self::FS::new(true)
116    }
117
118    fn set_state(&mut self, _s1: StateId, _s2: StateId, _filter_state: &Self::FS) -> Result<()> {
119        Ok(())
120    }
121
122    fn filter_tr(&mut self, arc1: &mut Tr<W>, arc2: &mut Tr<W>) -> Result<Self::FS> {
123        let res = if arc1.olabel == NO_LABEL || arc2.ilabel == NO_LABEL {
124            Self::FS::new_no_state()
125        } else {
126            Self::FS::new(true)
127        };
128        Ok(res)
129    }
130
131    fn filter_final(&self, _w1: &mut W, _w2: &mut W) -> Result<()> {
132        Ok(())
133    }
134
135    fn matcher1(&self) -> &M1 {
136        &self.matcher1
137    }
138
139    fn matcher2(&self) -> &M2 {
140        &self.matcher2
141    }
142
143    fn matcher1_shared(&self) -> &Arc<M1> {
144        &self.matcher1
145    }
146
147    fn matcher2_shared(&self) -> &Arc<M2> {
148        &self.matcher2
149    }
150
151    fn properties(&self, inprops: FstProperties) -> FstProperties {
152        inprops
153    }
154}