/// common/graph.rs, BAYES STAR, (c) coppola.ai 2024 use super::{ interface::{PredictStatistics, TrainStatistics}, redis::{seq_get_all, seq_push, RedisManager}, resources::FactoryResources, }; use crate::{ common::{ interface::PropositionDB, redis::{set_add, set_members}, }, model::{ self, exponential::ExponentialModel, objects::{ Domain, Entity, Predicate, PredicateGroup, PredicateFactor, Proposition, PropositionGroup, }, choose::extract_existence_factor_for_proposition, }, print_blue, }; use redis::{Commands, Connection}; use serde::{Deserialize, Serialize}; use std::{cell::RefCell, error::Error, rc::Rc}; pub struct InferenceGraph { redis_connection: RefCell, } impl InferenceGraph { pub fn new_mutable(resources: &FactoryResources) -> Result, Box> { let redis_connection = resources.redis.get_connection()?; Ok(Box::new(InferenceGraph { redis_connection })) } pub fn new_shared(resources: &FactoryResources) -> Result, Box> { let redis_connection = resources.redis.get_connection()?; Ok(Rc::new(InferenceGraph { redis_connection })) } pub fn store_entity(&mut self, entity: &Entity) -> Result<(), Box> { trace!( "Storing entity in domain '{}': {}", entity.domain, entity.name ); // Logging set_add( &mut *self.redis_connection.borrow_mut(), &entity.domain.to_string(), &entity.name, )?; Ok(()) } pub fn get_entities_in_domain(&self, domain: &str) -> Result, Box> { trace!("Getting entities in domain '{}'", domain.clone()); // Logging let names: Vec = set_members(&mut *self.redis_connection.borrow_mut(), domain)?; Ok(names .into_iter() .map(|name| Entity { domain: Domain::from_str(domain).expect("Domain not recognized."), // Use the provided domain name, }) .collect()) } fn predicate_backward_set_name(predicate: &Predicate) -> String { format!("predicate_backward:{}", predicate.hash_string()) } fn implication_seq_name() -> String { "implications".to_string() } fn store_implication( &mut self, implication: &PredicateFactor, ) -> Result<(), Box> { let record = serialize_record(implication)?; set_add( &mut *self.redis_connection.borrow_mut(), &Self::implication_seq_name(), &record, )?; Ok(()) } pub fn ensure_existence_backlinks_for_proposition( &mut self, proposition: &Proposition, ) -> Result<(), Box> { let implication = extract_existence_factor_for_proposition(proposition)?; self.store_predicate_implication(&implication)?; Ok(()) } fn store_predicate_backward_link( &mut self, inference: &PredicateFactor, ) -> Result<(), Box> { let conclusion = &inference.conclusion; let record = serialize_record(inference)?; set_add( &mut *self.redis_connection.borrow_mut(), &Self::predicate_backward_set_name(conclusion), &record, )?; Ok(()) } pub fn store_predicate_implication( &mut self, implication: &PredicateFactor, ) -> Result<(), Box> { self.store_implication(implication)?; self.store_predicate_backward_link(implication)?; Ok(()) } pub fn get_all_implications(&self) -> Result, Box> { let set_members: Vec = set_members( &mut *self.redis_connection.borrow_mut(), &Self::implication_seq_name(), )?; set_members .into_iter() .map(|record| serde_json::from_str(&record).map_err(|e| Box::new(e) as Box)) .collect() } pub fn predicate_backward_links( &self, conclusion: &Predicate, ) -> Result, Box> { let set_members: Vec = set_members( &mut *self.redis_connection.borrow_mut(), &Self::predicate_backward_set_name(conclusion), )?; set_members .into_iter() .map(|record| serde_json::from_str(&record).map_err(|e| Box::new(e) as Box)) .collect() } } pub fn serialize_record(obj: &T) -> Result> where T: Serialize, { serde_json::to_string(obj).map_err(|e| Box::new(e) as Box) } fn deserialize_record<'a, T>(record: &'a str) -> Result> where T: Deserialize<'a>, { serde_json::from_str(record).map_err(|e| Box::new(e) as Box) }