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