use arcweight::algorithms::{decode_linear_fst, decode_linear_fst_input, decode_linear_fst_output};
use arcweight::prelude::*;
#[test]
fn test_decode_linear_fst_simple() {
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::new(0.5));
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(1.0), s1));
fst.add_arc(s1, Arc::new(2, 2, TropicalWeight::new(2.0), s2));
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.states, vec![0, 1, 2]);
assert_eq!(path.arcs.len(), 2);
assert_eq!(path.input_labels(), vec![1, 2]);
assert_eq!(path.output_labels(), vec![1, 2]);
assert_eq!(path.weight, TropicalWeight::new(3.5));
}
#[test]
fn test_decode_linear_fst_single_state() {
let mut fst = VectorFst::<TropicalWeight>::new();
let s0 = fst.add_state();
fst.set_start(s0);
fst.set_final(s0, TropicalWeight::one());
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.states, vec![0]);
assert_eq!(path.arcs.len(), 0);
assert_eq!(path.final_state, 0);
}
#[test]
fn test_decode_linear_fst_no_start() {
let fst = VectorFst::<TropicalWeight>::new();
assert!(decode_linear_fst(&fst).is_err());
}
#[test]
fn test_decode_linear_fst_multiple_paths() {
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::one(), s1));
fst.add_arc(s0, Arc::new(2, 2, TropicalWeight::one(), s2));
assert!(decode_linear_fst(&fst).is_err());
}
#[test]
fn test_decode_linear_fst_cycle() {
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());
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::one(), s1));
fst.add_arc(s1, Arc::new(2, 2, TropicalWeight::one(), s1));
let result = decode_linear_fst(&fst);
assert!(result.is_err() || result.is_ok()); }
#[test]
fn test_decode_linear_fst_no_path_to_final() {
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());
assert!(decode_linear_fst(&fst).is_err());
}
#[test]
fn test_decode_linear_fst_input() {
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(10, 1, TropicalWeight::one(), s1));
fst.add_arc(s1, Arc::new(20, 2, TropicalWeight::one(), s2));
let input_labels = decode_linear_fst_input(&fst).unwrap();
assert_eq!(input_labels, vec![10, 20]);
}
#[test]
fn test_decode_linear_fst_output() {
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, 10, TropicalWeight::one(), s1));
fst.add_arc(s1, Arc::new(2, 20, TropicalWeight::one(), s2));
let output_labels = decode_linear_fst_output(&fst).unwrap();
assert_eq!(output_labels, vec![10, 20]);
}
#[test]
fn test_decode_linear_fst_epsilon() {
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(0, 0, TropicalWeight::one(), s1)); fst.add_arc(s1, Arc::new(1, 1, TropicalWeight::one(), s2));
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.input_labels(), vec![0, 1]);
}
#[test]
fn test_decode_linear_fst_different_weights() {
let mut fst = VectorFst::<LogWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, LogWeight::new(-0.693)); fst.add_arc(s0, Arc::new(1, 1, LogWeight::new(-1.609), s1));
let path = decode_linear_fst(&fst).unwrap();
assert!((path.weight.value() - (-2.302)).abs() < 0.001);
}
#[test]
fn test_decode_linear_fst_long_path() {
let mut fst = VectorFst::<TropicalWeight>::new();
let mut states = Vec::new();
for _ in 0..100 {
states.push(fst.add_state());
}
fst.set_start(states[0]);
fst.set_final(states[99], TropicalWeight::one());
for i in 0..99 {
fst.add_arc(
states[i],
Arc::new(i as u32, i as u32, TropicalWeight::one(), states[i + 1]),
);
}
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.states.len(), 100);
assert_eq!(path.arcs.len(), 99);
}
#[test]
fn test_decode_linear_fst_branching_error() {
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(s2, TropicalWeight::one());
fst.set_final(s3, TropicalWeight::one());
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::one(), s1));
fst.add_arc(s1, Arc::new(2, 2, TropicalWeight::one(), s2));
fst.add_arc(s1, Arc::new(3, 3, TropicalWeight::one(), s3));
assert!(decode_linear_fst(&fst).is_err());
}
#[test]
fn test_decode_linear_fst_empty_arcs() {
let mut fst = VectorFst::<TropicalWeight>::new();
let s0 = fst.add_state();
fst.set_start(s0);
fst.set_final(s0, TropicalWeight::one());
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.states, vec![0]);
assert_eq!(path.arcs.len(), 0);
}
#[test]
fn test_decode_linear_fst_weight_accumulation() {
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::new(5.0));
fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(2.0), s1));
fst.add_arc(s1, Arc::new(2, 2, TropicalWeight::new(3.0), s2));
let path = decode_linear_fst(&fst).unwrap();
assert_eq!(path.weight, TropicalWeight::new(10.0));
}