eryon-mem 0.0.4

this crate implements the memory-related aspects of the eryon framework
/*
    Appellation: memory <module>
    Contrib: @FL03
*/
use super::types::{IndexMap, PropertiesMap};
use super::{MemoryIndex, MemoryState};
use crate::features::{FeaturePattern, FeatureRelationship, PersistentFeature};
use eryon::LearnedRule;
use std::collections::hash_map::{self, HashMap};

/// Memory system based on persistent homology
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
    feature = "serde",
    derive(serde_derive::Deserialize, serde_derive::Serialize)
)]
pub struct TopoLedger<T = f32> {
    /// Collection of persistent features
    pub(crate) features: Vec<PersistentFeature<T>>,
    /// the indexing structure for the memory
    pub(crate) index: MemoryIndex,
    /// Relationships between features
    pub(crate) relationships: Vec<FeatureRelationship<T>>,
    /// a cache of learned rules for the driver
    pub(crate) rulespace: Vec<LearnedRule<T, usize, usize>>,
    /// Recognized patterns
    pub(crate) patterns: Vec<FeaturePattern<T>>,
    /// Properties of the memory store
    pub(crate) properties: HashMap<String, String>,
    pub(crate) state: MemoryState,
}

impl<T> TopoLedger<T> {
    /// initializes a new [`TopologicalMemory`] with default values.
    pub fn new() -> Self {
        Self {
            features: Vec::new(),
            index: MemoryIndex::new(),
            patterns: Vec::new(),
            properties: PropertiesMap::new(),
            relationships: Vec::new(),
            rulespace: Vec::new(),
            state: MemoryState::new(),
        }
    }
    /// returns a reference to the features of the system
    pub const fn features(&self) -> &Vec<PersistentFeature<T>> {
        &self.features
    }
    /// returns a mutable reference to the features of the system
    pub const fn features_mut(&mut self) -> &mut Vec<PersistentFeature<T>> {
        &mut self.features
    }
    /// returns an immutable reference to the memory index
    pub const fn index(&self) -> &MemoryIndex {
        &self.index
    }
    /// returns a mutable reference to the memory index
    pub const fn index_mut(&mut self) -> &mut MemoryIndex {
        &mut self.index
    }
    /// returns an immutable reference to the memory patterns
    pub const fn patterns(&self) -> &Vec<FeaturePattern<T>> {
        &self.patterns
    }
    /// returns a mutable reference to the memory patterns
    pub const fn patterns_mut(&mut self) -> &mut Vec<FeaturePattern<T>> {
        &mut self.patterns
    }
    /// returns an immutable reference to the properties of the memory store
    pub const fn properties(&self) -> &HashMap<String, String> {
        &self.properties
    }
    /// returns a mutable reference to the properties of the memory store
    pub const fn properties_mut(&mut self) -> &mut HashMap<String, String> {
        &mut self.properties
    }
    /// returns a reference to the relationships of the system
    pub const fn relationships(&self) -> &Vec<FeatureRelationship<T>> {
        &self.relationships
    }
    /// returns a mutable reference to the relationships of the system
    pub const fn relationships_mut(&mut self) -> &mut Vec<FeatureRelationship<T>> {
        &mut self.relationships
    }
    /// returns an immutable reference to the learned rulespace
    pub const fn rulespace(&self) -> &Vec<LearnedRule<T>> {
        &self.rulespace
    }
    /// returns a mutable reference to the memoized rulespace
    pub const fn rulespace_mut(&mut self) -> &mut Vec<LearnedRule<T>> {
        &mut self.rulespace
    }
    /// returns a copy of the current memory state
    pub const fn state(&self) -> MemoryState {
        self.state
    }
    /// returns a mutable reference to the current memory state
    pub const fn state_mut(&mut self) -> &mut MemoryState {
        &mut self.state
    }
    /// returns an immutable reference to the content index
    pub const fn content_index(&self) -> &IndexMap<Vec<usize>, usize> {
        self.index().content_index()
    }
    /// returns a mutable reference to the content index
    pub const fn content_index_mut(&mut self) -> &mut IndexMap<Vec<usize>, usize> {
        self.index_mut().content_index_mut()
    }
    /// returns an immutable reference to the dimensional index
    pub const fn dimension_index(&self) -> &IndexMap<usize, usize> {
        self.index().dimension_index()
    }
    /// returns a mutable reference to the dimensional index
    pub const fn dimension_index_mut(&mut self) -> &mut IndexMap<usize, usize> {
        self.index_mut().dimension_index_mut()
    }
    /// returns an immutable reference to the importance index
    pub const fn importance_index(&self) -> &IndexMap<usize, usize> {
        self.index().importance_index()
    }
    /// returns a mutable reference to the importance index
    pub const fn importance_index_mut(&mut self) -> &mut IndexMap<usize, usize> {
        self.index_mut().importance_index_mut()
    }
    /// returns the total number of features
    #[inline]
    pub fn count_features(&self) -> usize {
        self.features().len()
    }
    /// returns the number of patterns
    #[inline]
    pub fn count_patterns(&self) -> usize {
        self.patterns().len()
    }
    /// returns the number of relationships
    #[inline]
    pub fn count_relationships(&self) -> usize {
        self.relationships().len()
    }
    /// returns the value for the given property (if any);
    pub fn get_property<Q>(&self, key: &Q) -> Option<&String>
    where
        Q: Eq + core::hash::Hash + ?Sized,
        String: core::borrow::Borrow<Q>,
    {
        self.properties().get(key)
    }
    /// Get a float property, parsing from string
    pub fn get_property_float<Q>(&self, key: &Q) -> Option<T>
    where
        Q: Eq + core::hash::Hash + ?Sized,
        T: num_traits::Num,
        String: core::borrow::Borrow<Q>,
    {
        self.get_property(key)
            .and_then(|v| T::from_str_radix(v, 10).ok())
    }
    /// returns a copy of the internal time
    pub const fn current_epoch(&self) -> usize {
        self.state().epoch()
    }
    /// increment the epoch returing the previous value
    pub fn next_epoch(&mut self) -> usize {
        self.state_mut().next_epoch()
    }
    /// increments the current feature index and returns the old value
    pub fn next_feature_id(&mut self) -> usize {
        self.state_mut().next_feature_id()
    }
    /// increments the current pattern index and returns the old value
    pub fn next_pattern_id(&mut self) -> usize {
        self.state_mut().next_pattern_id()
    }
    /// returns the entry of a property in the memory store with the given key
    pub fn property<K: ToString>(&mut self, key: K) -> hash_map::Entry<'_, String, String> {
        self.properties_mut().entry(key.to_string())
    }
    /// Set a property in the memory store
    pub fn set_property<V>(&mut self, key: &str, value: V)
    where
        V: ToString,
    {
        self.properties_mut()
            .insert(key.to_string(), value.to_string());
    }
}

impl<T> Default for TopoLedger<T> {
    fn default() -> Self {
        Self::new()
    }
}