use arcweight::prelude::*;
#[test]
fn test_encode_decode_preserves_structure() {
let mut fst = VectorFst::<TropicalWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
let s3 = fst.add_state();
fst.set_start(s0);
fst.set_final(s3, TropicalWeight::new(1.0));
fst.add_arc(s0, Arc::new(1, 2, TropicalWeight::new(0.5), s1));
fst.add_arc(s0, Arc::new(3, 4, TropicalWeight::new(0.3), s2));
fst.add_arc(s1, Arc::new(5, 6, TropicalWeight::new(0.2), s3));
fst.add_arc(s2, Arc::new(7, 8, TropicalWeight::new(0.4), s3));
let (encoded, table) = encode(&fst).unwrap();
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
assert_eq!(decoded.num_arcs_total(), fst.num_arcs_total());
assert_eq!(decoded.start(), fst.start());
for state in fst.states() {
let orig_arcs: Vec<_> = fst.arcs(state).collect();
let dec_arcs: Vec<_> = decoded.arcs(state).collect();
assert_eq!(orig_arcs.len(), dec_arcs.len());
for (orig, dec) in orig_arcs.iter().zip(dec_arcs.iter()) {
assert_eq!(orig.ilabel, dec.ilabel);
assert_eq!(orig.olabel, dec.olabel);
assert_eq!(orig.weight, dec.weight);
assert_eq!(orig.nextstate, dec.nextstate);
}
}
}
#[test]
fn test_encode_decode_with_determinization() {
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(s1, TropicalWeight::one());
fst.set_final(s2, TropicalWeight::one());
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(0.5), s1));
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(0.3), s2));
let (encoded, table) = encode(&fst).unwrap();
assert_eq!(encoded.num_states(), fst.num_states());
assert_eq!(encoded.num_arcs_total(), fst.num_arcs_total());
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
assert_eq!(decoded.num_arcs_total(), fst.num_arcs_total());
}
#[test]
fn test_encode_decode_with_minimization() {
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(s1, TropicalWeight::new(1.0));
fst.set_final(s2, TropicalWeight::new(1.0));
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(0.5), s1));
fst.add_arc(s0, Arc::new(2, 2, TropicalWeight::new(0.5), s2));
let (encoded, table) = encode(&fst).unwrap();
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
}
#[test]
fn test_encode_decode_complex_transducer() {
let mut fst = VectorFst::<TropicalWeight>::new();
let states: Vec<_> = (0..10).map(|_| fst.add_state()).collect();
fst.set_start(states[0]);
fst.set_final(states[9], TropicalWeight::new(2.0));
for i in 0..9 {
fst.add_arc(
states[i],
Arc::new(
(i + 1) as u32,
(i + 2) as u32,
TropicalWeight::new((i as f32 + 1.0) * 0.1),
states[i + 1],
),
);
}
fst.add_arc(
states[2],
Arc::epsilon(TropicalWeight::new(0.05), states[5]),
);
fst.add_arc(
states[4],
Arc::epsilon(TropicalWeight::new(0.15), states[7]),
);
let (encoded, table) = encode(&fst).unwrap();
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
assert_eq!(decoded.num_arcs_total(), fst.num_arcs_total());
for state in fst.states() {
let orig_arcs: Vec<_> = fst.arcs(state).collect();
let dec_arcs: Vec<_> = decoded.arcs(state).collect();
assert_eq!(orig_arcs.len(), dec_arcs.len());
for (orig, dec) in orig_arcs.iter().zip(dec_arcs.iter()) {
assert_eq!(orig.ilabel, dec.ilabel);
assert_eq!(orig.olabel, dec.olabel);
assert_eq!(orig.weight, dec.weight);
assert_eq!(orig.nextstate, dec.nextstate);
}
}
}
#[test]
fn test_encode_with_multiple_identical_arcs() {
let mut fst = VectorFst::<TropicalWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, TropicalWeight::one());
for _ in 0..10 {
fst.add_arc(s0, Arc::new(1, 2, TropicalWeight::new(0.5), s1));
}
let (encoded, table) = encode(&fst).unwrap();
assert_eq!(table.size(), 1);
let arcs: Vec<_> = encoded.arcs(s0).collect();
assert_eq!(arcs.len(), 10);
let first_label = arcs[0].ilabel;
for arc in &arcs {
assert_eq!(arc.ilabel, first_label);
}
}
#[test]
fn test_encode_decode_with_cycles() {
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(1, 1, TropicalWeight::new(0.5), s1));
fst.add_arc(s1, Arc::new(2, 2, TropicalWeight::new(0.3), s2));
fst.add_arc(s1, Arc::new(3, 3, TropicalWeight::new(0.2), s0)); fst.add_arc(s2, Arc::new(4, 4, TropicalWeight::new(0.1), s0));
let (encoded, table) = encode(&fst).unwrap();
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
assert_eq!(decoded.num_arcs_total(), fst.num_arcs_total());
for state in fst.states() {
let orig_arcs: Vec<_> = fst.arcs(state).collect();
let dec_arcs: Vec<_> = decoded.arcs(state).collect();
assert_eq!(orig_arcs.len(), dec_arcs.len());
}
}
#[test]
fn test_encode_decode_with_boolean_weight() {
let mut fst = VectorFst::<BooleanWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, BooleanWeight::one());
fst.add_arc(s0, Arc::new(1, 2, BooleanWeight::one(), s1));
fst.add_arc(s0, Arc::new(3, 4, BooleanWeight::one(), s1));
let (encoded, table) = encode(&fst).unwrap();
let decoded = decode(&encoded, &table).unwrap();
assert_eq!(decoded.num_states(), fst.num_states());
assert_eq!(decoded.num_arcs_total(), fst.num_arcs_total());
for state in fst.states() {
let orig_arcs: Vec<_> = fst.arcs(state).collect();
let dec_arcs: Vec<_> = decoded.arcs(state).collect();
assert_eq!(orig_arcs.len(), dec_arcs.len());
for (orig, dec) in orig_arcs.iter().zip(dec_arcs.iter()) {
assert_eq!(orig.ilabel, dec.ilabel);
assert_eq!(orig.olabel, dec.olabel);
assert_eq!(orig.weight, dec.weight);
}
}
}
#[test]
fn test_encode_table_reuse() {
let mut fst1 = VectorFst::<TropicalWeight>::new();
let s0 = fst1.add_state();
let s1 = fst1.add_state();
fst1.set_start(s0);
fst1.set_final(s1, TropicalWeight::one());
fst1.add_arc(s0, Arc::new(1, 2, TropicalWeight::new(0.5), s1));
let mut fst2 = VectorFst::<TropicalWeight>::new();
let t0 = fst2.add_state();
let t1 = fst2.add_state();
fst2.set_start(t0);
fst2.set_final(t1, TropicalWeight::one());
fst2.add_arc(t0, Arc::new(1, 2, TropicalWeight::new(0.5), t1));
let (encoded1, table1) = encode(&fst1).unwrap();
let (encoded2, table2) = encode(&fst2).unwrap();
assert_eq!(table1.size(), table2.size());
let decoded1 = decode(&encoded1, &table1).unwrap();
let decoded2 = decode(&encoded2, &table2).unwrap();
assert_eq!(decoded1.num_arcs_total(), fst1.num_arcs_total());
assert_eq!(decoded2.num_arcs_total(), fst2.num_arcs_total());
}