use super::intersection::PathNode;
use super::state_f64::StateF64;
use libdictenstein::{CharUnit, DictionaryNode};
pub struct IntersectionF64<N: DictionaryNode> {
pub label: Option<N::Unit>,
pub node: N,
pub state: StateF64,
pub parent: Option<Box<PathNode<N::Unit>>>,
}
impl<N: DictionaryNode> IntersectionF64<N> {
pub fn new(node: N, state: StateF64) -> Self {
Self {
label: None,
node,
state,
parent: None,
}
}
#[inline]
pub fn with_parent(
label: N::Unit,
node: N,
state: StateF64,
parent: Option<Box<PathNode<N::Unit>>>,
) -> Self {
Self {
label: Some(label),
node,
state,
parent,
}
}
pub fn term(&self) -> String {
let mut units = Vec::new();
if let Some(label) = self.label {
units.push(label);
}
if let Some(parent) = &self.parent {
parent.collect_labels(&mut units);
}
units.reverse();
N::Unit::to_string(&units)
}
pub fn depth(&self) -> usize {
match &self.parent {
Some(parent) => 1 + parent.depth(),
None => {
if self.label.is_some() {
1
} else {
0
}
}
}
}
#[inline(always)]
pub fn is_final(&self) -> bool {
self.node.is_final()
}
#[inline(always)]
pub fn min_distance(&self) -> Option<f64> {
self.state.min_distance()
}
}
impl<N: DictionaryNode> Clone for IntersectionF64<N> {
fn clone(&self) -> Self {
Self {
label: self.label,
node: self.node.clone(),
state: self.state.clone(),
parent: self.parent.clone(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::transducer::PositionF64;
use libdictenstein::double_array_trie::DoubleArrayTrie;
use libdictenstein::Dictionary;
#[test]
fn test_intersection_creation() {
let dict = DoubleArrayTrie::from_terms(vec!["test"]);
let root = dict.root();
let state = StateF64::single(PositionF64::new(0, 0.0));
let intersection = IntersectionF64::new(root, state);
assert_eq!(intersection.depth(), 0);
assert_eq!(intersection.term(), "");
}
#[test]
fn test_intersection_path_reconstruction() {
let dict = DoubleArrayTrie::from_terms(vec!["test"]);
let root = dict.root();
let t_node = root
.transition(b't')
.expect("test fixture: 't' exists in dictionary root");
let e_node = t_node
.transition(b'e')
.expect("test fixture: 'e' exists at t-node");
let s_node = e_node
.transition(b's')
.expect("test fixture: 's' exists at e-node");
let i4 = IntersectionF64::with_parent(
b's',
s_node,
StateF64::new(),
Some(Box::new(PathNode::new(
b'e',
Some(Box::new(PathNode::new(b't', None))),
))),
);
assert_eq!(i4.term(), "tes");
assert_eq!(i4.depth(), 3);
}
}