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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//! FST reversal algorithm.
//!
//! Constructs the reverse of a weighted finite-state transducer by reversing
//! all transitions and swapping start/final states. The reversed FST accepts
//! the reversal of each string in the original language.
//!
//! For an FST $`T`$ that accepts language $`L`$, the reversed FST $`T^R`$ accepts
//! the language $`L^R = \{w^R : w \in L\}`$ where $`w^R`$ is the reversal of string $`w`$.
//!
//! # Complexity
//!
//! - **Time:** $`O(|V| + |E|)`$ for state and arc creation
//! - **Space:** $`O(|V| + |E|)`$ for the new FST structure
//!
//! # References
//!
//! - Mehryar Mohri. 2009. Weighted automata algorithms. In *Handbook of Weighted
//! Automata*, Manfred Droste, Werner Kuich, and Heiko Vogler (Eds.). Springer,
//! Berlin, Heidelberg, 213-254. DOI: <https://doi.org/10.1007/978-3-642-01492-5_6>
use crateArc;
use crate;
use crateSemiring;
use crateResult;
/// Reverses an FST by swapping direction of transitions and start/final states.
///
/// Creates the reverse automaton where all transitions are reversed, the original
/// start state becomes final, and original final states connect to a new start state.
/// The reversed FST accepts the reversal of each string in the original language.
///
/// For an FST $`T`$ that maps input strings to output strings with weights,
/// the reverse $`T^R`$ satisfies: $`T^R(x^R) = T(x)`$ where $`x^R`$ is the reversal
/// of string $`x`$.
///
/// # Type Parameters
///
/// * `W` - Weight type implementing [`Semiring`]
/// * `F` - Input FST type implementing [`Fst<W>`]
/// * `M` - Output FST type implementing [`MutableFst<W>`] and [`Default`]
///
/// # Returns
///
/// A new FST representing the reversal of the input FST.
///
/// # Errors
///
/// Returns [`Error::Algorithm`](crate::Error::Algorithm) if the input FST is invalid.
///
/// # Examples
///
/// ```rust
/// use arcweight::prelude::*;
///
/// // Create FST that accepts "ab"
/// let mut fst = VectorFst::<TropicalWeight>::new();
/// let s0 = fst.add_state();
/// let s1 = fst.add_state();
/// let s2 = fst.add_state();
///
/// fst.set_start(s0);
/// fst.set_final(s2, TropicalWeight::one());
///
/// fst.add_arc(s0, Arc::new('a' as u32, 'a' as u32, TropicalWeight::one(), s1));
/// fst.add_arc(s1, Arc::new('b' as u32, 'b' as u32, TropicalWeight::one(), s2));
///
/// // Reverse: now accepts "ba"
/// let reversed: VectorFst<TropicalWeight> = reverse(&fst)?;
///
/// // +1 state for new start that connects to original finals
/// assert_eq!(reversed.num_states(), fst.num_states() + 1);
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # References
///
/// - Mehryar Mohri. 2009. Weighted automata algorithms. In *Handbook of Weighted
/// Automata*, Manfred Droste, Werner Kuich, and Heiko Vogler (Eds.). Springer,
/// Berlin, Heidelberg, 213-254.
///
/// [`Semiring`]: crate::semiring::Semiring