use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone)]
pub struct CollectiveIntelligence {
pub groups: HashMap<String, OrganismGroup>,
pub active_decisions: Vec<CollectiveDecision>,
pub swarm_behaviors: Vec<SwarmBehavior>,
pub collective_memory: CollectiveMemory,
pub intelligence_metrics: IntelligenceMetrics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OrganismGroup {
pub group_id: String,
pub members: Vec<String>,
pub purpose: String,
pub intelligence_level: f64,
pub cohesion: f64,
pub created_at: u64,
pub performance_history: Vec<GroupPerformance>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectiveDecision {
pub decision_id: String,
pub question: String,
pub participants: Vec<String>,
pub options: Vec<DecisionOption>,
pub algorithm: DecisionAlgorithm,
pub status: DecisionStatus,
pub result: Option<String>,
pub confidence: f64,
pub timestamp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DecisionOption {
pub option_id: String,
pub description: String,
pub votes: Vec<Vote>,
pub weight: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Vote {
pub organism_id: String,
pub strength: f64,
pub confidence: f64,
pub timestamp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DecisionAlgorithm {
Majority,
WeightedByFitness,
Consensus,
SwarmIntelligence,
NeuralNetwork,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DecisionStatus {
Proposed,
Voting,
Decided,
Cancelled,
Executing,
Complete,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SwarmBehavior {
pub behavior_id: String,
pub name: String,
pub behavior_type: SwarmBehaviorType,
pub participants: Vec<String>,
pub parameters: HashMap<String, f64>,
pub effectiveness: f64,
pub created_at: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SwarmBehaviorType {
Flocking,
Foraging,
ProblemSolving,
InformationSharing,
CoordinatedEvolution,
Defense,
Exploration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectiveMemory {
pub knowledge_base: HashMap<String, SharedKnowledge>,
pub experiences: Vec<CollectiveExperience>,
pub wisdom: Vec<CollectiveWisdom>,
pub consolidation_rules: Vec<ConsolidationRule>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SharedKnowledge {
pub knowledge_id: String,
pub content: String,
pub contributors: Vec<String>,
pub reliability: f64,
pub age: u64,
pub access_count: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectiveExperience {
pub experience_id: String,
pub description: String,
pub participants: Vec<String>,
pub outcome: ExperienceOutcome,
pub lessons: Vec<String>,
pub timestamp: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExperienceOutcome {
Success,
Failure,
Partial,
Learning,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CollectiveWisdom {
pub statement: String,
pub supporting_experiences: Vec<String>,
pub confidence: f64,
pub age: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsolidationRule {
pub name: String,
pub condition: String,
pub action: String,
pub priority: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GroupPerformance {
pub timestamp: u64,
pub task_completion_rate: f64,
pub decision_accuracy: f64,
pub coordination_efficiency: f64,
pub innovation_rate: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntelligenceMetrics {
pub total_groups: usize,
pub active_decisions: usize,
pub successful_decisions: u64,
pub failed_decisions: u64,
pub avg_decision_time: f64,
pub collective_iq: f64,
}
impl CollectiveIntelligence {
pub fn new() -> Result<Self, CollectiveError> {
Ok(CollectiveIntelligence {
groups: HashMap::new(),
active_decisions: Vec::new(),
swarm_behaviors: Vec::new(),
collective_memory: CollectiveMemory::new(),
intelligence_metrics: IntelligenceMetrics::new(),
})
}
pub fn create_group(&mut self, members: Vec<String>, purpose: String) -> Result<String, CollectiveError> {
let group_id = format!("group_{}", uuid::Uuid::new_v4());
let group = OrganismGroup {
group_id: group_id.clone(),
members,
purpose,
intelligence_level: 0.5,
cohesion: 0.6,
created_at: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
performance_history: Vec::new(),
};
self.groups.insert(group_id.clone(), group);
self.intelligence_metrics.total_groups += 1;
Ok(group_id)
}
pub fn initiate_decision(
&mut self,
question: String,
participants: Vec<String>,
options: Vec<String>,
algorithm: DecisionAlgorithm,
) -> Result<String, CollectiveError> {
let decision_id = format!("decision_{}", uuid::Uuid::new_v4());
let decision_options: Vec<DecisionOption> = options
.into_iter()
.map(|desc| DecisionOption {
option_id: uuid::Uuid::new_v4().to_string(),
description: desc,
votes: Vec::new(),
weight: 0.0,
})
.collect();
let decision = CollectiveDecision {
decision_id: decision_id.clone(),
question,
participants,
options: decision_options,
algorithm,
status: DecisionStatus::Proposed,
result: None,
confidence: 0.0,
timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
};
self.active_decisions.push(decision);
self.intelligence_metrics.active_decisions += 1;
Ok(decision_id)
}
pub fn cast_vote(
&mut self,
decision_id: &str,
organism_id: &str,
option_id: &str,
strength: f64,
confidence: f64,
) -> Result<(), CollectiveError> {
if let Some(decision) = self.active_decisions.iter_mut().find(|d| d.decision_id == decision_id) {
if decision.status != DecisionStatus::Voting {
return Err(CollectiveError::DecisionNotVoting);
}
if let Some(option) = decision.options.iter_mut().find(|o| o.option_id == option_id) {
let vote = Vote {
organism_id: organism_id.to_string(),
strength,
confidence,
timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
};
option.votes.push(vote);
option.weight += strength * confidence;
Ok(())
} else {
Err(CollectiveError::OptionNotFound(option_id.to_string()))
}
} else {
Err(CollectiveError::DecisionNotFound(decision_id.to_string()))
}
}
pub fn finalize_decision(&mut self, decision_id: &str) -> Result<String, CollectiveError> {
if let Some(decision) = self.active_decisions.iter_mut().find(|d| d.decision_id == decision_id) {
match decision.algorithm {
DecisionAlgorithm::Majority => {
let best_option = decision.options.iter()
.max_by(|a, b| a.votes.len().cmp(&b.votes.len()));
if let Some(option) = best_option {
decision.result = Some(option.description.clone());
decision.status = DecisionStatus::Decided;
decision.confidence = option.votes.len() as f64 / decision.participants.len() as f64;
self.intelligence_metrics.successful_decisions += 1;
self.intelligence_metrics.active_decisions -= 1;
Ok(option.description.clone())
} else {
Err(CollectiveError::NoVotesCast)
}
},
DecisionAlgorithm::WeightedByFitness => {
let best_option = decision.options.iter()
.max_by(|a, b| a.weight.partial_cmp(&b.weight).unwrap());
if let Some(option) = best_option {
decision.result = Some(option.description.clone());
decision.status = DecisionStatus::Decided;
decision.confidence = option.weight / decision.options.len() as f64;
self.intelligence_metrics.successful_decisions += 1;
self.intelligence_metrics.active_decisions -= 1;
Ok(option.description.clone())
} else {
Err(CollectiveError::NoVotesCast)
}
},
_ => {
Err(CollectiveError::AlgorithmNotImplemented)
}
}
} else {
Err(CollectiveError::DecisionNotFound(decision_id.to_string()))
}
}
pub fn get_metrics(&self) -> IntelligenceMetrics {
self.intelligence_metrics.clone()
}
}
impl CollectiveMemory {
pub fn new() -> Self {
CollectiveMemory {
knowledge_base: HashMap::new(),
experiences: Vec::new(),
wisdom: Vec::new(),
consolidation_rules: Vec::new(),
}
}
}
impl IntelligenceMetrics {
pub fn new() -> Self {
IntelligenceMetrics {
total_groups: 0,
active_decisions: 0,
successful_decisions: 0,
failed_decisions: 0,
avg_decision_time: 0.0,
collective_iq: 100.0,
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum CollectiveError {
#[error("Group not found: {0}")]
GroupNotFound(String),
#[error("Decision not found: {0}")]
DecisionNotFound(String),
#[error("Option not found: {0}")]
OptionNotFound(String),
#[error("Decision is not in voting state")]
DecisionNotVoting,
#[error("No votes cast")]
NoVotesCast,
#[error("Algorithm not implemented")]
AlgorithmNotImplemented,
#[error("Insufficient participants")]
InsufficientParticipants,
#[error("Group capacity exceeded")]
GroupCapacityExceeded,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_collective_intelligence_creation() {
let ci = CollectiveIntelligence::new().unwrap();
assert_eq!(ci.groups.len(), 0);
assert_eq!(ci.active_decisions.len(), 0);
}
#[test]
fn test_group_creation() {
let mut ci = CollectiveIntelligence::new().unwrap();
let members = vec!["tron_1".to_string(), "tron_2".to_string()];
let group_id = ci.create_group(members.clone(), "Test Group".to_string()).unwrap();
assert!(!group_id.is_empty());
assert!(ci.groups.contains_key(&group_id));
assert_eq!(ci.groups[&group_id].members, members);
}
#[test]
fn test_decision_initiation() {
let mut ci = CollectiveIntelligence::new().unwrap();
let participants = vec!["tron_1".to_string(), "tron_2".to_string()];
let options = vec!["Option A".to_string(), "Option B".to_string()];
let decision_id = ci.initiate_decision(
"Test Question".to_string(),
participants,
options,
DecisionAlgorithm::Majority,
).unwrap();
assert!(!decision_id.is_empty());
assert_eq!(ci.active_decisions.len(), 1);
assert_eq!(ci.active_decisions[0].options.len(), 2);
}
#[test]
fn test_voting_and_decision() {
let mut ci = CollectiveIntelligence::new().unwrap();
let participants = vec!["tron_1".to_string(), "tron_2".to_string()];
let options = vec!["Option A".to_string(), "Option B".to_string()];
let decision_id = ci.initiate_decision(
"Test Question".to_string(),
participants,
options,
DecisionAlgorithm::Majority,
).unwrap();
ci.active_decisions[0].status = DecisionStatus::Voting;
let option_id = ci.active_decisions[0].options[0].option_id.clone();
ci.cast_vote(&decision_id, "tron_1", &option_id, 1.0, 0.8).unwrap();
ci.cast_vote(&decision_id, "tron_2", &option_id, 0.8, 0.9).unwrap();
let result = ci.finalize_decision(&decision_id).unwrap();
assert_eq!(result, "Option A");
assert_eq!(ci.active_decisions[0].status, DecisionStatus::Decided);
assert!(ci.active_decisions[0].confidence > 0.0);
}
}