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
use anyhow::Result;
use crate::algorithms::ProjectType;
use crate::algorithms::{FinalTr, MapFinalAction, WeightConverter};
use crate::fst_properties::mutable_properties::project_properties;
use crate::fst_properties::FstProperties;
use crate::semirings::{
GallicWeight, GallicWeightLeft, GallicWeightMin, GallicWeightRestrict, GallicWeightRight,
Semiring, StringWeightLeft, StringWeightRestrict, StringWeightRight,
};
use crate::{Tr, EPS_LABEL};
pub struct ToGallicConverter {}
macro_rules! impl_to_gallic_converter {
($gallic: ident, $string_weight: ident) => {
impl<W> WeightConverter<W, $gallic<W>> for ToGallicConverter
where
W: Semiring,
{
fn tr_map(&mut self, tr: &Tr<W>) -> Result<Tr<$gallic<W>>> {
let new_tr = if tr.olabel == EPS_LABEL {
let w = ($string_weight::one(), tr.weight.clone());
Tr::new(tr.ilabel, tr.ilabel, w, tr.nextstate)
} else {
let w = (tr.olabel, tr.weight.clone());
Tr::new(tr.ilabel, tr.ilabel, w, tr.nextstate)
};
Ok(new_tr)
}
fn final_tr_map(&mut self, final_tr: &FinalTr<W>) -> Result<FinalTr<$gallic<W>>> {
if final_tr.weight.is_zero() {
bail!("Shouldn't happen")
}
let w = ($string_weight::one(), final_tr.weight.clone());
Ok(FinalTr {
ilabel: EPS_LABEL,
olabel: EPS_LABEL,
weight: w.into(),
})
}
fn final_action(&self) -> MapFinalAction {
MapFinalAction::MapNoSuperfinal
}
fn properties(&self, inprops: FstProperties) -> FstProperties {
inprops
& project_properties(inprops, ProjectType::ProjectInput)
& FstProperties::weight_invariant_properties()
}
}
};
}
impl_to_gallic_converter!(GallicWeightLeft, StringWeightLeft);
impl_to_gallic_converter!(GallicWeightRight, StringWeightRight);
impl_to_gallic_converter!(GallicWeightRestrict, StringWeightRestrict);
impl_to_gallic_converter!(GallicWeightMin, StringWeightRestrict);
impl_to_gallic_converter!(GallicWeight, StringWeightRestrict);