Compare commits
2 commits
6d79b7a7fa
...
a8f20af75d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8f20af75d | ||
|
|
6518ed8a4d |
131
src/main.rs
131
src/main.rs
|
|
@ -85,133 +85,4 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod test;
|
||||||
use super::*;
|
|
||||||
use assert_approx_eq::assert_approx_eq;
|
|
||||||
|
|
||||||
fn simple_symmetric_tree() -> Tree<String, f64> {
|
|
||||||
let a = Alternative {
|
|
||||||
name: "A".to_owned()
|
|
||||||
};
|
|
||||||
let b = Alternative {
|
|
||||||
name: "B".to_owned()
|
|
||||||
};
|
|
||||||
let edge_a = Edge {
|
|
||||||
weight: 1.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(a)}
|
|
||||||
};
|
|
||||||
let edge_b = Edge {
|
|
||||||
weight: 1.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(b)}
|
|
||||||
};
|
|
||||||
let root = Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b));
|
|
||||||
Tree {root: root}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn simple_asymmetric_tree() -> Tree<String, f64> {
|
|
||||||
let a = Alternative {
|
|
||||||
name: "A".to_owned()
|
|
||||||
};
|
|
||||||
let b = Alternative {
|
|
||||||
name: "B".to_owned()
|
|
||||||
};
|
|
||||||
let edge_a = Edge {
|
|
||||||
weight: 3.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(a)}
|
|
||||||
};
|
|
||||||
let edge_b = Edge {
|
|
||||||
weight: 1.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(b)}
|
|
||||||
};
|
|
||||||
let root = Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b));
|
|
||||||
Tree {root: root}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn complex_tree() -> Tree<String, f64> {
|
|
||||||
let a = Alternative {
|
|
||||||
name: "A".to_owned()
|
|
||||||
};
|
|
||||||
let b = Alternative {
|
|
||||||
name: "B".to_owned()
|
|
||||||
};
|
|
||||||
let c = Alternative {
|
|
||||||
name: "C".to_owned()
|
|
||||||
};
|
|
||||||
let edge_a = Edge {
|
|
||||||
weight: 2.5,
|
|
||||||
destination: Tree {root: Vertex::Terminal(a)}
|
|
||||||
};
|
|
||||||
let edge_b = Edge {
|
|
||||||
weight: 1.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(b)}
|
|
||||||
};
|
|
||||||
let edge_ab = Edge{
|
|
||||||
weight: 0.5,
|
|
||||||
destination: Tree {
|
|
||||||
root: Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let edge_c = Edge{
|
|
||||||
weight: 1.0,
|
|
||||||
destination: Tree {root: Vertex::Terminal(c)}
|
|
||||||
};
|
|
||||||
let root = Vertex::NonTerminal(Box::new(edge_ab), Box::new(edge_c));
|
|
||||||
Tree {root: root}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// A test for the simplest symmetric case
|
|
||||||
#[test]
|
|
||||||
fn choice_probability_test_1() {
|
|
||||||
assert_eq!(simple_symmetric_tree().choice_probability(&("A".to_owned())), 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A test for the simplest asymmetric case
|
|
||||||
#[test]
|
|
||||||
fn choice_probability_test_2() {
|
|
||||||
assert_eq!(simple_asymmetric_tree().choice_probability(&("A".to_owned())), 0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A test for depth higher than 1
|
|
||||||
#[test]
|
|
||||||
fn choice_probability_test_3() {
|
|
||||||
assert_approx_eq!(
|
|
||||||
complex_tree().choice_probability(&("A".to_owned())),
|
|
||||||
(2.5/(2.5+1.0))*((2.5+1.0+0.5)/(2.5+1.0+0.5+1.0))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A test for parsing the simplest symmetric case
|
|
||||||
#[test]
|
|
||||||
fn parser_test_1() {
|
|
||||||
assert_eq!(
|
|
||||||
{
|
|
||||||
let (_, b) = parser::subtree("([1.0]A[1.0]B)").unwrap();
|
|
||||||
b
|
|
||||||
},
|
|
||||||
simple_symmetric_tree()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parser_test_2() {
|
|
||||||
assert_eq!(
|
|
||||||
{
|
|
||||||
let (_, b) = parser::subtree("([3.0]A[1.0]B)").unwrap();
|
|
||||||
b
|
|
||||||
},
|
|
||||||
simple_asymmetric_tree()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parser_test_3() {
|
|
||||||
assert_eq!(
|
|
||||||
{
|
|
||||||
let (_, b) = parser::subtree("([0.5]([2.5]A[1.0]B)[1.0]C)").unwrap();
|
|
||||||
b
|
|
||||||
},
|
|
||||||
complex_tree()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,14 @@
|
||||||
/*
|
/*
|
||||||
* WHAT WE ARE PARSING:
|
* WHAT WE ARE PARSING:
|
||||||
*
|
* letter = "A"-"Z" | "a"-"z" ;
|
||||||
|
* digit = "0"-"9" ;
|
||||||
|
* decimal = digit + , ".", digit + ;
|
||||||
|
* weight = "[" , decimal , "]" ;
|
||||||
|
* alternative = letter + ;
|
||||||
|
* edge to alternative = weight , alternative ;
|
||||||
|
* out edge = edge to alternative | edge to subtree ;
|
||||||
|
* subtree = "(" , out edge , out edge , ")" ;
|
||||||
|
* edge to subtree = weight , subtree ;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use nom::{branch::alt, bytes::complete::take_while1, character::char, combinator::map, error::Error, number::complete::double, sequence::{delimited, pair}, AsChar, IResult, Parser};
|
use nom::{branch::alt, bytes::complete::take_while1, character::char, combinator::map, error::Error, number::complete::double, sequence::{delimited, pair}, AsChar, IResult, Parser};
|
||||||
|
|
@ -16,7 +24,7 @@ fn weighted_edge(input: &str) -> IResult<&str, Edge<String, f64>> {
|
||||||
let alternative = map(
|
let alternative = map(
|
||||||
take_while1::<_, &str, Error<&str>>(AsChar::is_alpha),
|
take_while1::<_, &str, Error<&str>>(AsChar::is_alpha),
|
||||||
|a| Tree::<String, f64> {
|
|a| Tree::<String, f64> {
|
||||||
root: Vertex::Terminal(Alternative{name: a.to_string()})
|
root: Vertex::Terminal(Alternative{name: a.to_owned()})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
map(
|
map(
|
||||||
|
|
|
||||||
128
src/test.rs
Normal file
128
src/test.rs
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
use super::*;
|
||||||
|
use assert_approx_eq::assert_approx_eq;
|
||||||
|
|
||||||
|
fn simple_symmetric_tree() -> Tree<String, f64> {
|
||||||
|
let a = Alternative {
|
||||||
|
name: "A".to_owned()
|
||||||
|
};
|
||||||
|
let b = Alternative {
|
||||||
|
name: "B".to_owned()
|
||||||
|
};
|
||||||
|
let edge_a = Edge {
|
||||||
|
weight: 1.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(a)}
|
||||||
|
};
|
||||||
|
let edge_b = Edge {
|
||||||
|
weight: 1.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(b)}
|
||||||
|
};
|
||||||
|
let root = Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b));
|
||||||
|
Tree {root: root}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn simple_asymmetric_tree() -> Tree<String, f64> {
|
||||||
|
let a = Alternative {
|
||||||
|
name: "A".to_owned()
|
||||||
|
};
|
||||||
|
let b = Alternative {
|
||||||
|
name: "B".to_owned()
|
||||||
|
};
|
||||||
|
let edge_a = Edge {
|
||||||
|
weight: 3.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(a)}
|
||||||
|
};
|
||||||
|
let edge_b = Edge {
|
||||||
|
weight: 1.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(b)}
|
||||||
|
};
|
||||||
|
let root = Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b));
|
||||||
|
Tree {root: root}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn complex_tree() -> Tree<String, f64> {
|
||||||
|
let a = Alternative {
|
||||||
|
name: "A".to_owned()
|
||||||
|
};
|
||||||
|
let b = Alternative {
|
||||||
|
name: "B".to_owned()
|
||||||
|
};
|
||||||
|
let c = Alternative {
|
||||||
|
name: "C".to_owned()
|
||||||
|
};
|
||||||
|
let edge_a = Edge {
|
||||||
|
weight: 2.5,
|
||||||
|
destination: Tree {root: Vertex::Terminal(a)}
|
||||||
|
};
|
||||||
|
let edge_b = Edge {
|
||||||
|
weight: 1.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(b)}
|
||||||
|
};
|
||||||
|
let edge_ab = Edge{
|
||||||
|
weight: 0.5,
|
||||||
|
destination: Tree {
|
||||||
|
root: Vertex::NonTerminal(Box::new(edge_a), Box::new(edge_b))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let edge_c = Edge{
|
||||||
|
weight: 1.0,
|
||||||
|
destination: Tree {root: Vertex::Terminal(c)}
|
||||||
|
};
|
||||||
|
let root = Vertex::NonTerminal(Box::new(edge_ab), Box::new(edge_c));
|
||||||
|
Tree {root: root}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// A test for the simplest symmetric case
|
||||||
|
#[test]
|
||||||
|
fn choice_probability_test_1() {
|
||||||
|
assert_eq!(simple_symmetric_tree().choice_probability(&("A".to_owned())), 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A test for the simplest asymmetric case
|
||||||
|
#[test]
|
||||||
|
fn choice_probability_test_2() {
|
||||||
|
assert_eq!(simple_asymmetric_tree().choice_probability(&("A".to_owned())), 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A test for depth higher than 1
|
||||||
|
#[test]
|
||||||
|
fn choice_probability_test_3() {
|
||||||
|
assert_approx_eq!(
|
||||||
|
complex_tree().choice_probability(&("A".to_owned())),
|
||||||
|
(2.5/(2.5+1.0))*((2.5+1.0+0.5)/(2.5+1.0+0.5+1.0))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A test for parsing the simplest symmetric case
|
||||||
|
#[test]
|
||||||
|
fn parser_test_1() {
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let (_, b) = parser::subtree("([1.0]A[1.0]B)").unwrap();
|
||||||
|
b
|
||||||
|
},
|
||||||
|
simple_symmetric_tree()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parser_test_2() {
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let (_, b) = parser::subtree("([3.0]A[1.0]B)").unwrap();
|
||||||
|
b
|
||||||
|
},
|
||||||
|
simple_asymmetric_tree()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parser_test_3() {
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let (_, b) = parser::subtree("([0.5]([2.5]A[1.0]B)[1.0]C)").unwrap();
|
||||||
|
b
|
||||||
|
},
|
||||||
|
complex_tree()
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue