Skip to main content

argumentation/aspic/
kb.rs

1//! Knowledge base: necessary and ordinary premises.
2
3use super::language::Literal;
4
5/// A premise in the knowledge base.
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub enum Premise {
8    /// Necessary premise (indefeasible): cannot be attacked.
9    Necessary(Literal),
10    /// Ordinary premise (defeasible): can be attacked by undermining.
11    Ordinary(Literal),
12}
13
14impl Premise {
15    /// The literal content of this premise.
16    pub fn literal(&self) -> &Literal {
17        match self {
18            Premise::Necessary(l) | Premise::Ordinary(l) => l,
19        }
20    }
21
22    /// Whether this premise can be attacked.
23    pub fn is_defeasible(&self) -> bool {
24        matches!(self, Premise::Ordinary(_))
25    }
26}
27
28/// The knowledge base.
29#[derive(Debug, Default, Clone)]
30pub struct KnowledgeBase {
31    premises: Vec<Premise>,
32}
33
34impl KnowledgeBase {
35    /// Create an empty knowledge base.
36    pub fn new() -> Self {
37        Self::default()
38    }
39
40    /// Add a necessary premise.
41    pub fn add_necessary(&mut self, l: Literal) {
42        self.premises.push(Premise::Necessary(l));
43    }
44
45    /// Add an ordinary premise.
46    pub fn add_ordinary(&mut self, l: Literal) {
47        self.premises.push(Premise::Ordinary(l));
48    }
49
50    /// Iterate over all premises.
51    pub fn premises(&self) -> &[Premise] {
52        &self.premises
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn kb_stores_both_types() {
62        let mut kb = KnowledgeBase::new();
63        kb.add_necessary(Literal::atom("p"));
64        kb.add_ordinary(Literal::atom("q"));
65        assert_eq!(kb.premises().len(), 2);
66        assert!(!kb.premises()[0].is_defeasible());
67        assert!(kb.premises()[1].is_defeasible());
68    }
69}