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
use std::cell::RefCell;
use std::collections::HashMap;
use crate::algorithms::encode::EncodeType;
use crate::algorithms::FinalTr;
use crate::{Label, Semiring, Tr, EPS_LABEL};
use std::collections::hash_map::Entry;
#[derive(PartialEq, Eq, Hash, Clone)]
pub struct EncodeTuple<W: Semiring> {
pub ilabel: Label,
pub olabel: Label,
pub weight: W,
}
pub struct EncodeTableMut<W: Semiring> {
pub encode_type: EncodeType,
id_to_tuple: Vec<EncodeTuple<W>>,
tuple_to_id: HashMap<EncodeTuple<W>, usize>,
}
pub struct EncodeTable<W: Semiring>(pub RefCell<EncodeTableMut<W>>);
impl<W: Semiring> EncodeTableMut<W> {
pub fn new(encode_type: EncodeType) -> Self {
EncodeTableMut {
encode_type,
id_to_tuple: vec![],
tuple_to_id: HashMap::new(),
}
}
pub fn tr_to_tuple(&self, tr: &Tr<W>) -> EncodeTuple<W> {
EncodeTuple {
ilabel: tr.ilabel,
olabel: if self.encode_type.encode_labels() {
tr.olabel
} else {
EPS_LABEL
},
weight: if self.encode_type.encode_weights() {
tr.weight.clone()
} else {
W::one()
},
}
}
pub fn final_tr_to_tuple(&self, tr: &FinalTr<W>) -> EncodeTuple<W> {
EncodeTuple {
ilabel: tr.ilabel,
olabel: if self.encode_type.encode_labels() {
tr.olabel
} else {
EPS_LABEL
},
weight: if self.encode_type.encode_weights() {
tr.weight.clone()
} else {
W::one()
},
}
}
pub fn encode(&mut self, tuple: EncodeTuple<W>) -> usize {
let a = match self.tuple_to_id.entry(tuple.clone()) {
Entry::Occupied(e) => *e.get(),
Entry::Vacant(e) => {
let new_id = self.id_to_tuple.len();
self.id_to_tuple.push(tuple);
*e.insert(new_id)
}
};
a + 1
}
pub fn decode(&mut self, tuple_id: usize) -> Option<&EncodeTuple<W>> {
self.id_to_tuple.get(tuple_id - 1)
}
}
impl<W: Semiring> Default for EncodeTableMut<W> {
fn default() -> Self {
Self::new(EncodeType::EncodeWeightsAndLabels)
}
}