1#![deny(missing_docs)]
116#![cfg_attr(not(feature = "wasm"), deny(unsafe_code))]
117#![warn(clippy::all)]
118#![warn(clippy::pedantic)]
119#![allow(clippy::module_name_repetitions)]
120#![allow(clippy::missing_errors_doc)]
121#![allow(clippy::missing_panics_doc)]
122
123pub mod error;
125pub mod graph;
126pub mod linkcut;
127pub mod euler;
128pub mod tree;
129pub mod witness;
130pub mod algorithm;
131pub mod sparsify;
132pub mod expander;
133pub mod localkcut;
134pub mod connectivity;
135pub mod instance;
136pub mod wrapper;
137pub mod certificate;
138pub mod fragment;
139pub mod fragmentation;
140pub mod cluster;
141pub mod compact;
142pub mod parallel;
143pub mod pool;
144pub mod integration;
145
146pub mod snn;
178
179mod core;
181
182#[cfg(feature = "monitoring")]
184pub mod monitoring;
185
186#[cfg(feature = "wasm")]
187pub mod wasm;
188
189pub use error::{MinCutError, Result};
191pub use graph::{DynamicGraph, Edge, GraphStats, VertexId, EdgeId, Weight};
192pub use algorithm::{DynamicMinCut, MinCutBuilder, MinCutConfig, MinCutResult, AlgorithmStats};
193pub use algorithm::approximate::{ApproxMinCut, ApproxMinCutConfig, ApproxMinCutResult, ApproxMinCutStats};
194pub use tree::{HierarchicalDecomposition, DecompositionNode, LevelInfo};
195pub use witness::{WitnessTree, LazyWitnessTree, EdgeWitness};
196pub use linkcut::LinkCutTree;
197pub use euler::EulerTourTree;
198pub use sparsify::{SparseGraph, SparsifyConfig};
199pub use expander::{ExpanderDecomposition, ExpanderComponent, Conductance};
200pub use localkcut::{
201 LocalKCut, LocalCutResult, EdgeColor, ColorMask, ForestPacking,
202 LocalKCutQuery, LocalKCutResult as PaperLocalKCutResult, LocalKCutOracle,
203 DeterministicLocalKCut, DeterministicFamilyGenerator,
204};
205pub use connectivity::DynamicConnectivity;
206pub use connectivity::polylog::{PolylogConnectivity, PolylogStats};
207pub use instance::{ProperCutInstance, InstanceResult, WitnessHandle, StubInstance, BoundedInstance};
208pub use wrapper::MinCutWrapper;
209pub use certificate::{
210 CutCertificate, CertificateError, CertLocalKCutQuery, LocalKCutResponse,
211 LocalKCutResultSummary, UpdateTrigger, UpdateType, AuditLogger,
212 AuditEntry, AuditEntryType, AuditData,
213};
214pub use cluster::{ClusterHierarchy, Cluster};
215pub use cluster::hierarchy::{
216 ThreeLevelHierarchy, Expander, Precluster, HierarchyCluster,
217 MirrorCut, HierarchyConfig, HierarchyStats,
218};
219pub use fragment::{Fragment, FragmentResult, FragmentingAlgorithm};
220pub use fragmentation::{
221 Fragmentation, FragmentationConfig, TrimResult,
222 Fragment as FragmentationFragment,
223};
224pub use compact::{
225 BitSet256, CompactEdge, CompactWitness, CompactAdjacency, CompactCoreState,
226 CoreResult, CompactVertexId, CompactEdgeId, MAX_VERTICES_PER_CORE, MAX_EDGES_PER_CORE,
227};
228pub use parallel::{
229 NUM_CORES, RANGES_PER_CORE, TOTAL_RANGES, RANGE_FACTOR,
230 CoreStrategy, CoreMessage, WorkItem, SharedCoordinator,
231 CoreDistributor, CoreExecutor, ResultAggregator,
232 compute_core_range,
233};
234pub use integration::{
235 RuVectorGraphAnalyzer, CommunityDetector, GraphPartitioner,
236};
237
238pub use snn::{
240 LIFNeuron, NeuronState, NeuronConfig, SpikeTrain,
242 Synapse, STDPConfig, SynapseMatrix,
243 SpikingNetwork, NetworkConfig, LayerConfig,
244 AttractorDynamics, EnergyLandscape, AttractorConfig,
246 MetaCognitiveMinCut, MetaAction, MetaLevel, StrangeLoopConfig,
248 CausalDiscoverySNN, CausalGraph, CausalRelation, CausalConfig,
250 TimeCrystalCPG, OscillatorNeuron, PhaseTopology, CPGConfig,
252 MorphogeneticSNN, GrowthRules, TuringPattern, MorphConfig,
254 NeuralGraphOptimizer, PolicySNN, ValueNetwork, OptimizerConfig, OptimizationResult,
256 CognitiveMinCutEngine, EngineConfig, EngineMetrics,
258 Spike, SimTime, SNNMinCutConfig,
260};
261
262#[cfg(feature = "agentic")]
263pub use integration::AgenticAnalyzer;
264
265#[cfg(feature = "monitoring")]
266pub use monitoring::{
267 MinCutMonitor, MonitorBuilder, MonitorConfig, MinCutEvent,
268 EventType, Threshold, MonitorMetrics
269};
270
271pub const VERSION: &str = env!("CARGO_PKG_VERSION");
273
274pub const NAME: &str = env!("CARGO_PKG_NAME");
276
277pub mod prelude {
290 pub use crate::{
293 DynamicMinCut, MinCutBuilder, MinCutConfig, MinCutResult, ApproxMinCut, ApproxMinCutConfig,
294 DynamicGraph, Edge, VertexId, EdgeId, Weight,
295 MinCutError, Result,
296 AlgorithmStats,
297 ExpanderDecomposition, ExpanderComponent, Conductance,
298 LocalKCut, LocalCutResult, EdgeColor, ColorMask, ForestPacking,
299 LocalKCutQuery, PaperLocalKCutResult, LocalKCutOracle,
300 DeterministicLocalKCut, DeterministicFamilyGenerator,
301 CutCertificate, CertificateError, AuditLogger,
302 DynamicConnectivity, PolylogConnectivity, PolylogStats,
303 ProperCutInstance, InstanceResult, WitnessHandle, StubInstance, BoundedInstance,
304 MinCutWrapper,
305 ClusterHierarchy, Cluster,
306 Fragment, FragmentResult, FragmentingAlgorithm,
307 BitSet256, CompactEdge, CompactWitness, CompactAdjacency, CompactCoreState,
308 CoreResult, CompactVertexId, CompactEdgeId, MAX_VERTICES_PER_CORE, MAX_EDGES_PER_CORE,
309 NUM_CORES, RANGES_PER_CORE, CoreStrategy, SharedCoordinator,
310 CoreDistributor, CoreExecutor, ResultAggregator, compute_core_range,
311 RuVectorGraphAnalyzer, CommunityDetector, GraphPartitioner,
312 CognitiveMinCutEngine, EngineConfig, EngineMetrics,
314 AttractorDynamics, AttractorConfig,
315 TimeCrystalCPG, CPGConfig,
316 NeuralGraphOptimizer, OptimizerConfig,
317 Spike, SimTime,
318 };
319
320 #[cfg(feature = "agentic")]
321 pub use crate::AgenticAnalyzer;
322
323 #[cfg(feature = "monitoring")]
324 pub use crate::{MinCutMonitor, MonitorBuilder, MinCutEvent, EventType};
325}
326
327#[cfg(test)]
328mod tests {
329 use super::*;
330
331 #[test]
332 fn test_version_constant() {
333 assert!(!VERSION.is_empty());
334 assert!(!NAME.is_empty());
335 assert_eq!(NAME, "ruvector-mincut");
336 }
337
338 #[test]
339 fn test_basic_workflow() {
340 let mut mincut = MinCutBuilder::new()
342 .exact()
343 .with_edges(vec![
344 (1, 2, 1.0),
345 (2, 3, 1.0),
346 (3, 1, 1.0),
347 ])
348 .build()
349 .unwrap();
350
351 assert_eq!(mincut.num_vertices(), 3);
353 assert_eq!(mincut.num_edges(), 3);
354 assert_eq!(mincut.min_cut_value(), 2.0);
355
356 let new_cut = mincut.insert_edge(1, 4, 2.0).unwrap();
358 assert!(new_cut.is_finite());
359 assert_eq!(mincut.num_edges(), 4);
360
361 let new_cut = mincut.delete_edge(1, 2).unwrap();
363 assert!(new_cut.is_finite());
364 assert_eq!(mincut.num_edges(), 3);
365 }
366
367 #[test]
368 fn test_prelude_imports() {
369 use crate::prelude::*;
370
371 let mincut = MinCutBuilder::new()
373 .build()
374 .unwrap();
375
376 assert_eq!(mincut.min_cut_value(), f64::INFINITY);
377 }
378
379 #[test]
380 fn test_approximate_mode() {
381 let mincut = MinCutBuilder::new()
382 .approximate(0.1)
383 .with_edges(vec![(1, 2, 1.0)])
384 .build()
385 .unwrap();
386
387 let result = mincut.min_cut();
388 assert!(!result.is_exact);
389 assert_eq!(result.approximation_ratio, 1.1);
390 }
391
392 #[test]
393 fn test_exact_mode() {
394 let mincut = MinCutBuilder::new()
395 .exact()
396 .with_edges(vec![(1, 2, 1.0)])
397 .build()
398 .unwrap();
399
400 let result = mincut.min_cut();
401 assert!(result.is_exact);
402 assert_eq!(result.approximation_ratio, 1.0);
403 }
404
405 #[test]
406 fn test_min_cut_result() {
407 let mincut = MinCutBuilder::new()
408 .with_edges(vec![
409 (1, 2, 1.0),
410 (2, 3, 1.0),
411 (3, 1, 1.0),
412 ])
413 .build()
414 .unwrap();
415
416 let result = mincut.min_cut();
417 assert_eq!(result.value, 2.0);
418 assert!(result.cut_edges.is_some());
419 assert!(result.partition.is_some());
420
421 if let Some((s, t)) = result.partition {
422 assert_eq!(s.len() + t.len(), 3);
423 assert!(!s.is_empty());
424 assert!(!t.is_empty());
425 }
426 }
427
428 #[test]
429 fn test_graph_stats() {
430 let mincut = MinCutBuilder::new()
431 .with_edges(vec![
432 (1, 2, 2.0),
433 (2, 3, 3.0),
434 (3, 1, 1.0),
435 ])
436 .build()
437 .unwrap();
438
439 let graph = mincut.graph();
440 let stats = graph.read().stats();
441
442 assert_eq!(stats.num_vertices, 3);
443 assert_eq!(stats.num_edges, 3);
444 assert_eq!(stats.total_weight, 6.0);
445 assert_eq!(stats.min_degree, 2);
446 assert_eq!(stats.max_degree, 2);
447 }
448
449 #[test]
450 fn test_algorithm_stats() {
451 let mut mincut = MinCutBuilder::new()
452 .with_edges(vec![(1, 2, 1.0)])
453 .build()
454 .unwrap();
455
456 mincut.insert_edge(2, 3, 1.0).unwrap();
457 mincut.delete_edge(1, 2).unwrap();
458 let _ = mincut.min_cut_value();
459
460 let stats = mincut.stats();
461 assert_eq!(stats.insertions, 1);
462 assert_eq!(stats.deletions, 1);
463 assert_eq!(stats.queries, 1);
464 assert!(stats.avg_update_time_us > 0.0);
465 }
466
467 #[test]
468 fn test_dynamic_updates() {
469 let mut mincut = MinCutBuilder::new().build().unwrap();
470
471 assert_eq!(mincut.min_cut_value(), f64::INFINITY);
473
474 mincut.insert_edge(1, 2, 1.0).unwrap();
476 assert_eq!(mincut.min_cut_value(), 1.0);
477
478 mincut.insert_edge(2, 3, 1.0).unwrap();
479 assert_eq!(mincut.min_cut_value(), 1.0);
480
481 mincut.insert_edge(3, 1, 1.0).unwrap();
482 assert_eq!(mincut.min_cut_value(), 2.0);
483 }
484
485 #[test]
486 fn test_disconnected_graph() {
487 let mincut = MinCutBuilder::new()
488 .with_edges(vec![
489 (1, 2, 1.0),
490 (3, 4, 1.0),
491 ])
492 .build()
493 .unwrap();
494
495 assert!(!mincut.is_connected());
496 assert_eq!(mincut.min_cut_value(), 0.0);
497 }
498
499 #[test]
500 fn test_builder_pattern() {
501 let mincut = MinCutBuilder::new()
502 .exact()
503 .max_cut_size(500)
504 .parallel(true)
505 .with_edges(vec![(1, 2, 1.0)])
506 .build()
507 .unwrap();
508
509 assert!(!mincut.config().approximate);
510 assert_eq!(mincut.config().max_exact_cut_size, 500);
511 assert!(mincut.config().parallel);
512 }
513
514 #[test]
515 fn test_weighted_graph() {
516 let mincut = MinCutBuilder::new()
517 .with_edges(vec![
518 (1, 2, 5.0),
519 (2, 3, 3.0),
520 (3, 1, 2.0),
521 ])
522 .build()
523 .unwrap();
524
525 assert_eq!(mincut.min_cut_value(), 5.0);
526 }
527
528 #[test]
529 fn test_error_handling() {
530 let mut mincut = MinCutBuilder::new()
531 .with_edges(vec![(1, 2, 1.0)])
532 .build()
533 .unwrap();
534
535 let result = mincut.insert_edge(1, 2, 2.0);
537 assert!(result.is_err());
538 assert!(matches!(result, Err(MinCutError::EdgeExists(1, 2))));
539
540 let result = mincut.delete_edge(3, 4);
542 assert!(result.is_err());
543 assert!(matches!(result, Err(MinCutError::EdgeNotFound(3, 4))));
544 }
545
546 #[test]
547 fn test_large_graph() {
548 let mut edges = Vec::new();
549 for i in 0..99 {
550 edges.push((i, i + 1, 1.0));
551 }
552
553 let mincut = MinCutBuilder::new()
554 .with_edges(edges)
555 .build()
556 .unwrap();
557
558 assert_eq!(mincut.num_vertices(), 100);
559 assert_eq!(mincut.num_edges(), 99);
560 assert_eq!(mincut.min_cut_value(), 1.0);
561 }
562
563 #[cfg(feature = "monitoring")]
564 #[test]
565 fn test_monitoring_feature() {
566 use crate::monitoring::EventType;
567
568 let _ = EventType::CutIncreased;
570 let _ = EventType::CutDecreased;
571 }
572}