use num_traits::Float; mod parser; /* * NOTES * - each alternative should appear only once in a tree. need to figure out a * way to enforce this. * - looks like this is like quite difficult to do through the type system */ #[derive(PartialEq, Eq, Debug)] pub struct Alternative { name: T } #[derive(PartialEq, Eq, Debug)] pub struct Edge { weight: U, destination: Tree } #[derive(PartialEq, Eq, Debug)] pub enum Vertex { NonTerminal(Box>, Box>), Terminal(Alternative), } #[derive(PartialEq, Eq, Debug)] pub struct Tree { root: Vertex } impl Tree { fn left_edge_weights(&self) -> U { match &self.root { Vertex::NonTerminal(a, _) => { let left = &*a; left.weight + left.destination.left_edge_weights() + left.destination.right_edge_weights() }, Vertex::Terminal(_) => U::zero() } } fn right_edge_weights(&self) -> U { match &self.root { Vertex::NonTerminal(_, b) => { let right = &*b; right.weight + right.destination.left_edge_weights() + right.destination.right_edge_weights() }, Vertex::Terminal(_) => U::zero() } } pub fn choice_probability(&self, alternative: &T) -> U { match &self.root { Vertex::Terminal(alt) => { if alt.name == *alternative { U::one() } else { U::zero() } }, Vertex::NonTerminal(a, b) => { let left = &*a; let right = &*b; let left_edge_weights = self.left_edge_weights(); let right_edge_weights = self.right_edge_weights(); let left_choice_probability = left.destination.choice_probability(alternative); let right_choice_probability = right.destination.choice_probability(alternative); ( left_edge_weights * left_choice_probability + right_edge_weights * right_choice_probability ) /(left_edge_weights + right_edge_weights) } } } } fn main() { unimplemented!(); } #[cfg(test)] mod test;