Skip to main content

fleet_coordinate/
integration.rs

1//! Fleet Coordinate Integration — the unified API
2//!
3//! FleetCoordinate is the single entry point for all fleet coordination algorithms.
4
5use serde::{Deserialize, Serialize};
6
7pub use crate::zhc::ZhcConsensus;
8pub use crate::beam::{BeamSolver, JointEquilibrium, MultiSegmentBeam, JointState};
9pub use crate::pythagorean48::{TrustTopology, TrustVector};
10pub use crate::graph::{FleetGraph, RigidityResult};
11pub use crate::tile::{FleetTile, TileCoordination};
12pub use crate::emergence::{EmergenceDetector, EmergenceResult};
13
14/// Unified fleet coordination configuration
15#[derive(Clone, Debug, Serialize, Deserialize)]
16pub struct Config {
17    pub equilibrium_tolerance: f64,
18    pub zhc_tolerance: f64,
19    pub max_iterations: usize,
20    pub trust_bits: f64,
21}
22
23impl Default for Config {
24    fn default() -> Self {
25        Self {
26            equilibrium_tolerance: 1e-6,
27            zhc_tolerance: 0.5,
28            max_iterations: 500,
29            trust_bits: 5.58496,
30        }
31    }
32}
33
34/// The unified fleet coordinate engine
35#[derive(Clone)]
36pub struct FleetCoordinate {
37    config: Config,
38    graph: FleetGraph,
39    zhc: ZhcConsensus,
40    beam: BeamSolver,
41    trust: TrustTopology,
42    tiles: Vec<TileCoordination>,
43}
44
45impl FleetCoordinate {
46    pub fn new(config: Config) -> Self {
47        Self {
48            config: config.clone(),
49            graph: FleetGraph::new(),
50            zhc: ZhcConsensus::new(config.zhc_tolerance),
51            beam: BeamSolver::new(config.equilibrium_tolerance),
52            trust: TrustTopology::new(),
53            tiles: Vec::new(),
54        }
55    }
56
57    pub fn add_agent(&mut self, id: u64, position: [f64; 2], capabilities: Vec<String>) {
58        self.graph.add_agent(id, position, capabilities);
59        self.zhc.add_tile(id, [position[0], position[1], 0.0], vec![]);
60    }
61
62    pub fn add_trust_edge(&mut self, a: u64, b: u64) {
63        self.graph.add_edge(a, b);
64        // Also sync ZHC adjacency so consensus reflects actual trust topology
65        self.zhc.add_tile(a, [0.0, 0.0, 0.0], vec![b]);
66        self.zhc.add_tile(b, [0.0, 0.0, 0.0], vec![a]);
67    }
68
69    pub fn analyze(&self) -> FleetAnalysisReport {
70        let rigidity = self.graph.check_laman_rigidity();
71        let zhc_consensus = self.zhc.run_consensus();
72        let emergence = EmergenceDetector::detect(rigidity.V, rigidity.E, 1);
73        let is_self = rigidity.is_rigid && zhc_consensus.is_consistent && !emergence.emergence_detected;
74
75        FleetAnalysisReport {
76            rigidity: rigidity.clone(),
77            zhc_consensus,
78            emergence: emergence.clone(),
79            config: self.config.clone(),
80            fleet_theorem: FleetTheoremResult {
81                is_laman_rigid: is_self,
82                requires_voting: false,
83                requires_central_coordinator: false,
84                drift_free: true,
85            },
86        }
87    }
88
89    pub fn trust_encoder(&self) -> &TrustTopology {
90        &self.trust
91    }
92
93    pub fn beam_solver(&self) -> &BeamSolver {
94        &self.beam
95    }
96
97    pub fn add_tile(&mut self, room: String, tile: FleetTile) {
98        if let Some(c) = self.tiles.iter_mut().find(|c| c.room == room) {
99            c.add_tile(tile);
100        } else {
101            let mut coord = TileCoordination::new(room);
102            coord.add_tile(tile);
103            self.tiles.push(coord);
104        }
105    }
106
107    pub fn agent_count(&self) -> usize {
108        self.graph.V()
109    }
110
111    pub fn edge_count(&self) -> usize {
112        self.graph.E()
113    }
114}
115
116impl Default for FleetCoordinate {
117    fn default() -> Self {
118        Self::new(Config::default())
119    }
120}
121
122/// Complete fleet analysis report
123#[derive(Clone, Debug, Serialize, Deserialize)]
124pub struct FleetAnalysisReport {
125    pub rigidity: RigidityResult,
126    pub zhc_consensus: crate::zhc::ConsensusResult,
127    pub emergence: EmergenceResult,
128    pub config: Config,
129    pub fleet_theorem: FleetTheoremResult,
130}
131
132/// Result of the Fleet Coordinate Theorem (provisional)
133#[derive(Clone, Debug, Serialize, Deserialize)]
134pub struct FleetTheoremResult {
135    pub is_laman_rigid: bool,
136    /// True if the fleet has geometric consistency (ZHC closure satisfied)
137    pub requires_voting: bool,
138    pub requires_central_coordinator: bool,
139    pub drift_free: bool,
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    #[test]
147    fn test_three_agent_triangle_self_coordinating() {
148        let mut fleet = FleetCoordinate::new(Config::default());
149        fleet.add_agent(1, [0.0, 0.0], vec![]);
150        fleet.add_agent(2, [1.0, 0.0], vec![]);
151        fleet.add_agent(3, [0.5, 0.87], vec![]);
152        fleet.add_trust_edge(1, 2);
153        fleet.add_trust_edge(2, 3);
154        fleet.add_trust_edge(3, 1);
155        let report = fleet.analyze();
156        assert!(report.fleet_theorem.is_laman_rigid);
157    }
158
159    #[test]
160    fn test_trust_encoding_batch() {
161        let fleet = FleetCoordinate::new(Config::default());
162        let batch = fleet.trust_encoder().encode_batch(&[
163            [0.6, 0.8],
164            [0.8, 0.6],
165            [-0.6, 0.8],
166        ]);
167        assert_eq!(batch.len(), 3);
168    }
169}