use crate::clock::ClockTime;
use crate::confidence::Confidence;
use crate::symbol::SymbolId;
use crate::value::Value;
#[derive(Clone, Debug, PartialEq)]
pub struct Semantic {
pub s: SymbolId,
pub p: SymbolId,
pub o: Value,
pub source: SymbolId,
pub confidence: Confidence,
pub valid_at: ClockTime,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Episodic {
pub event_id: SymbolId,
pub kind: SymbolId,
pub participants: Vec<SymbolId>,
pub location: SymbolId,
pub at_time: ClockTime,
pub observed_at: ClockTime,
pub source: SymbolId,
pub confidence: Confidence,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Procedural {
pub rule_id: SymbolId,
pub trigger: Value,
pub action: Value,
pub precondition: Option<Value>,
pub scope: SymbolId,
pub source: SymbolId,
pub confidence: Confidence,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Inferential {
pub s: SymbolId,
pub p: SymbolId,
pub o: Value,
pub derived_from: Vec<SymbolId>,
pub method: SymbolId,
pub confidence: Confidence,
pub valid_at: ClockTime,
}
#[derive(Clone, Debug, PartialEq)]
pub enum MemoryKind {
Semantic(Semantic),
Episodic(Episodic),
Procedural(Procedural),
Inferential(Inferential),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum MemoryKindTag {
Semantic,
Episodic,
Procedural,
Inferential,
}
impl MemoryKind {
#[must_use]
pub const fn tag(&self) -> MemoryKindTag {
match self {
Self::Semantic(_) => MemoryKindTag::Semantic,
Self::Episodic(_) => MemoryKindTag::Episodic,
Self::Procedural(_) => MemoryKindTag::Procedural,
Self::Inferential(_) => MemoryKindTag::Inferential,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn clock(millis: u64) -> ClockTime {
ClockTime::try_from_millis(millis).expect("non-sentinel")
}
fn conf(raw: u16) -> Confidence {
Confidence::from_u16(raw)
}
#[test]
fn tag_reflects_variant() {
let sem = MemoryKind::Semantic(Semantic {
s: SymbolId::new(1),
p: SymbolId::new(2),
o: Value::String("x".into()),
source: SymbolId::new(3),
confidence: conf(62_258),
valid_at: clock(1_000),
});
assert_eq!(sem.tag(), MemoryKindTag::Semantic);
let epi = MemoryKind::Episodic(Episodic {
event_id: SymbolId::new(10),
kind: SymbolId::new(11),
participants: vec![SymbolId::new(12)],
location: SymbolId::new(13),
at_time: clock(1_000),
observed_at: clock(1_000),
source: SymbolId::new(14),
confidence: conf(u16::MAX),
});
assert_eq!(epi.tag(), MemoryKindTag::Episodic);
let pro = MemoryKind::Procedural(Procedural {
rule_id: SymbolId::new(20),
trigger: Value::String("agent about to write".into()),
action: Value::String("route via librarian".into()),
precondition: None,
scope: SymbolId::new(21),
source: SymbolId::new(22),
confidence: conf(u16::MAX),
});
assert_eq!(pro.tag(), MemoryKindTag::Procedural);
let inf = MemoryKind::Inferential(Inferential {
s: SymbolId::new(30),
p: SymbolId::new(31),
o: Value::Boolean(true),
derived_from: vec![SymbolId::new(32), SymbolId::new(33)],
method: SymbolId::new(34),
confidence: conf(50_000),
valid_at: clock(2_000),
});
assert_eq!(inf.tag(), MemoryKindTag::Inferential);
}
}