use crate::domain::Qualitative;
use crate::fuzzy::{Label, LabelMembership};
use crate::valuation::Linguistic;
use crate::Valuation;
use std::fmt::{Display, Formatter};
#[derive(Debug, PartialEq)]
pub struct Single<'domain, T: LabelMembership> {
domain: &'domain Qualitative<T>,
index: usize,
}
#[derive(Debug, PartialEq)]
pub enum SingleError<'domain, T: LabelMembership> {
InvalidIndex {
domain: &'domain Qualitative<T>,
index: usize,
},
InvalidName {
domain: &'domain Qualitative<T>,
name: String,
},
}
impl<'domain, T: LabelMembership> Display for SingleError<'domain, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use SingleError::*;
match &self {
InvalidIndex { domain, index } => {
write!(
f,
"Invalid label index {} (domain cardinality == {}).",
index,
domain.cardinality()
)
}
InvalidName { domain, name } => {
write!(
f,
"Invalid label name '{}' (domain labels are == {:?}).",
name,
domain.get_labels_names()
)
}
}
}
}
impl<'domain, T: LabelMembership> Linguistic for Single<'domain, T> {}
impl<'domain, T: LabelMembership> Valuation for Single<'domain, T> {}
impl<'domain, T: LabelMembership> Single<'domain, T> {
pub fn new_by_label_index(
domain: &'domain Qualitative<T>,
index: usize,
) -> Result<Self, SingleError<'domain, T>> {
use SingleError::*;
if index >= domain.cardinality() {
Err(InvalidIndex { domain, index })
} else {
Ok(Self { domain, index })
}
}
pub fn new_by_label_name(
domain: &'domain Qualitative<T>,
name: &str,
) -> Result<Self, SingleError<'domain, T>> {
use SingleError::*;
if let Some(index) = domain.label_index(name) {
Ok(Self { domain, index })
} else {
Err(InvalidName {
domain,
name: String::from(name),
})
}
}
pub fn index(&self) -> usize {
self.index
}
pub fn label(&self) -> &Label<T> {
self.domain.get_label_by_index(self.index).unwrap()
}
pub fn domain(&self) -> &'domain Qualitative<T> {
self.domain
}
pub fn neg(&self) -> Self {
Self {
domain: self.domain,
index: self.domain.cardinality() - self.index - 1,
}
}
}