extern crate tphrase;
use tphrase::*;
mod utils;
use utils::*;
#[test]
fn test_struct_generator_new() {
let mut ph: Generator = Generator::new();
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
}
#[test]
fn test_struct_generator_default() {
let mut ph: Generator = Default::default();
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
}
#[test]
fn test_struct_generator_from_str() {
let mut ph: Generator = std::str::FromStr::from_str(
r#"
main = Hello, World!
"#,
)
.unwrap();
assert_eq!(ph.generate(), "Hello, World!");
assert_eq!(ph.combination_number(), 1);
assert_eq!(ph.weight(), 1.0);
assert_eq!(ph.number_of_syntax(), 1);
}
#[test]
fn test_struct_generator_str_parse() {
let mut ph: Generator = r#"
main = Hello, World!
"#
.parse()
.unwrap();
assert_eq!(ph.generate(), "Hello, World!");
assert_eq!(ph.combination_number(), 1);
assert_eq!(ph.weight(), 1.0);
assert_eq!(ph.number_of_syntax(), 1);
}
#[test]
fn test_struct_generator_clone_and_equalize_chance() {
let mut ph1: Generator = r#"
main = {= X | Y | Z } | {A} | {B}
A = A1 | A2 | A3 ~ /a/b/
B = B1 | B2 | B3
"#
.parse()
.unwrap();
let syntax: Syntax = r#"
main = {= V | W } | {C} ~ /c/d/
C = C1 | C2 | C3
"#
.parse()
.unwrap();
ph1.add(syntax).unwrap();
let mut ph2: Generator = ph1.clone();
ph1.equalize_chance(true);
let dist1 = TextDistribution::from([
("X".to_string(), 1.0 / (2.0 * 9.0)),
("Y".to_string(), 1.0 / (2.0 * 9.0)),
("Z".to_string(), 1.0 / (2.0 * 9.0)),
("A1".to_string(), 1.0 / (2.0 * 9.0)),
("A2".to_string(), 1.0 / (2.0 * 9.0)),
("A3".to_string(), 1.0 / (2.0 * 9.0)),
("B1".to_string(), 1.0 / (2.0 * 9.0)),
("B2".to_string(), 1.0 / (2.0 * 9.0)),
("B3".to_string(), 1.0 / (2.0 * 9.0)),
("V".to_string(), 1.0 / (2.0 * 5.0)),
("W".to_string(), 1.0 / (2.0 * 5.0)),
("C1".to_string(), 1.0 / (2.0 * 5.0)),
("C2".to_string(), 1.0 / (2.0 * 5.0)),
("C3".to_string(), 1.0 / (2.0 * 5.0)),
]);
let dist2 = TextDistribution::from([
("X".to_string(), 1.0 / 14.0),
("Y".to_string(), 1.0 / 14.0),
("Z".to_string(), 1.0 / 14.0),
("A1".to_string(), 1.0 / 14.0),
("A2".to_string(), 1.0 / 14.0),
("A3".to_string(), 1.0 / 14.0),
("B1".to_string(), 1.0 / 14.0),
("B2".to_string(), 1.0 / 14.0),
("B3".to_string(), 1.0 / 14.0),
("V".to_string(), 1.0 / 14.0),
("W".to_string(), 1.0 / 14.0),
("C1".to_string(), 1.0 / 14.0),
("C2".to_string(), 1.0 / 14.0),
("C3".to_string(), 1.0 / 14.0),
]);
assert!(check_distribution(&mut ph1, 100000, &dist1, 0.01));
assert!(check_distribution(&mut ph2, 100000, &dist2, 0.01));
assert_eq!(ph1.combination_number(), 14);
assert_eq!(ph1.weight(), 14.0);
assert_eq!(ph1.number_of_syntax(), 2);
assert_eq!(ph2.combination_number(), 14);
assert_eq!(ph2.weight(), 14.0);
assert_eq!(ph2.number_of_syntax(), 2);
}
#[test]
fn test_struct_generator_generate() {
let mut ph: Generator<ZeroNG> = r#"
main = A | B | C
"#
.parse()
.unwrap();
assert_eq!(ph.generate(), "A");
}
#[test]
fn test_struct_generator_generate_with_context() {
let mut ph: Generator<ZeroNG> = r#"
main = {A} | B | C
"#
.parse()
.unwrap();
assert_eq!(
ph.generate_with_context(&ExtContext::from([("A".to_string(), "a".to_string()),])),
"a"
);
}
#[test]
fn test_struct_generator_add() {
let mut ph: Generator<ZeroNG> = r#"
main = {= X | Y | Z } | {A} | {B}
A = A1 | A2 | A3
B = B1 | B2 | B3
"#
.parse()
.unwrap();
let syntax: Syntax = r#"
main = {= V | W } | {C}
C = C1 | C2 | C3
"#
.parse()
.unwrap();
let id: SyntaxId = ph.add(syntax).unwrap();
assert_eq!(id, 2);
assert_eq!(ph.generate(), "X");
assert_eq!(ph.combination_number(), 14);
assert_eq!(ph.weight(), 14.0);
assert_eq!(ph.number_of_syntax(), 2);
}
#[test]
fn test_struct_generator_add_with_start_condition() {
let syntax: Syntax = r#"
main = MAIN
alt = ALT
"#
.parse()
.unwrap();
let mut ph: Generator = Generator::new();
let id: SyntaxId = ph.add_with_start_condition(syntax, "alt").unwrap();
assert_eq!(id, 1);
assert_eq!(ph.generate(), "ALT");
assert_eq!(ph.combination_number(), 1);
assert_eq!(ph.weight(), 1.0);
assert_eq!(ph.number_of_syntax(), 1);
}
#[test]
fn test_struct_generator_add_and_error() {
let mut ph: Generator<ZeroNG> = r#"
main = {= X | Y | Z } | {A} | {B}
A = A1 | A2 | A3
B = B1 | B2 | B3
"#
.parse()
.unwrap();
let syntax1: Syntax = r#"
main = {= V | W } | {C}
C = C1 | C2 | C3
"#
.parse()
.unwrap();
assert!(ph.add_with_start_condition(syntax1, "MAIN").is_err());
let syntax2: Syntax = r#"
C = C4
"#
.parse()
.unwrap();
let id2: SyntaxId = ph.add_with_start_condition(syntax2, "C").unwrap();
assert_eq!(id2, 2);
assert_eq!(ph.generate(), "X");
assert_eq!(ph.combination_number(), 10);
assert_eq!(ph.weight(), 10.0);
assert_eq!(ph.number_of_syntax(), 2);
}
#[test]
fn test_struct_generator_remove_first_phrase() {
let mut ph: Generator<Point9NG> = Generator::new();
let syntax1: Syntax = r#"main = "1" 2 | 2 | 3"#.parse().unwrap();
let syntax2: Syntax = r#"main = A | "B" 3 | C"#.parse().unwrap();
let syntax3: Syntax = r#"main = あ | い | "う" 4"#.parse().unwrap();
let id1: SyntaxId = ph.add(syntax1).unwrap();
let id2: SyntaxId = ph.add(syntax2).unwrap();
let id3: SyntaxId = ph.add(syntax3).unwrap();
assert_eq!(id1, 1);
assert_eq!(id2, 2);
assert_eq!(id3, 3);
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 9);
assert_eq!(ph.weight(), 15.0);
assert_eq!(ph.number_of_syntax(), 3);
let _ = ph.remove(id1).unwrap();
assert!(ph.remove(id1).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 6);
assert_eq!(ph.weight(), 11.0);
assert_eq!(ph.number_of_syntax(), 2);
let _ = ph.remove(id2).unwrap();
assert!(ph.remove(id2).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 3);
assert_eq!(ph.weight(), 6.0);
assert_eq!(ph.number_of_syntax(), 1);
let _ = ph.remove(id3).unwrap();
assert!(ph.remove(id3).is_err());
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
}
#[test]
fn test_struct_generator_remove_last_phrase() {
let mut ph: Generator<Point9NG> = Generator::new();
let syntax1: Syntax = r#"main = "1" 2 | 2 | 3"#.parse().unwrap();
let syntax2: Syntax = r#"main = A | "B" 3 | C"#.parse().unwrap();
let syntax3: Syntax = r#"main = あ | い | "う" 4"#.parse().unwrap();
let id1: SyntaxId = ph.add(syntax1).unwrap();
let id2: SyntaxId = ph.add(syntax2).unwrap();
let id3: SyntaxId = ph.add(syntax3).unwrap();
assert_eq!(id1, 1);
assert_eq!(id2, 2);
assert_eq!(id3, 3);
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 9);
assert_eq!(ph.weight(), 15.0);
assert_eq!(ph.number_of_syntax(), 3);
let _ = ph.remove(id3).unwrap();
assert!(ph.remove(id3).is_err());
assert_eq!(ph.generate(), "C");
assert_eq!(ph.combination_number(), 6);
assert_eq!(ph.weight(), 9.0);
assert_eq!(ph.number_of_syntax(), 2);
let _ = ph.remove(id2).unwrap();
assert!(ph.remove(id2).is_err());
assert_eq!(ph.generate(), "3");
assert_eq!(ph.combination_number(), 3);
assert_eq!(ph.weight(), 4.0);
assert_eq!(ph.number_of_syntax(), 1);
let _ = ph.remove(id1).unwrap();
assert!(ph.remove(id1).is_err());
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
}
#[test]
fn test_struct_generator_remove_middle_phrase() {
let mut ph: Generator<Point9NG> = Generator::new();
let syntax1: Syntax = r#"main = "1" 2 | 2 | 3"#.parse().unwrap();
let syntax2: Syntax = r#"main = A | "B" 3 | C"#.parse().unwrap();
let syntax3: Syntax = r#"main = あ | い | "う" 4"#.parse().unwrap();
let id1: SyntaxId = ph.add(syntax1).unwrap();
let id2: SyntaxId = ph.add(syntax2).unwrap();
let id3: SyntaxId = ph.add(syntax3).unwrap();
assert_eq!(id1, 1);
assert_eq!(id2, 2);
assert_eq!(id3, 3);
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 9);
assert_eq!(ph.weight(), 15.0);
assert_eq!(ph.number_of_syntax(), 3);
let _ = ph.remove(id2).unwrap();
assert!(ph.remove(id2).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 6);
assert_eq!(ph.weight(), 10.0);
assert_eq!(ph.number_of_syntax(), 2);
let _ = ph.remove(id1).unwrap();
assert!(ph.remove(id1).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 3);
assert_eq!(ph.weight(), 6.0);
assert_eq!(ph.number_of_syntax(), 1);
let _ = ph.remove(id3).unwrap();
assert!(ph.remove(id3).is_err());
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
}
#[test]
fn test_struct_generator_remove_and_add_phrase() {
let mut ph: Generator<Point9NG> = Generator::new();
let syntax1: Syntax = r#"main = 1"#.parse().unwrap();
let syntax2: Syntax = r#"main = A | B"#.parse().unwrap();
let syntax3: Syntax = r#"main = あ | い | う"#.parse().unwrap();
let id1: SyntaxId = ph.add(syntax1).unwrap();
let id2: SyntaxId = ph.add(syntax2).unwrap();
let id3: SyntaxId = ph.add(syntax3).unwrap();
assert_eq!(id1, 1);
assert_eq!(id2, 2);
assert_eq!(id3, 3);
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 6);
assert_eq!(ph.weight(), 6.0);
assert_eq!(ph.number_of_syntax(), 3);
let _ = ph.remove(id2).unwrap();
assert!(ph.remove(id2).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 4);
assert_eq!(ph.weight(), 4.0);
assert_eq!(ph.number_of_syntax(), 2);
let syntax4: Syntax = r#"main = 11 | 12 | 13 | 14"#.parse().unwrap();
let id4: SyntaxId = ph.add(syntax4).unwrap();
assert_eq!(id4, 4);
assert_eq!(ph.generate(), "14");
assert_eq!(ph.combination_number(), 8);
assert_eq!(ph.weight(), 8.0);
assert_eq!(ph.number_of_syntax(), 3);
let _ = ph.remove(id4).unwrap();
assert!(ph.remove(id4).is_err());
assert_eq!(ph.generate(), "う");
assert_eq!(ph.combination_number(), 4);
assert_eq!(ph.weight(), 4.0);
assert_eq!(ph.number_of_syntax(), 2);
let syntax5: Syntax = r#"main = AA | BB | CC | DD | EE"#.parse().unwrap();
let id5: SyntaxId = ph.add(syntax5).unwrap();
assert_eq!(id5, 4);
assert_eq!(ph.generate(), "EE");
assert_eq!(ph.combination_number(), 9);
assert_eq!(ph.weight(), 9.0);
assert_eq!(ph.number_of_syntax(), 3);
}
#[test]
fn test_struct_generator_clear() {
let mut ph: Generator<ZeroNG> = r#"
main = {= X | Y | Z } | {A} | {B}
A = A1 | A2 | A3
B = B1 | B2 | B3
"#
.parse()
.unwrap();
assert_eq!(ph.generate(), "X");
assert_eq!(ph.combination_number(), 9);
assert_eq!(ph.weight(), 9.0);
assert_eq!(ph.number_of_syntax(), 1);
ph.clear();
assert_eq!(ph.generate(), "nil");
assert_eq!(ph.combination_number(), 0);
assert_eq!(ph.weight(), 0.0);
assert_eq!(ph.number_of_syntax(), 0);
let syntax: Syntax = r#"
main = {= V | W } | {C}
C = C1 | C2 | C3
"#
.parse()
.unwrap();
let _ = ph.add(syntax).unwrap();
assert_eq!(ph.generate(), "V");
assert_eq!(ph.combination_number(), 5);
assert_eq!(ph.weight(), 5.0);
assert_eq!(ph.number_of_syntax(), 1);
}
#[test]
fn test_struct_generator_alternaitve_rng_and_subst() {
let mut ph: Generator<PosixRng, PlainSubst> = r#"
main = {= X | Y | Z } | {A} | {B}
A = A[1] | A[2] | A[3] ~ /[1]/[0]/g
B = B1 | B2 | B3
"#
.parse()
.unwrap();
let syntax: Syntax<PlainSubst> = r#"
main = {= V | W } | {C} ~ /C/D/g
C = C1 | C2 | C3
"#
.parse()
.unwrap();
ph.add(syntax).unwrap();
let dist = TextDistribution::from([
("X".to_string(), 1.0 / 14.0),
("Y".to_string(), 1.0 / 14.0),
("Z".to_string(), 1.0 / 14.0),
("A[0]".to_string(), 1.0 / 14.0),
("A[2]".to_string(), 1.0 / 14.0),
("A[3]".to_string(), 1.0 / 14.0),
("B1".to_string(), 1.0 / 14.0),
("B2".to_string(), 1.0 / 14.0),
("B3".to_string(), 1.0 / 14.0),
("V".to_string(), 1.0 / 14.0),
("W".to_string(), 1.0 / 14.0),
("D1".to_string(), 1.0 / 14.0),
("D2".to_string(), 1.0 / 14.0),
("D3".to_string(), 1.0 / 14.0),
]);
assert!(check_distribution(&mut ph, 100000, &dist, 0.01));
assert_eq!(ph.combination_number(), 14);
assert_eq!(ph.weight(), 14.0);
assert_eq!(ph.number_of_syntax(), 2);
}