use std::cmp::Ordering;
pub type AtomId = &'static str;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Hyp(Vec<AtomId>);
impl Hyp {
pub fn new(atoms: Vec<AtomId>) -> Self {
Hyp(atoms)
}
pub fn unknown() -> Self {
Hyp(vec![])
}
pub fn compat(&self, other: &Hyp) -> bool {
self == other || self.is_unknown() || other.is_unknown()
}
pub fn meet(&self, other: &Hyp) -> Option<Hyp> {
if self == other {
return Some(self.clone());
}
if self.is_unknown() {
return Some(other.clone());
}
if other.is_unknown() {
return Some(self.clone());
}
None
}
fn is_unknown(&self) -> bool {
self.0.is_empty()
}
pub fn atoms(&self) -> &[AtomId] {
&self.0
}
}
impl PartialOrd for Hyp {
fn partial_cmp(&self, other: &Hyp) -> Option<Ordering> {
match (self, other) {
_ if self == other => Some(Ordering::Equal),
(_, _) if other.is_unknown() => Some(Ordering::Less),
(_, _) if self.is_unknown() => Some(Ordering::Greater),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_unknown_top_element() {
let unknown = Hyp::unknown();
let hyp = Hyp::new(vec!["diagnosis_a"]);
assert_eq!(hyp.partial_cmp(&unknown), Some(Ordering::Less));
assert_eq!(unknown.partial_cmp(&hyp), Some(Ordering::Greater));
}
#[test]
fn test_equal_hypotheses() {
let h1 = Hyp::new(vec!["diagnosis_a", "severity_high"]);
let h2 = Hyp::new(vec!["diagnosis_a", "severity_high"]);
assert_eq!(h1.partial_cmp(&h2), Some(Ordering::Equal));
assert!(h1.compat(&h2));
}
#[test]
fn test_incomparable_hypotheses() {
let h1 = Hyp::new(vec!["diagnosis_a"]);
let h2 = Hyp::new(vec!["diagnosis_b"]);
assert_eq!(h1.partial_cmp(&h2), None);
assert!(!h1.compat(&h2));
}
#[test]
fn test_compat_with_unknown() {
let unknown = Hyp::unknown();
let hyp = Hyp::new(vec!["diagnosis_a"]);
assert!(hyp.compat(&unknown));
assert!(unknown.compat(&hyp));
}
#[test]
fn test_meet_equal_hypotheses() {
let h1 = Hyp::new(vec!["diagnosis_a"]);
let h2 = Hyp::new(vec!["diagnosis_a"]);
assert_eq!(h1.meet(&h2), Some(h1.clone()));
}
#[test]
fn test_meet_with_unknown() {
let unknown = Hyp::unknown();
let hyp = Hyp::new(vec!["diagnosis_a"]);
assert_eq!(hyp.meet(&unknown), Some(hyp.clone()));
assert_eq!(unknown.meet(&hyp), Some(hyp.clone()));
}
#[test]
fn test_meet_incomparable_none() {
let h1 = Hyp::new(vec!["diagnosis_a"]);
let h2 = Hyp::new(vec!["diagnosis_b"]);
assert_eq!(h1.meet(&h2), None);
}
}