use crate::{AssumptionError, DescriptionValue, Identifiable, NumericalValue, PropagatingEffect};
pub trait Assumable: Identifiable {
fn description(&self) -> DescriptionValue;
fn assumption_tested(&self) -> bool;
fn assumption_valid(&self) -> bool;
fn verify_assumption(&self, data: &[PropagatingEffect<f64>]) -> Result<bool, AssumptionError>;
}
pub trait AssumableReasoning<T>
where
T: Assumable,
{
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn get_all_items(&self) -> Vec<&T>;
fn all_assumptions_tested(&self) -> bool {
for elem in self.get_all_items() {
if !elem.assumption_tested() {
return false;
}
}
true
}
fn all_assumptions_valid(&self) -> bool {
for a in self.get_all_items() {
if !a.assumption_valid() {
return false;
}
}
true
}
fn number_assumption_valid(&self) -> NumericalValue {
self.get_all_items()
.iter()
.filter(|a| a.assumption_valid())
.count() as NumericalValue
}
fn percent_assumption_valid(&self) -> Result<NumericalValue, AssumptionError> {
if self.is_empty() {
return Err(AssumptionError::EvaluationFailed(
"Cannot calculate percentage with zero assumptions".to_string(),
));
}
let percentage = (self.number_assumption_valid() / self.len() as NumericalValue) * 100.0;
Ok(percentage)
}
fn verify_all_assumptions(
&self,
data: &[PropagatingEffect<f64>],
) -> Result<(), AssumptionError> {
for a in self.get_all_items() {
let _ = a.verify_assumption(data)?;
}
Ok(())
}
fn get_all_invalid_assumptions(&self) -> Vec<&T> {
self.get_all_items()
.into_iter()
.filter(|a| !a.assumption_valid())
.collect()
}
fn get_all_valid_assumptions(&self) -> Vec<&T> {
self.get_all_items()
.into_iter()
.filter(|a| a.assumption_valid())
.collect()
}
fn get_all_tested_assumptions(&self) -> Vec<&T> {
self.get_all_items()
.into_iter()
.filter(|a| a.assumption_tested())
.collect()
}
fn get_all_untested_assumptions(&self) -> Vec<&T> {
self.get_all_items()
.into_iter()
.filter(|a| !a.assumption_tested())
.collect()
}
}