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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
use std::marker::PhantomData; use std::sync::Arc; use anyhow::Result; use crate::algorithms::compose::compose_filters::{ComposeFilter, ComposeFilterBuilder}; use crate::algorithms::compose::filter_states::{FilterState, TrivialFilterState}; use crate::algorithms::compose::matchers::{MatchType, Matcher}; use crate::fst_properties::FstProperties; use crate::semirings::Semiring; use crate::{Tr, EPS_LABEL}; #[derive(Debug, Clone)] pub struct NoMatchComposeFilter<W: Semiring, M1: Matcher<W>, M2: Matcher<W>> { matcher1: Arc<M1>, matcher2: Arc<M2>, w: PhantomData<W>, } #[derive(Debug, Clone)] pub struct NoMatchComposeFilterBuilder<W: Semiring, M1: Matcher<W>, M2: Matcher<W>> { matcher1: Arc<M1>, matcher2: Arc<M2>, w: PhantomData<W>, } impl<W: Semiring, M1: Matcher<W>, M2: Matcher<W>> ComposeFilterBuilder<W> for NoMatchComposeFilterBuilder<W, M1, M2> { type CF = NoMatchComposeFilter<W, M1, M2>; type M1 = M1; type M2 = M2; fn new( fst1: Arc<M1::F>, fst2: Arc<M2::F>, matcher1: Option<M1>, matcher2: Option<M2>, ) -> Result<Self> { let matcher1 = matcher1.unwrap_or_else(|| M1::new(Arc::clone(&fst1), MatchType::MatchOutput).unwrap()); let matcher2 = matcher2.unwrap_or_else(|| M2::new(Arc::clone(&fst2), MatchType::MatchInput).unwrap()); Ok(Self { matcher1: Arc::new(matcher1), matcher2: Arc::new(matcher2), w: PhantomData, }) } fn build(&self) -> Result<Self::CF> { Ok(NoMatchComposeFilter::<W, M1, M2> { matcher1: Arc::clone(&self.matcher1), matcher2: Arc::clone(&self.matcher2), w: PhantomData, }) } } impl<W: Semiring, M1: Matcher<W>, M2: Matcher<W>> ComposeFilter<W> for NoMatchComposeFilter<W, M1, M2> { type M1 = M1; type M2 = M2; type FS = TrivialFilterState; fn start(&self) -> Self::FS { Self::FS::new(true) } fn set_state(&mut self, _s1: usize, _s2: usize, _filter_state: &Self::FS) -> Result<()> { Ok(()) } fn filter_tr(&mut self, arc1: &mut Tr<W>, arc2: &mut Tr<W>) -> Result<Self::FS> { Ok(Self::FS::new( arc1.olabel != EPS_LABEL || arc2.ilabel != EPS_LABEL, )) } fn filter_final(&self, _w1: &mut W, _w2: &mut W) -> Result<()> { Ok(()) } fn matcher1(&self) -> &Self::M1 { &self.matcher1 } fn matcher2(&self) -> &Self::M2 { &self.matcher2 } fn matcher1_shared(&self) -> &Arc<Self::M1> { &self.matcher1 } fn matcher2_shared(&self) -> &Arc<Self::M2> { &self.matcher2 } fn properties(&self, inprops: FstProperties) -> FstProperties { inprops } }