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