use crate::{
AllIntervalReport, CombinatorialPartner, DerivationReport, OrderedIntervalString, RowFamilySet,
RowOperation, SegmentInvariant, ToneRow, analyze_all_interval, analyze_derivation,
analyze_invariance,
};
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct RowClassAlias {
pub operation: RowOperation,
pub distinct_form_index: usize,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FormEquivalence {
pub distinct_form_index: usize,
pub row: ToneRow,
pub operations: Vec<RowOperation>,
pub invariant: SegmentInvariant,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RowClassReport {
pub row: ToneRow,
pub ordered_intervals: OrderedIntervalString,
pub derivation: DerivationReport,
pub all_interval: AllIntervalReport,
pub combinatoriality: Vec<CombinatorialPartner>,
pub aliases: Vec<RowClassAlias>,
pub distinct_forms: Vec<ToneRow>,
pub stabilizers: Vec<RowOperation>,
pub form_equivalences: Vec<FormEquivalence>,
}
pub fn analyze_row_class(row: &ToneRow) -> RowClassReport {
let family = RowFamilySet::of(row);
let aliases = family
.aliases()
.iter()
.map(|alias| RowClassAlias {
operation: alias.operation,
distinct_form_index: alias.distinct_form_index(),
})
.collect::<Vec<_>>();
let distinct_forms = family.distinct_forms().to_vec();
let stabilizers = family
.aliases()
.iter()
.filter(|alias| alias.form.row() == row)
.map(|alias| alias.operation)
.collect::<Vec<_>>();
let left = row
.indexed_segment(&(0..row.classes().len()).collect::<Vec<_>>())
.expect("full-row indexed segment is valid");
let form_equivalences = distinct_forms
.iter()
.enumerate()
.map(|(distinct_form_index, form)| {
let right = form
.indexed_segment(&(0..form.classes().len()).collect::<Vec<_>>())
.expect("full-row indexed segment is valid");
let operations = family
.aliases_for_distinct_form(distinct_form_index)
.map(|alias| alias.operation)
.collect::<Vec<_>>();
FormEquivalence {
distinct_form_index,
row: form.clone(),
operations,
invariant: analyze_invariance(&left, &right),
}
})
.collect();
RowClassReport {
row: row.clone(),
ordered_intervals: row.ordered_intervals(),
derivation: analyze_derivation(row),
all_interval: analyze_all_interval(row),
combinatoriality: crate::analyze_combinatoriality(row).partners,
aliases,
distinct_forms,
stabilizers,
form_equivalences,
}
}