use std::collections::BTreeSet;
use crate::ids::SourceId;
use crate::model::{AuthorityLevel, Confidence, FactEvent, FactEventKind};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EpistemicPolicy {
pub distrusted_sources: BTreeSet<SourceId>,
pub authority_floor: AuthorityLevel,
pub confidence_floor: Confidence,
}
impl EpistemicPolicy {
#[must_use]
pub const fn identity() -> Self {
Self {
distrusted_sources: BTreeSet::new(),
authority_floor: AuthorityLevel::Unknown,
confidence_floor: Confidence::ZERO,
}
}
#[must_use]
pub fn is_identity(&self) -> bool {
self.distrusted_sources.is_empty()
&& self.authority_floor == AuthorityLevel::Unknown
&& self.confidence_floor == Confidence::ZERO
}
#[must_use]
pub fn admits(&self, event: &FactEvent) -> bool {
if self.distrusted_sources.contains(&event.provenance.source) {
return false;
}
if affects_belief(&event.kind)
&& (event.authority.level < self.authority_floor
|| event.confidence < self.confidence_floor)
{
return false;
}
true
}
}
impl Default for EpistemicPolicy {
fn default() -> Self {
Self::identity()
}
}
const fn affects_belief(kind: &FactEventKind) -> bool {
matches!(
kind,
FactEventKind::Asserted
| FactEventKind::Reinforced { .. }
| FactEventKind::Contradicted { .. }
| FactEventKind::Superseded { .. }
)
}
#[cfg(test)]
mod tests {
use super::EpistemicPolicy;
use crate::ids::SourceId;
use crate::model::{AuthorityLevel, Confidence};
#[test]
fn identity_is_identity() {
assert!(EpistemicPolicy::identity().is_identity());
assert!(EpistemicPolicy::default().is_identity());
}
#[test]
fn a_distrusted_source_breaks_identity() {
let mut policy = EpistemicPolicy::identity();
policy
.distrusted_sources
.insert(SourceId::new("source:web-scrape").expect("valid source"));
assert!(!policy.is_identity());
}
#[test]
fn a_raised_authority_floor_breaks_identity() {
let policy = EpistemicPolicy {
authority_floor: AuthorityLevel::High,
..EpistemicPolicy::identity()
};
assert!(!policy.is_identity());
}
#[test]
fn a_raised_confidence_floor_breaks_identity() {
let policy = EpistemicPolicy {
confidence_floor: Confidence::from_millis(500).expect("confidence"),
..EpistemicPolicy::identity()
};
assert!(!policy.is_identity());
}
}