#![cfg(test)]
use proptest::prelude::*;
use crate::fst_impls::VectorFst;
use crate::fst_traits::MutableFst;
use crate::semirings::{Semiring, TropicalWeight};
use crate::Tr;
static MAX_NUM_STATES: usize = 100;
static MAX_ILABEL: usize = 100;
static MAX_OLABEL: usize = 100;
static MAX_NUM_ARCS: usize = 500;
fn proptest_weight() -> impl Strategy<Value = Option<TropicalWeight>> {
prop_oneof![
Just(None),
(2..10).prop_map(|e| Some(TropicalWeight::new(e as f32)))
]
}
fn proptest_trs(nstates: usize) -> impl Strategy<Value = Vec<(usize, Tr<TropicalWeight>)>> {
proptest::collection::vec(
(
0..nstates,
0..MAX_ILABEL,
0..MAX_OLABEL,
proptest_weight(),
0..nstates,
),
0..MAX_NUM_ARCS,
)
.prop_map(|v| {
v.into_iter()
.map(|(state, ilabel, olabel, weight, nextstate)| {
(
state,
Tr {
ilabel,
olabel,
weight: weight.unwrap_or_else(TropicalWeight::one),
nextstate,
},
)
})
.collect()
})
}
pub(crate) fn proptest_fst() -> impl Strategy<Value = VectorFst<TropicalWeight>> {
let nstates_strategy = 1..MAX_NUM_STATES;
nstates_strategy
.prop_flat_map(|nstates| {
(
Just(nstates),
(0..nstates),
proptest_trs(nstates),
proptest::collection::vec(proptest_weight(), nstates..=nstates),
)
})
.prop_map(|(nstates, start_state, trs, final_weights)| {
let mut fst = VectorFst::new();
fst.add_states(nstates);
fst.set_start(start_state).unwrap();
for (state, tr) in trs.into_iter() {
unsafe { fst.add_tr_unchecked(state, tr) };
}
for (idx, final_weight) in final_weights.into_iter().enumerate() {
if let Some(_final_weight) = final_weight {
unsafe { fst.set_final_unchecked(idx, _final_weight) };
}
}
fst
})
}