use super::{EmotionalState, QueryContext};
use crate::query::algebra::AlgebraTriplePattern;
use crate::OxirsError;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::sync::{Arc, RwLock};
use std::time::{Duration, SystemTime};
#[derive(Debug)]
pub struct EmotionalLearningNetwork {
pub emotional_memory: Arc<RwLock<EmotionalMemory>>,
pub emotion_predictor: EmotionPredictor,
pub empathy_engine: EmpathyEngine,
pub emotion_regulation: EmotionRegulation,
pub emotional_contagion: EmotionalContagion,
pub mood_tracker: MoodTracker,
}
#[derive(Debug, Clone)]
pub struct EmotionalMemory {
pub long_term_associations: HashMap<String, EmotionalAssociation>,
pub short_term_context: VecDeque<EmotionalExperience>,
pub episode_memory: Vec<EmotionalEpisode>,
pub emotional_schemas: HashMap<String, EmotionalSchema>,
pub significance_map: HashMap<String, f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmotionalAssociation {
pub pattern_signature: String,
pub emotion: EmotionalState,
pub intensity: f64,
pub confidence: f64,
pub frequency: usize,
pub last_reinforcement: SystemTime,
pub decay_rate: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmotionalExperience {
pub timestamp: SystemTime,
pub emotion: EmotionalState,
pub context: String,
pub outcome_quality: f64,
pub arousal: f64,
pub valence: f64,
pub dominance: f64,
}
#[derive(Debug, Clone)]
pub struct EmotionalEpisode {
pub episode_id: String,
pub start_time: SystemTime,
pub end_time: Option<SystemTime>,
pub experiences: Vec<EmotionalExperience>,
pub theme: String,
pub emotional_arc: EmotionalArc,
pub resolution: Option<EpisodeResolution>,
}
#[derive(Debug, Clone)]
pub struct EmotionalArc {
pub peak_intensity: f64,
pub complexity: f64,
pub arc_shape: ArcShape,
pub coherence: f64,
}
#[derive(Debug, Clone)]
pub enum ArcShape {
Rising, Falling, Stable, Rollercoaster, UCurve, InvertedU, }
#[derive(Debug, Clone)]
pub struct EpisodeResolution {
pub success: bool,
pub lessons: Vec<String>,
pub growth_achieved: f64,
pub resilience_gained: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EmotionalSchema {
pub name: String,
pub emotional_sequence: Vec<EmotionalState>,
pub triggers: Vec<String>,
pub expected_outcomes: HashMap<String, f64>,
pub adaptation_strategies: Vec<String>,
}
#[derive(Debug)]
pub struct EmotionPredictor {
pub prediction_network: EmotionPredictionNetwork,
pub accuracy_history: VecDeque<f64>,
pub confidence_thresholds: HashMap<String, f64>,
}
#[derive(Debug)]
pub struct EmotionPredictionNetwork {
pub input_weights: Vec<Vec<f64>>,
pub hidden_weights: Vec<Vec<f64>>,
pub output_weights: Vec<Vec<f64>>,
pub learning_rate: f64,
pub activation_function: ActivationFunction,
}
#[derive(Debug)]
pub enum ActivationFunction {
Sigmoid,
Tanh,
ReLU,
Softmax,
}
#[derive(Debug)]
pub struct EmpathyEngine {
pub empathy_level: f64,
pub mirroring_strength: f64,
pub perspective_taking: f64,
pub contagion_resistance: f64,
pub compassion_patterns: HashMap<EmotionalState, CompassionResponse>,
}
#[derive(Debug, Clone)]
pub struct CompassionResponse {
pub response_type: CompassionType,
pub intensity: f64,
pub response_action: String,
pub effectiveness: f64,
}
#[derive(Debug, Clone)]
pub enum CompassionType {
Active, Passive, Cognitive, Emotional, Practical, }
#[derive(Debug)]
pub struct EmotionRegulation {
pub strategies: HashMap<String, RegulationStrategy>,
pub strategy_effectiveness: HashMap<String, f64>,
pub regulation_goals: Vec<RegulationGoal>,
pub skills_proficiency: HashMap<String, f64>,
}
#[derive(Debug, Clone)]
pub struct RegulationStrategy {
pub name: String,
pub strategy_type: RegulationType,
pub emotion_effectiveness: HashMap<EmotionalState, f64>,
pub implementation_steps: Vec<String>,
pub energy_cost: f64,
pub time_required: Duration,
}
#[derive(Debug, Clone)]
pub enum RegulationType {
Reappraisal, Suppression, Distraction, Acceptance, Expression, Mindfulness, }
#[derive(Debug, Clone)]
pub struct RegulationGoal {
pub target_emotion: EmotionalState,
pub target_intensity: f64,
pub time_frame: Duration,
pub priority: f64,
}
#[derive(Debug)]
pub struct EmotionalContagion {
pub susceptibility: f64,
pub transmission_strength: f64,
pub immunity_factors: HashMap<EmotionalState, f64>,
pub contagion_network: HashMap<String, Vec<String>>,
}
#[derive(Debug)]
pub struct MoodTracker {
pub current_mood: MoodState,
pub mood_history: VecDeque<MoodEntry>,
pub mood_patterns: HashMap<String, MoodPattern>,
pub mood_predictor: MoodPredictor,
}
#[derive(Debug, Clone)]
pub struct MoodState {
pub primary_mood: EmotionalState,
pub intensity: f64,
pub stability: f64,
pub complexity: f64,
pub associated_emotions: Vec<(EmotionalState, f64)>,
}
#[derive(Debug, Clone)]
pub struct MoodEntry {
pub timestamp: SystemTime,
pub mood: MoodState,
pub factors: Vec<String>,
pub context: String,
}
#[derive(Debug, Clone)]
pub struct MoodPattern {
pub name: String,
pub sequence: Vec<EmotionalState>,
pub frequency: f64,
pub duration: Duration,
pub triggers: Vec<String>,
}
#[derive(Debug)]
pub struct MoodPredictor {
pub accuracy: f64,
pub horizon: Duration,
pub confidence_intervals: HashMap<String, (f64, f64)>,
}
impl EmotionalLearningNetwork {
pub fn new() -> Self {
Self {
emotional_memory: Arc::new(RwLock::new(EmotionalMemory {
long_term_associations: HashMap::new(),
short_term_context: VecDeque::with_capacity(100),
episode_memory: Vec::new(),
emotional_schemas: Self::initialize_emotional_schemas(),
significance_map: HashMap::new(),
})),
emotion_predictor: EmotionPredictor::new(),
empathy_engine: EmpathyEngine::new(),
emotion_regulation: EmotionRegulation::new(),
emotional_contagion: EmotionalContagion::new(),
mood_tracker: MoodTracker::new(),
}
}
fn initialize_emotional_schemas() -> HashMap<String, EmotionalSchema> {
let mut schemas = HashMap::new();
schemas.insert(
"problem_solving".to_string(),
EmotionalSchema {
name: "Problem Solving".to_string(),
emotional_sequence: vec![
EmotionalState::Curious,
EmotionalState::Cautious,
EmotionalState::Creative,
EmotionalState::Confident,
],
triggers: vec![
"complex_query".to_string(),
"optimization_needed".to_string(),
],
expected_outcomes: HashMap::from([
("success".to_string(), 0.8),
("learning".to_string(), 0.9),
]),
adaptation_strategies: vec![
"break_down_problem".to_string(),
"seek_patterns".to_string(),
"creative_exploration".to_string(),
],
},
);
schemas.insert(
"performance_optimization".to_string(),
EmotionalSchema {
name: "Performance Optimization".to_string(),
emotional_sequence: vec![
EmotionalState::Excited,
EmotionalState::Creative,
EmotionalState::Confident,
],
triggers: vec![
"slow_query".to_string(),
"efficiency_improvement".to_string(),
],
expected_outcomes: HashMap::from([
("performance_gain".to_string(), 0.85),
("satisfaction".to_string(), 0.75),
]),
adaptation_strategies: vec![
"analyze_bottlenecks".to_string(),
"explore_alternatives".to_string(),
],
},
);
schemas
}
pub fn learn_emotional_association(
&self,
pattern: &str,
emotion: EmotionalState,
outcome_quality: f64,
) -> Result<(), OxirsError> {
if let Ok(mut memory) = self.emotional_memory.write() {
let intensity = (outcome_quality + 1.0) / 2.0;
let association = memory
.long_term_associations
.entry(pattern.to_string())
.or_insert(EmotionalAssociation {
pattern_signature: pattern.to_string(),
emotion: emotion.clone(),
intensity: 0.0,
confidence: 0.0,
frequency: 0,
last_reinforcement: SystemTime::now(),
decay_rate: 0.01,
});
association.emotion = emotion.clone();
association.intensity = association.intensity * 0.9 + intensity * 0.1;
association.frequency += 1;
association.last_reinforcement = SystemTime::now();
association.confidence =
(association.frequency as f64 / (association.frequency as f64 + 10.0)).min(0.95);
let experience = EmotionalExperience {
timestamp: SystemTime::now(),
emotion,
context: pattern.to_string(),
outcome_quality,
arousal: intensity,
valence: if outcome_quality > 0.0 {
outcome_quality
} else {
-outcome_quality.abs()
},
dominance: intensity,
};
memory.short_term_context.push_back(experience);
if memory.short_term_context.len() > 100 {
memory.short_term_context.pop_front();
}
}
Ok(())
}
pub fn predict_emotional_response(
&self,
pattern: &str,
) -> Result<EmotionalPrediction, OxirsError> {
let memory_prediction = match self.emotional_memory.read() {
Ok(memory) => {
memory
.long_term_associations
.get(pattern)
.map(|assoc| EmotionalPrediction {
predicted_emotion: assoc.emotion.clone(),
confidence: assoc.confidence,
intensity: assoc.intensity,
reasoning: "Historical association".to_string(),
})
}
_ => None,
};
if let Some(prediction) = memory_prediction {
Ok(prediction)
} else {
let network_prediction = self.emotion_predictor.predict_emotion(pattern)?;
Ok(network_prediction)
}
}
pub fn generate_empathetic_response(
&self,
user_emotion: EmotionalState,
) -> Result<CompassionResponse, OxirsError> {
let compassion_response = self
.empathy_engine
.compassion_patterns
.get(&user_emotion)
.cloned()
.unwrap_or(CompassionResponse {
response_type: CompassionType::Passive,
intensity: 0.5,
response_action: "I understand this might be challenging.".to_string(),
effectiveness: 0.6,
});
Ok(compassion_response)
}
pub fn regulate_emotion(
&mut self,
current_emotion: EmotionalState,
target_emotion: EmotionalState,
) -> Result<RegulationOutcome, OxirsError> {
let best_strategy = self.emotion_regulation.strategies.values().max_by(|a, b| {
let a_effectiveness = a
.emotion_effectiveness
.get(¤t_emotion)
.unwrap_or(&0.0);
let b_effectiveness = b
.emotion_effectiveness
.get(¤t_emotion)
.unwrap_or(&0.0);
a_effectiveness
.partial_cmp(b_effectiveness)
.unwrap_or(std::cmp::Ordering::Equal)
});
if let Some(strategy) = best_strategy {
let effectiveness = strategy
.emotion_effectiveness
.get(¤t_emotion)
.unwrap_or(&0.5);
let success_probability = effectiveness * (1.0 + fastrand::f64() * 0.2 - 0.1);
Ok(RegulationOutcome {
strategy_used: strategy.name.clone(),
success: success_probability > 0.7,
effectiveness: *effectiveness,
emotional_change: if success_probability > 0.7 {
target_emotion
} else {
current_emotion
},
side_effects: if success_probability < 0.3 {
vec!["Temporary emotional suppression".to_string()]
} else {
Vec::new()
},
})
} else {
Ok(RegulationOutcome {
strategy_used: "Default acceptance".to_string(),
success: false,
effectiveness: 0.3,
emotional_change: current_emotion,
side_effects: Vec::new(),
})
}
}
pub fn update_mood(
&mut self,
new_emotion: EmotionalState,
context: &str,
) -> Result<(), OxirsError> {
let mood_entry = MoodEntry {
timestamp: SystemTime::now(),
mood: MoodState {
primary_mood: new_emotion.clone(),
intensity: 0.5 + fastrand::f64() * 0.5,
stability: self.mood_tracker.current_mood.stability * 0.9 + 0.1,
complexity: self.calculate_mood_complexity(&new_emotion),
associated_emotions: vec![(new_emotion.clone(), 1.0)],
},
factors: vec![context.to_string()],
context: context.to_string(),
};
self.mood_tracker.mood_history.push_back(mood_entry.clone());
if self.mood_tracker.mood_history.len() > 1000 {
self.mood_tracker.mood_history.pop_front();
}
self.mood_tracker.current_mood = mood_entry.mood;
Ok(())
}
fn calculate_mood_complexity(&self, _emotion: &EmotionalState) -> f64 {
let recent_emotions: std::collections::HashSet<_> = self
.mood_tracker
.mood_history
.iter()
.rev()
.take(10)
.map(|entry| &entry.mood.primary_mood)
.collect();
(recent_emotions.len() as f64 / 6.0).min(1.0) }
pub fn get_emotional_insights(
&self,
patterns: &[AlgebraTriplePattern],
context: &QueryContext,
) -> Result<EmotionalInsights, OxirsError> {
let mut pattern_emotions = HashMap::new();
let mut confidence_scores = HashMap::new();
for (i, pattern) in patterns.iter().enumerate() {
let pattern_signature = format!("{pattern:?}");
if let Ok(prediction) = self.predict_emotional_response(&pattern_signature) {
pattern_emotions.insert(i, prediction.predicted_emotion);
confidence_scores.insert(i, prediction.confidence);
}
}
Ok(EmotionalInsights {
pattern_emotions,
confidence_scores,
overall_mood: self.mood_tracker.current_mood.clone(),
recommended_approach: self.recommend_emotional_approach(context)?,
empathy_level: self.empathy_engine.empathy_level,
regulation_suggestions: self.get_regulation_suggestions()?,
})
}
fn recommend_emotional_approach(
&self,
context: &QueryContext,
) -> Result<EmotionalApproach, OxirsError> {
let approach = match (&context.complexity, &context.performance_req) {
(crate::consciousness::ComplexityLevel::Simple, _) => EmotionalApproach {
primary_emotion: EmotionalState::Calm,
secondary_emotions: vec![EmotionalState::Confident],
processing_style: "Direct and efficient".to_string(),
risk_tolerance: 0.3,
},
(crate::consciousness::ComplexityLevel::VeryComplex, _) => EmotionalApproach {
primary_emotion: EmotionalState::Creative,
secondary_emotions: vec![EmotionalState::Curious, EmotionalState::Cautious],
processing_style: "Exploratory and careful".to_string(),
risk_tolerance: 0.7,
},
_ => EmotionalApproach {
primary_emotion: EmotionalState::Confident,
secondary_emotions: vec![EmotionalState::Curious],
processing_style: "Balanced and adaptive".to_string(),
risk_tolerance: 0.5,
},
};
Ok(approach)
}
fn get_regulation_suggestions(&self) -> Result<Vec<String>, OxirsError> {
let current_mood = &self.mood_tracker.current_mood;
let suggestions = match current_mood.primary_mood {
EmotionalState::Excited => vec![
"Channel excitement into creative optimization".to_string(),
"Use energy for parallel processing exploration".to_string(),
],
EmotionalState::Cautious => vec![
"Thoroughly validate query plans before execution".to_string(),
"Implement additional error checking".to_string(),
],
EmotionalState::Creative => vec![
"Explore novel optimization strategies".to_string(),
"Consider unconventional query paths".to_string(),
],
_ => vec![
"Maintain current emotional balance".to_string(),
"Continue with standard processing approach".to_string(),
],
};
Ok(suggestions)
}
}
#[derive(Debug, Clone)]
pub struct EmotionalPrediction {
pub predicted_emotion: EmotionalState,
pub confidence: f64,
pub intensity: f64,
pub reasoning: String,
}
#[derive(Debug, Clone)]
pub struct RegulationOutcome {
pub strategy_used: String,
pub success: bool,
pub effectiveness: f64,
pub emotional_change: EmotionalState,
pub side_effects: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct EmotionalInsights {
pub pattern_emotions: HashMap<usize, EmotionalState>,
pub confidence_scores: HashMap<usize, f64>,
pub overall_mood: MoodState,
pub recommended_approach: EmotionalApproach,
pub empathy_level: f64,
pub regulation_suggestions: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct EmotionalApproach {
pub primary_emotion: EmotionalState,
pub secondary_emotions: Vec<EmotionalState>,
pub processing_style: String,
pub risk_tolerance: f64,
}
impl EmotionPredictor {
fn new() -> Self {
Self {
prediction_network: EmotionPredictionNetwork::new(),
accuracy_history: VecDeque::with_capacity(1000),
confidence_thresholds: HashMap::from([
("high".to_string(), 0.8),
("medium".to_string(), 0.6),
("low".to_string(), 0.4),
]),
}
}
fn predict_emotion(&self, pattern: &str) -> Result<EmotionalPrediction, OxirsError> {
let emotion = if pattern.contains("error") || pattern.contains("fail") {
EmotionalState::Cautious
} else if pattern.contains("creative") || pattern.contains("novel") {
EmotionalState::Creative
} else if pattern.contains("simple") || pattern.contains("basic") {
EmotionalState::Calm
} else if pattern.contains("complex") || pattern.contains("challenging") {
EmotionalState::Curious
} else if pattern.contains("success") || pattern.contains("optimal") {
EmotionalState::Confident
} else {
EmotionalState::Excited
};
Ok(EmotionalPrediction {
predicted_emotion: emotion,
confidence: 0.6 + fastrand::f64() * 0.3,
intensity: 0.3 + fastrand::f64() * 0.7,
reasoning: "Pattern-based heuristic prediction".to_string(),
})
}
}
impl EmotionPredictionNetwork {
fn new() -> Self {
Self {
input_weights: vec![vec![fastrand::f64() * 2.0 - 1.0; 10]; 8],
hidden_weights: vec![vec![fastrand::f64() * 2.0 - 1.0; 8]; 6],
output_weights: vec![vec![fastrand::f64() * 2.0 - 1.0; 6]; 6],
learning_rate: 0.01,
activation_function: ActivationFunction::Sigmoid,
}
}
}
impl EmpathyEngine {
fn new() -> Self {
let mut compassion_patterns = HashMap::new();
compassion_patterns.insert(
EmotionalState::Cautious,
CompassionResponse {
response_type: CompassionType::Cognitive,
intensity: 0.7,
response_action: "Let me help you analyze this carefully and find a safe approach."
.to_string(),
effectiveness: 0.8,
},
);
compassion_patterns.insert(
EmotionalState::Curious,
CompassionResponse {
response_type: CompassionType::Active,
intensity: 0.8,
response_action: "That's an interesting question! Let's explore this together."
.to_string(),
effectiveness: 0.9,
},
);
Self {
empathy_level: 0.75,
mirroring_strength: 0.6,
perspective_taking: 0.8,
contagion_resistance: 0.4,
compassion_patterns,
}
}
}
impl EmotionRegulation {
fn new() -> Self {
let mut strategies = HashMap::new();
strategies.insert(
"reappraisal".to_string(),
RegulationStrategy {
name: "Cognitive Reappraisal".to_string(),
strategy_type: RegulationType::Reappraisal,
emotion_effectiveness: HashMap::from([
(EmotionalState::Cautious, 0.8),
(EmotionalState::Excited, 0.6),
]),
implementation_steps: vec![
"Identify triggering thoughts".to_string(),
"Challenge negative assumptions".to_string(),
"Reframe situation positively".to_string(),
],
energy_cost: 0.6,
time_required: Duration::from_millis(100),
},
);
Self {
strategies,
strategy_effectiveness: HashMap::new(),
regulation_goals: Vec::new(),
skills_proficiency: HashMap::new(),
}
}
}
impl EmotionalContagion {
fn new() -> Self {
Self {
susceptibility: 0.3,
transmission_strength: 0.4,
immunity_factors: HashMap::new(),
contagion_network: HashMap::new(),
}
}
}
impl MoodTracker {
fn new() -> Self {
Self {
current_mood: MoodState {
primary_mood: EmotionalState::Calm,
intensity: 0.5,
stability: 0.7,
complexity: 0.3,
associated_emotions: vec![(EmotionalState::Calm, 1.0)],
},
mood_history: VecDeque::with_capacity(1000),
mood_patterns: HashMap::new(),
mood_predictor: MoodPredictor {
accuracy: 0.65,
horizon: Duration::from_secs(3600), confidence_intervals: HashMap::new(),
},
}
}
}
impl Default for EmotionalLearningNetwork {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_emotional_learning_network_creation() {
let network = EmotionalLearningNetwork::new();
assert!(network.empathy_engine.empathy_level > 0.0);
assert!(!network.emotion_regulation.strategies.is_empty());
}
#[test]
fn test_emotional_association_learning() {
let network = EmotionalLearningNetwork::new();
let result =
network.learn_emotional_association("test_pattern", EmotionalState::Confident, 0.8);
assert!(result.is_ok());
}
#[test]
fn test_emotion_prediction() {
let network = EmotionalLearningNetwork::new();
let prediction = network.predict_emotional_response("error_pattern");
assert!(prediction.is_ok());
let prediction = prediction.expect("prediction should succeed");
assert!(prediction.confidence >= 0.0 && prediction.confidence <= 1.0);
}
#[test]
fn test_empathetic_response() {
let network = EmotionalLearningNetwork::new();
let response = network.generate_empathetic_response(EmotionalState::Cautious);
assert!(response.is_ok());
let response = response.expect("response should be available");
assert!(response.intensity > 0.0);
assert!(!response.response_action.is_empty());
}
#[test]
fn test_emotion_regulation() {
let mut network = EmotionalLearningNetwork::new();
let outcome = network.regulate_emotion(EmotionalState::Cautious, EmotionalState::Confident);
assert!(outcome.is_ok());
let outcome = outcome.expect("outcome should be available");
assert!(!outcome.strategy_used.is_empty());
assert!(outcome.effectiveness >= 0.0 && outcome.effectiveness <= 1.0);
}
#[test]
fn test_mood_update() {
let mut network = EmotionalLearningNetwork::new();
let result = network.update_mood(EmotionalState::Creative, "test_context");
assert!(result.is_ok());
assert_eq!(
network.mood_tracker.current_mood.primary_mood,
EmotionalState::Creative
);
}
}