Skip to main content

phago_core/
substrate.rs

1//! Substrate — the shared environment all agents operate within.
2//!
3//! The substrate is the extracellular matrix: it holds the signal field,
4//! the knowledge graph, and trace deposits. Agents read from and write to
5//! the substrate, but never directly to each other.
6
7use crate::types::*;
8
9/// The shared environment that all agents sense and modify.
10///
11/// The substrate is the computational analog of the extracellular matrix
12/// in biology. It holds:
13/// - A **signal field** for chemotaxis (agents sense gradients)
14/// - A **knowledge graph** for stigmergy (agents deposit and read structure)
15/// - **Trace storage** for indirect coordination
16pub trait Substrate {
17    // --- Signal field ---
18
19    /// Read all signals within a radius of a position.
20    fn signals_near(&self, position: &Position, radius: f64) -> Vec<&Signal>;
21
22    /// Emit a signal into the substrate.
23    fn emit_signal(&mut self, signal: Signal);
24
25    /// Decay all signals by a rate (0.0-1.0). Signals below threshold are removed.
26    fn decay_signals(&mut self, rate: f64, removal_threshold: f64);
27
28    // --- Knowledge graph ---
29
30    /// Add a node to the knowledge graph.
31    fn add_node(&mut self, data: NodeData) -> NodeId;
32
33    /// Get a node by ID.
34    fn get_node(&self, id: &NodeId) -> Option<&NodeData>;
35
36    /// Add or update an edge between two nodes.
37    fn set_edge(&mut self, from: NodeId, to: NodeId, data: EdgeData);
38
39    /// Get edge data between two nodes.
40    fn get_edge(&self, from: &NodeId, to: &NodeId) -> Option<&EdgeData>;
41
42    /// Get all neighbors of a node with their edge data.
43    fn neighbors(&self, node: &NodeId) -> Vec<(NodeId, &EdgeData)>;
44
45    /// Remove an edge.
46    fn remove_edge(&mut self, from: &NodeId, to: &NodeId);
47
48    /// Get all node IDs.
49    fn all_nodes(&self) -> Vec<NodeId>;
50
51    /// Get all edges as (from, to, data) triples.
52    fn all_edges(&self) -> Vec<(NodeId, NodeId, &EdgeData)>;
53
54    /// Number of nodes in the graph.
55    fn node_count(&self) -> usize;
56
57    /// Number of edges in the graph.
58    fn edge_count(&self) -> usize;
59
60    // --- Trace storage ---
61
62    /// Deposit a trace at a location.
63    fn deposit_trace(&mut self, location: &SubstrateLocation, trace: Trace);
64
65    /// Read traces at a location.
66    fn traces_at(&self, location: &SubstrateLocation) -> Vec<&Trace>;
67
68    /// Decay all traces by a rate. Traces below threshold are removed.
69    fn decay_traces(&mut self, rate: f64, removal_threshold: f64);
70
71    // --- Document storage ---
72
73    /// Place a document in the substrate.
74    fn add_document(&mut self, doc: Document);
75
76    /// Get a document by ID.
77    fn get_document(&self, id: &DocumentId) -> Option<&Document>;
78
79    /// Get all undigested documents.
80    fn undigested_documents(&self) -> Vec<&Document>;
81
82    /// Mark a document as digested and return its content.
83    fn consume_document(&mut self, id: &DocumentId) -> Option<String>;
84
85    /// Get all documents.
86    fn all_documents(&self) -> Vec<&Document>;
87
88    // --- Lifecycle ---
89
90    /// Current simulation tick.
91    fn current_tick(&self) -> Tick;
92
93    /// Advance the tick counter.
94    fn advance_tick(&mut self);
95}