use arcweight::prelude::*;
#[test]
fn test_integer_with_vector_fst() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(5), s1));
assert_eq!(fst.num_states(), 2);
assert_eq!(fst.num_arcs(s0), 1);
let arc = fst.arcs(s0).next().unwrap();
assert_eq!(arc.weight, IntegerWeight::new(5));
}
#[test]
fn test_integer_with_shortest_distance() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s0);
fst.set_final(s2, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::one(), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::one(), s1));
fst.add_arc(s1, Arc::new(3, 3, IntegerWeight::one(), s2));
let distances = shortest_distance(&fst).unwrap();
assert_eq!(distances[s2 as usize], IntegerWeight::new(2));
}
#[test]
fn test_integer_with_arc_sort() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.add_arc(s0, Arc::new(3, 3, IntegerWeight::new(10), s1));
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(20), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::new(30), s1));
arc_sort(&mut fst, ArcSortType::ByInput).unwrap();
let labels: Vec<_> = fst.arcs(s0).map(|a| a.ilabel).collect();
assert_eq!(labels, vec![1, 2, 3]);
}
#[test]
fn test_integer_with_arc_sum() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(5), s1));
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(3), s1));
arc_sum(&mut fst).unwrap();
assert_eq!(fst.num_arcs(s0), 1);
let arc = fst.arcs(s0).next().unwrap();
assert_eq!(arc.weight, IntegerWeight::new(8)); }
#[test]
fn test_integer_with_arc_unique() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(5), s1));
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(5), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::new(3), s1));
arc_unique(&mut fst).unwrap();
assert_eq!(fst.num_arcs(s0), 2); }
#[test]
fn test_integer_with_compose() {
let mut fst1 = VectorFst::<IntegerWeight>::new();
let s0 = fst1.add_state();
let s1 = fst1.add_state();
fst1.set_start(s0);
fst1.set_final(s1, IntegerWeight::one());
fst1.add_arc(s0, Arc::new(1, 2, IntegerWeight::new(3), s1));
let mut fst2 = VectorFst::<IntegerWeight>::new();
let s0 = fst2.add_state();
let s1 = fst2.add_state();
fst2.set_start(s0);
fst2.set_final(s1, IntegerWeight::one());
fst2.add_arc(s0, Arc::new(2, 3, IntegerWeight::new(4), s1));
let result: VectorFst<IntegerWeight> = compose(&fst1, &fst2, DefaultComposeFilter).unwrap();
assert!(result.num_states() > 0);
if let Some(start) = result.start() {
if result.is_final(start) {
let final_weight = result.final_weight(start).unwrap();
assert_eq!(*final_weight, IntegerWeight::new(12));
}
}
}
#[test]
fn test_integer_with_union() {
let mut fst1 = VectorFst::<IntegerWeight>::new();
let s0 = fst1.add_state();
let s1 = fst1.add_state();
fst1.set_start(s0);
fst1.set_final(s1, IntegerWeight::new(5));
fst1.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(10), s1));
let mut fst2 = VectorFst::<IntegerWeight>::new();
let s0 = fst2.add_state();
let s1 = fst2.add_state();
fst2.set_start(s0);
fst2.set_final(s1, IntegerWeight::new(3));
fst2.add_arc(s0, Arc::new(2, 2, IntegerWeight::new(20), s1));
let result: VectorFst<IntegerWeight> = union(&fst1, &fst2).unwrap();
assert!(result.num_states() > 0);
assert!(result.num_arcs_total() >= 2);
}
#[test]
fn test_integer_with_concat() {
let mut fst1 = VectorFst::<IntegerWeight>::new();
let s0 = fst1.add_state();
let s1 = fst1.add_state();
fst1.set_start(s0);
fst1.set_final(s1, IntegerWeight::new(2));
fst1.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(3), s1));
let mut fst2 = VectorFst::<IntegerWeight>::new();
let s0 = fst2.add_state();
let s1 = fst2.add_state();
fst2.set_start(s0);
fst2.set_final(s1, IntegerWeight::new(5));
fst2.add_arc(s0, Arc::new(2, 2, IntegerWeight::new(7), s1));
let result: VectorFst<IntegerWeight> = concat(&fst1, &fst2).unwrap();
assert!(result.num_states() > 0);
assert!(result.num_arcs_total() >= 2);
}
#[test]
fn test_integer_with_reverse() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s0);
fst.set_final(s2, IntegerWeight::new(10));
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(5), s1));
fst.add_arc(s1, Arc::new(2, 2, IntegerWeight::new(3), s2));
let reversed: VectorFst<IntegerWeight> = reverse(&fst).unwrap();
assert!(reversed.num_states() >= fst.num_states());
assert!(reversed.num_arcs_total() > 0);
}
#[test]
fn test_integer_io_text_format() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, IntegerWeight::new(42));
fst.add_arc(s0, Arc::new(1, 2, IntegerWeight::new(100), s1));
let mut buffer = Vec::new();
write_text(&fst, &mut buffer, None, None).unwrap();
let text = String::from_utf8(buffer.clone()).unwrap();
assert!(text.contains("42"));
assert!(text.contains("100"));
let fst2: VectorFst<IntegerWeight> = read_text(&mut &buffer[..], None, None).unwrap();
assert_eq!(fst2.num_states(), fst.num_states());
assert_eq!(fst2.num_arcs_total(), fst.num_arcs_total());
if let Some(start) = fst2.start() {
let arc = fst2.arcs(start).next().unwrap();
assert_eq!(arc.weight, IntegerWeight::new(100));
}
}
#[test]
fn test_integer_path_counting_complex() {
let mut fst = VectorFst::<IntegerWeight>::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, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::one(), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::one(), s2));
fst.add_arc(s1, Arc::new(3, 3, IntegerWeight::one(), s3));
fst.add_arc(s2, Arc::new(4, 4, IntegerWeight::one(), s3));
let distances = shortest_distance(&fst).unwrap();
assert_eq!(distances[s3 as usize], IntegerWeight::new(2));
}
#[test]
fn test_integer_with_weighted_paths() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s0);
fst.set_final(s2, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(3), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::new(5), s1));
fst.add_arc(s1, Arc::new(3, 3, IntegerWeight::new(2), s2));
let distances = shortest_distance(&fst).unwrap();
assert_eq!(distances[s2 as usize], IntegerWeight::new(16));
}
#[test]
fn test_integer_negative_weights() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, IntegerWeight::new(-5));
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(-10), s1));
assert_eq!(fst.num_states(), 2);
let arc = fst.arcs(s0).next().unwrap();
assert_eq!(arc.weight, IntegerWeight::new(-10));
}
#[test]
fn test_integer_large_counts() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::new(1_000_000), s1));
let distances = shortest_distance(&fst).unwrap();
assert_eq!(distances[s1 as usize], IntegerWeight::new(1_000_000));
}
#[test]
fn test_integer_weight_conversion() {
let mut tropical_fst = VectorFst::<TropicalWeight>::new();
let s0 = tropical_fst.add_state();
let s1 = tropical_fst.add_state();
tropical_fst.set_start(s0);
tropical_fst.set_final(s1, TropicalWeight::new(5.0));
tropical_fst.add_arc(s0, Arc::new(1, 1, TropicalWeight::new(3.0), s1));
let integer_fst: VectorFst<IntegerWeight> =
weight_convert(&tropical_fst, |w: &TropicalWeight| {
IntegerWeight::new(w.value().floor() as i64)
})
.unwrap();
assert_eq!(integer_fst.num_states(), tropical_fst.num_states());
assert_eq!(integer_fst.num_arcs_total(), tropical_fst.num_arcs_total());
let arc = integer_fst.arcs(s0).next().unwrap();
assert_eq!(arc.weight, IntegerWeight::new(3));
}
#[test]
fn test_integer_with_topsort() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
let s2 = fst.add_state();
fst.set_start(s0);
fst.set_final(s2, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::one(), s1));
fst.add_arc(s1, Arc::new(2, 2, IntegerWeight::one(), s2));
let sorted: VectorFst<IntegerWeight> = topsort(&fst).unwrap();
assert_eq!(sorted.num_states(), fst.num_states());
}
#[test]
fn test_integer_zero_and_one() {
let mut fst = VectorFst::<IntegerWeight>::new();
let s0 = fst.add_state();
let s1 = fst.add_state();
fst.set_start(s0);
fst.set_final(s1, IntegerWeight::one());
fst.add_arc(s0, Arc::new(1, 1, IntegerWeight::one(), s1));
fst.add_arc(s0, Arc::new(2, 2, IntegerWeight::zero(), s1));
assert!(fst.is_final(s1));
assert_eq!(*fst.final_weight(s1).unwrap(), IntegerWeight::one());
let arcs: Vec<_> = fst.arcs(s0).collect();
assert_eq!(arcs.len(), 2);
assert_eq!(arcs[0].weight, IntegerWeight::one());
assert_eq!(arcs[1].weight, IntegerWeight::zero());
}