use super::*;
use proptest::prelude::*;
use rug::Integer;
fn arb_letters(rank: i32, max_len: usize) -> impl Strategy<Value = Vec<i32>> {
proptest::collection::vec(prop_oneof![(1..=rank), (-rank..=-1)], 0..=max_len)
}
proptest! {
#[test]
fn free_reduction_is_idempotent(letters in arb_letters(4, 20)) {
let once = Word::from_letters(&letters).unwrap();
let twice = Word::from_letters(once.letters()).unwrap();
prop_assert_eq!(&once, &twice);
prop_assert!(once.len() <= letters.len());
for pair in once.letters().windows(2) {
prop_assert_ne!(pair[0], -pair[1]);
}
}
#[test]
fn inversion_is_an_involution_and_an_antihomomorphism(
u in arb_letters(3, 12),
v in arb_letters(3, 12),
) {
let u = Word::from_letters(&u).unwrap();
let v = Word::from_letters(&v).unwrap();
prop_assert_eq!(u.inverse().inverse(), u.clone());
prop_assert_eq!(u.times(&v).inverse(), v.inverse().times(&u.inverse()));
prop_assert_eq!(u.times(&u.inverse()), Word::identity());
prop_assert_eq!(u.times(&Word::identity()), u.clone());
}
#[test]
fn exponent_sums_are_additive(u in arb_letters(3, 10), v in arb_letters(3, 10)) {
let u = Word::from_letters(&u).unwrap();
let v = Word::from_letters(&v).unwrap();
let su = u.exponent_sums(3).unwrap();
let sv = v.exponent_sums(3).unwrap();
let suv = u.times(&v).exponent_sums(3).unwrap();
for i in 0..3 {
prop_assert_eq!(suv[i], su[i] + sv[i]);
}
}
#[test]
fn a_doubly_presented_cyclic_group_has_order_gcd(m in 1u32..=24, n in 1u32..=24) {
let g = FpGroup::from_strings(&["a"], &[&format!("a^{m}"), &format!("a^{n}")]).unwrap();
let expected = Integer::from(m).gcd(&Integer::from(n));
prop_assert_eq!(g.order().unwrap(), expected.clone());
prop_assert_eq!(
g.abelian_invariants().unwrap().order().unwrap(),
expected
);
}
#[test]
fn index_times_subgroup_order_is_the_group_order(
which in 0usize..2,
letters in arb_letters(2, 5),
) {
let (rels, order) = if which == 0 {
(vec!["a^2", "b^3", "(a*b)^3"], 12u32)
} else {
(vec!["a^2", "b^3", "(a*b)^4"], 24u32)
};
let g = FpGroup::from_strings(&["a", "b"], &rels).unwrap();
let h = vec![g.word(&letters).unwrap()];
let index = g.index(&h).unwrap();
prop_assert!(index >= 1 && index <= order as usize);
let sub = g.subgroup_presentation(&h).unwrap();
let sub_order = sub.presentation().order().unwrap();
prop_assert_eq!(
Integer::from(index) * sub_order,
Integer::from(order)
);
}
#[test]
fn the_permutation_representation_has_the_index_as_its_degree(
letters in arb_letters(2, 4),
) {
let g = FpGroup::from_strings(&["a", "b"], &["a^2", "b^3", "(a*b)^4"]).unwrap();
let h = vec![g.word(&letters).unwrap()];
let table = g.coset_table(&h).unwrap();
let perm = table.permutation_group().unwrap();
prop_assert_eq!(perm.degree(), table.index());
let order = perm.order().unwrap();
prop_assert_eq!(Integer::from(24) % order.clone(), Integer::from(0));
prop_assert!(order >= table.index());
}
}