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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use std::sync::Arc;
use anyhow::Result;
use crate::algorithms::compose::compose_filters::{
AltSequenceComposeFilterBuilder, MatchComposeFilterBuilder, NoMatchComposeFilterBuilder,
NullComposeFilterBuilder, SequenceComposeFilterBuilder, TrivialComposeFilterBuilder,
};
use crate::algorithms::compose::matchers::SortedMatcher;
use crate::algorithms::compose::ComposeFst;
use crate::fst_traits::{AllocableFst, ExpandedFst, MutableFst};
use crate::semirings::Semiring;
#[derive(PartialOrd, PartialEq, Debug, Clone, Copy)]
pub enum ComposeFilterEnum {
AutoFilter,
NullFilter,
TrivialFilter,
SequenceFilter,
AltSequenceFilter,
MatchFilter,
NoMatchFilter,
}
#[derive(PartialOrd, PartialEq, Debug, Clone, Copy)]
pub struct ComposeConfig {
pub compose_filter: ComposeFilterEnum,
pub connect: bool,
}
impl Default for ComposeConfig {
fn default() -> Self {
Self {
compose_filter: ComposeFilterEnum::AutoFilter,
connect: true,
}
}
}
pub fn compose_with_config<
W: Semiring,
F1: ExpandedFst<W>,
F2: ExpandedFst<W>,
F3: MutableFst<W> + AllocableFst<W>,
>(
fst1: Arc<F1>,
fst2: Arc<F2>,
config: ComposeConfig,
) -> Result<F3> {
let mut ofst: F3 = match config.compose_filter {
ComposeFilterEnum::AutoFilter => ComposeFst::new_auto(fst1, fst2)?.compute()?,
ComposeFilterEnum::NullFilter => ComposeFst::<
_,
NullComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::SequenceFilter => ComposeFst::<
_,
SequenceComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::AltSequenceFilter => ComposeFst::<
_,
AltSequenceComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::MatchFilter => ComposeFst::<
_,
MatchComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::NoMatchFilter => ComposeFst::<
_,
NoMatchComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
ComposeFilterEnum::TrivialFilter => ComposeFst::<
_,
TrivialComposeFilterBuilder<_, SortedMatcher<_, _>, SortedMatcher<_, _>>,
>::new(fst1, fst2)?
.compute()?,
};
if config.connect {
crate::algorithms::connect(&mut ofst)?;
}
Ok(ofst)
}
pub fn compose<
W: Semiring,
F1: ExpandedFst<W>,
F2: ExpandedFst<W>,
F3: MutableFst<W> + AllocableFst<W>,
>(
fst1: Arc<F1>,
fst2: Arc<F2>,
) -> Result<F3> {
let config = ComposeConfig::default();
compose_with_config(fst1, fst2, config)
}