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 algorithm;
125pub mod certificate;
126pub mod cluster;
127pub mod compact;
128pub mod connectivity;
129pub mod error;
130pub mod euler;
131pub mod expander;
132pub mod fragment;
133pub mod fragmentation;
134pub mod graph;
135pub mod instance;
136pub mod integration;
137pub mod linkcut;
138pub mod localkcut;
139pub mod parallel;
140pub mod pool;
141pub mod sparsify;
142pub mod tree;
143pub mod witness;
144pub mod wrapper;
145
146pub mod optimization;
150
151pub mod snn;
183
184pub mod subpolynomial;
189
190#[cfg(feature = "jtree")]
217pub mod jtree;
218
219mod core;
221
222#[cfg(feature = "monitoring")]
224pub mod monitoring;
225
226#[cfg(feature = "wasm")]
227pub mod wasm;
228
229pub use algorithm::approximate::{
231 ApproxMinCut, ApproxMinCutConfig, ApproxMinCutResult, ApproxMinCutStats,
232};
233pub use algorithm::{AlgorithmStats, DynamicMinCut, MinCutBuilder, MinCutConfig, MinCutResult};
234pub use certificate::{
235 AuditData, AuditEntry, AuditEntryType, AuditLogger, CertLocalKCutQuery, CertificateError,
236 CutCertificate, LocalKCutResponse, LocalKCutResultSummary, UpdateTrigger, UpdateType,
237};
238pub use cluster::hierarchy::{
239 Expander, HierarchyCluster, HierarchyConfig, HierarchyStats, MirrorCut, Precluster,
240 ThreeLevelHierarchy,
241};
242pub use cluster::{Cluster, ClusterHierarchy};
243pub use compact::{
244 BitSet256, CompactAdjacency, CompactCoreState, CompactEdge, CompactEdgeId, CompactVertexId,
245 CompactWitness, CoreResult, MAX_EDGES_PER_CORE, MAX_VERTICES_PER_CORE,
246};
247pub use connectivity::polylog::{PolylogConnectivity, PolylogStats};
248pub use connectivity::DynamicConnectivity;
249pub use error::{MinCutError, Result};
250pub use euler::EulerTourTree;
251pub use expander::{Conductance, ExpanderComponent, ExpanderDecomposition};
252pub use fragment::{Fragment, FragmentResult, FragmentingAlgorithm};
253pub use fragmentation::{
254 Fragment as FragmentationFragment, Fragmentation, FragmentationConfig, TrimResult,
255};
256pub use graph::{DynamicGraph, Edge, EdgeId, GraphStats, VertexId, Weight};
257pub use instance::{
258 BoundedInstance, InstanceResult, ProperCutInstance, StubInstance, WitnessHandle,
259};
260pub use integration::{CommunityDetector, GraphPartitioner, RuVectorGraphAnalyzer};
261pub use linkcut::LinkCutTree;
262pub use localkcut::{
263 ColorMask, DeterministicFamilyGenerator, DeterministicLocalKCut, EdgeColor, ForestPacking,
264 LocalCutResult, LocalKCut, LocalKCutOracle, LocalKCutQuery,
265 LocalKCutResult as PaperLocalKCutResult,
266};
267pub use parallel::{
268 compute_core_range, CoreDistributor, CoreExecutor, CoreMessage, CoreStrategy, ResultAggregator,
269 SharedCoordinator, WorkItem, NUM_CORES, RANGES_PER_CORE, RANGE_FACTOR, TOTAL_RANGES,
270};
271pub use sparsify::{SparseGraph, SparsifyConfig};
272pub use subpolynomial::{
273 HierarchyLevel, HierarchyStatistics, LevelExpander, MinCutQueryResult, RecourseStats,
274 SubpolyConfig, SubpolynomialMinCut,
275};
276pub use tree::{DecompositionNode, HierarchicalDecomposition, LevelInfo};
277pub use witness::{EdgeWitness, LazyWitnessTree, WitnessTree};
278pub use wrapper::MinCutWrapper;
279
280pub use optimization::{
282 BatchConfig,
283 BenchmarkResult,
284 BenchmarkSuite,
286 CacheConfig,
287 CacheStats,
288 DegreePresparse,
290 DistanceArray,
291 LazyLevel,
292 LevelPool,
294 OptimizationBenchmark,
295 ParallelConfig,
296 ParallelLevelUpdater,
298 PathDistanceCache,
300 PoolConfig,
301 PoolStats,
302 PrefetchHint,
303 PresparseConfig,
304 PresparseResult,
305 PresparseStats,
306 SimdDistanceOps,
308 TypedArrayTransfer,
309 WasmBatchOps,
311 WorkStealingScheduler,
312};
313
314#[cfg(feature = "jtree")]
316pub use jtree::{
317 ApproximateCut, BmsspJTreeLevel, ContractedGraph, CutResult as JTreeCutResult,
318 DynamicCutSparsifier, EscalationPolicy, EscalationTrigger, JTreeConfig, JTreeError,
319 JTreeHierarchy, JTreeLevel, JTreeStatistics, LevelConfig, LevelStatistics, PathCutResult,
320 QueryResult as CoordinatorQueryResult, RecourseTracker, SparsifierConfig, SparsifierStatistics,
321 Tier, TierMetrics, TwoTierCoordinator, VertexSplitResult,
322};
323
324#[cfg(feature = "jtree")]
326pub use jtree::ForestPacking as JTreeForestPacking;
327
328pub use snn::{
330 AttractorConfig,
331 AttractorDynamics,
333 CPGConfig,
334 CausalConfig,
335 CausalDiscoverySNN,
337 CausalGraph,
338 CausalRelation,
339 CognitiveMinCutEngine,
341 EnergyLandscape,
342 EngineConfig,
343 EngineMetrics,
344 GrowthRules,
345 LIFNeuron,
347 LayerConfig,
348 MetaAction,
349 MetaCognitiveMinCut,
351 MetaLevel,
352 MorphConfig,
353 MorphogeneticSNN,
355 NetworkConfig,
356 NeuralGraphOptimizer,
358 NeuronConfig,
359 NeuronState,
360 OptimizationResult,
361 OptimizerConfig,
362 OscillatorNeuron,
363 PhaseTopology,
364 PolicySNN,
365 SNNMinCutConfig,
366 STDPConfig,
367 SimTime,
368 Spike,
370 SpikeTrain,
371 SpikingNetwork,
372 StrangeLoopConfig,
373 Synapse,
374 SynapseMatrix,
375 TimeCrystalCPG,
377 TuringPattern,
378 ValueNetwork,
379};
380
381#[cfg(feature = "agentic")]
382pub use integration::AgenticAnalyzer;
383
384#[cfg(feature = "monitoring")]
385pub use monitoring::{
386 EventType, MinCutEvent, MinCutMonitor, MonitorBuilder, MonitorConfig, MonitorMetrics, Threshold,
387};
388
389pub const VERSION: &str = env!("CARGO_PKG_VERSION");
391
392pub const NAME: &str = env!("CARGO_PKG_NAME");
394
395pub mod prelude {
408 pub use crate::{
411 compute_core_range,
412 AlgorithmStats,
413 ApproxMinCut,
414 ApproxMinCutConfig,
415 AttractorConfig,
416 AttractorDynamics,
417 AuditLogger,
418 BitSet256,
419 BoundedInstance,
420 CPGConfig,
421 CertificateError,
422 Cluster,
423 ClusterHierarchy,
424 CognitiveMinCutEngine,
426 ColorMask,
427 CommunityDetector,
428 CompactAdjacency,
429 CompactCoreState,
430 CompactEdge,
431 CompactEdgeId,
432 CompactVertexId,
433 CompactWitness,
434 Conductance,
435 CoreDistributor,
436 CoreExecutor,
437 CoreResult,
438 CoreStrategy,
439 CutCertificate,
440 DeterministicFamilyGenerator,
441 DeterministicLocalKCut,
442 DynamicConnectivity,
443 DynamicGraph,
444 DynamicMinCut,
445 Edge,
446 EdgeColor,
447 EdgeId,
448 EngineConfig,
449 EngineMetrics,
450 ExpanderComponent,
451 ExpanderDecomposition,
452 ForestPacking,
453 Fragment,
454 FragmentResult,
455 FragmentingAlgorithm,
456 GraphPartitioner,
457 InstanceResult,
458 LocalCutResult,
459 LocalKCut,
460 LocalKCutOracle,
461 LocalKCutQuery,
462 MinCutBuilder,
463 MinCutConfig,
464 MinCutError,
465 MinCutResult,
466 MinCutWrapper,
467 NeuralGraphOptimizer,
468 OptimizerConfig,
469 PaperLocalKCutResult,
470 PolylogConnectivity,
471 PolylogStats,
472 ProperCutInstance,
473 RecourseStats,
474 Result,
475 ResultAggregator,
476 RuVectorGraphAnalyzer,
477 SharedCoordinator,
478 SimTime,
479 Spike,
480 StubInstance,
481 SubpolyConfig,
482 SubpolynomialMinCut,
484 TimeCrystalCPG,
485 VertexId,
486 Weight,
487 WitnessHandle,
488 MAX_EDGES_PER_CORE,
489 MAX_VERTICES_PER_CORE,
490 NUM_CORES,
491 RANGES_PER_CORE,
492 };
493
494 #[cfg(feature = "agentic")]
495 pub use crate::AgenticAnalyzer;
496
497 #[cfg(feature = "monitoring")]
498 pub use crate::{EventType, MinCutEvent, MinCutMonitor, MonitorBuilder};
499
500 #[cfg(feature = "jtree")]
501 pub use crate::{
502 ApproximateCut, BmsspJTreeLevel, ContractedGraph, CoordinatorQueryResult,
503 DynamicCutSparsifier, EscalationPolicy, EscalationTrigger, JTreeConfig, JTreeCutResult,
504 JTreeError, JTreeForestPacking, JTreeHierarchy, JTreeLevel, JTreeStatistics, LevelConfig,
505 LevelStatistics, PathCutResult, RecourseTracker, SparsifierConfig, SparsifierStatistics,
506 Tier, TierMetrics, TwoTierCoordinator, VertexSplitResult,
507 };
508}
509
510#[cfg(test)]
511mod tests {
512 use super::*;
513
514 #[test]
515 fn test_version_constant() {
516 assert!(!VERSION.is_empty());
517 assert!(!NAME.is_empty());
518 assert_eq!(NAME, "ruvector-mincut");
519 }
520
521 #[test]
522 fn test_basic_workflow() {
523 let mut mincut = MinCutBuilder::new()
525 .exact()
526 .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0), (3, 1, 1.0)])
527 .build()
528 .unwrap();
529
530 assert_eq!(mincut.num_vertices(), 3);
532 assert_eq!(mincut.num_edges(), 3);
533 assert_eq!(mincut.min_cut_value(), 2.0);
534
535 let new_cut = mincut.insert_edge(1, 4, 2.0).unwrap();
537 assert!(new_cut.is_finite());
538 assert_eq!(mincut.num_edges(), 4);
539
540 let new_cut = mincut.delete_edge(1, 2).unwrap();
542 assert!(new_cut.is_finite());
543 assert_eq!(mincut.num_edges(), 3);
544 }
545
546 #[test]
547 fn test_prelude_imports() {
548 use crate::prelude::*;
549
550 let mincut = MinCutBuilder::new().build().unwrap();
552
553 assert_eq!(mincut.min_cut_value(), f64::INFINITY);
554 }
555
556 #[test]
557 fn test_approximate_mode() {
558 let mincut = MinCutBuilder::new()
559 .approximate(0.1)
560 .with_edges(vec![(1, 2, 1.0)])
561 .build()
562 .unwrap();
563
564 let result = mincut.min_cut();
565 assert!(!result.is_exact);
566 assert_eq!(result.approximation_ratio, 1.1);
567 }
568
569 #[test]
570 fn test_exact_mode() {
571 let mincut = MinCutBuilder::new()
572 .exact()
573 .with_edges(vec![(1, 2, 1.0)])
574 .build()
575 .unwrap();
576
577 let result = mincut.min_cut();
578 assert!(result.is_exact);
579 assert_eq!(result.approximation_ratio, 1.0);
580 }
581
582 #[test]
583 fn test_min_cut_result() {
584 let mincut = MinCutBuilder::new()
585 .with_edges(vec![(1, 2, 1.0), (2, 3, 1.0), (3, 1, 1.0)])
586 .build()
587 .unwrap();
588
589 let result = mincut.min_cut();
590 assert_eq!(result.value, 2.0);
591 assert!(result.cut_edges.is_some());
592 assert!(result.partition.is_some());
593
594 if let Some((s, t)) = result.partition {
595 assert_eq!(s.len() + t.len(), 3);
596 assert!(!s.is_empty());
597 assert!(!t.is_empty());
598 }
599 }
600
601 #[test]
602 fn test_graph_stats() {
603 let mincut = MinCutBuilder::new()
604 .with_edges(vec![(1, 2, 2.0), (2, 3, 3.0), (3, 1, 1.0)])
605 .build()
606 .unwrap();
607
608 let graph = mincut.graph();
609 let stats = graph.read().stats();
610
611 assert_eq!(stats.num_vertices, 3);
612 assert_eq!(stats.num_edges, 3);
613 assert_eq!(stats.total_weight, 6.0);
614 assert_eq!(stats.min_degree, 2);
615 assert_eq!(stats.max_degree, 2);
616 }
617
618 #[test]
619 fn test_algorithm_stats() {
620 let mut mincut = MinCutBuilder::new()
621 .with_edges(vec![(1, 2, 1.0)])
622 .build()
623 .unwrap();
624
625 mincut.insert_edge(2, 3, 1.0).unwrap();
626 mincut.delete_edge(1, 2).unwrap();
627 let _ = mincut.min_cut_value();
628
629 let stats = mincut.stats();
630 assert_eq!(stats.insertions, 1);
631 assert_eq!(stats.deletions, 1);
632 assert_eq!(stats.queries, 1);
633 assert!(stats.avg_update_time_us > 0.0);
634 }
635
636 #[test]
637 fn test_dynamic_updates() {
638 let mut mincut = MinCutBuilder::new().build().unwrap();
639
640 assert_eq!(mincut.min_cut_value(), f64::INFINITY);
642
643 mincut.insert_edge(1, 2, 1.0).unwrap();
645 assert_eq!(mincut.min_cut_value(), 1.0);
646
647 mincut.insert_edge(2, 3, 1.0).unwrap();
648 assert_eq!(mincut.min_cut_value(), 1.0);
649
650 mincut.insert_edge(3, 1, 1.0).unwrap();
651 assert_eq!(mincut.min_cut_value(), 2.0);
652 }
653
654 #[test]
655 fn test_disconnected_graph() {
656 let mincut = MinCutBuilder::new()
657 .with_edges(vec![(1, 2, 1.0), (3, 4, 1.0)])
658 .build()
659 .unwrap();
660
661 assert!(!mincut.is_connected());
662 assert_eq!(mincut.min_cut_value(), 0.0);
663 }
664
665 #[test]
666 fn test_builder_pattern() {
667 let mincut = MinCutBuilder::new()
668 .exact()
669 .max_cut_size(500)
670 .parallel(true)
671 .with_edges(vec![(1, 2, 1.0)])
672 .build()
673 .unwrap();
674
675 assert!(!mincut.config().approximate);
676 assert_eq!(mincut.config().max_exact_cut_size, 500);
677 assert!(mincut.config().parallel);
678 }
679
680 #[test]
681 fn test_weighted_graph() {
682 let mincut = MinCutBuilder::new()
683 .with_edges(vec![(1, 2, 5.0), (2, 3, 3.0), (3, 1, 2.0)])
684 .build()
685 .unwrap();
686
687 assert_eq!(mincut.min_cut_value(), 5.0);
688 }
689
690 #[test]
691 fn test_error_handling() {
692 let mut mincut = MinCutBuilder::new()
693 .with_edges(vec![(1, 2, 1.0)])
694 .build()
695 .unwrap();
696
697 let result = mincut.insert_edge(1, 2, 2.0);
699 assert!(result.is_err());
700 assert!(matches!(result, Err(MinCutError::EdgeExists(1, 2))));
701
702 let result = mincut.delete_edge(3, 4);
704 assert!(result.is_err());
705 assert!(matches!(result, Err(MinCutError::EdgeNotFound(3, 4))));
706 }
707
708 #[test]
709 fn test_large_graph() {
710 let mut edges = Vec::new();
711 for i in 0..99 {
712 edges.push((i, i + 1, 1.0));
713 }
714
715 let mincut = MinCutBuilder::new().with_edges(edges).build().unwrap();
716
717 assert_eq!(mincut.num_vertices(), 100);
718 assert_eq!(mincut.num_edges(), 99);
719 assert_eq!(mincut.min_cut_value(), 1.0);
720 }
721
722 #[cfg(feature = "monitoring")]
723 #[test]
724 fn test_monitoring_feature() {
725 use crate::monitoring::EventType;
726
727 let _ = EventType::CutIncreased;
729 let _ = EventType::CutDecreased;
730 }
731}