Skip to content
1 change: 1 addition & 0 deletions examples/chained_reduction_ksat_to_mis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use problemreductions::rules::{MinimizeSteps, ReductionGraph};
use problemreductions::solvers::ILPSolver;
use problemreductions::topology::SimpleGraph;
use problemreductions::types::ProblemSize;
use problemreductions::variant::K3;
// ANCHOR_END: imports

pub fn run() {
Expand Down
9 changes: 6 additions & 3 deletions examples/export_mapping_stages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
//! cargo run --example export_mapping_stages -- petersen triangular

use problemreductions::rules::unitdiskmapping::{
create_copylines, ksg, mis_overhead_copyline, mis_overhead_copyline_triangular, triangular,
CopyLine, MappingGrid,
_internal::{
create_copylines, mis_overhead_copyline, mis_overhead_copyline_triangular, CopyLine,
MappingGrid,
},
ksg, triangular,
};
use problemreductions::topology::smallgraph;
use serde::Serialize;
Expand Down Expand Up @@ -102,7 +105,7 @@ fn gadget_name(idx: usize) -> String {
// The Typst script converts to 1-indexed for comparison with Julia.
// DO NOT add +1 here - keep 0-indexed!
fn extract_grid_nodes(grid: &MappingGrid) -> Vec<GridNodeExport> {
use problemreductions::rules::unitdiskmapping::CellState;
use problemreductions::rules::unitdiskmapping::_internal::CellState;
let mut nodes = Vec::new();
let (rows, cols) = grid.size();
for r in 0..rows {
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_factoring_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// Exports `docs/paper/examples/factoring_to_ilp.json` for use in paper code blocks.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::solvers::ILPSolver;

Expand Down
1 change: 1 addition & 0 deletions examples/reduction_ilp_to_qubo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
// ```

use problemreductions::export::*;
use problemreductions::models::optimization::{ILP, LinearConstraint, ObjectiveSense};
use problemreductions::prelude::*;

pub fn run() {
Expand Down
2 changes: 2 additions & 0 deletions examples/reduction_kcoloring_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
// Exports `docs/paper/examples/kcoloring_to_ilp.json` and `kcoloring_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::solvers::ILPSolver;
use problemreductions::topology::small_graphs::petersen;
use problemreductions::topology::{Graph, SimpleGraph};
use problemreductions::variant::K3;

pub fn run() {
// 1. Create KColoring instance: Petersen graph (10 vertices, 15 edges) with 3 colors, χ=3
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_kcoloring_to_qubo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use problemreductions::export::*;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::house;
use problemreductions::topology::{Graph, SimpleGraph};
use problemreductions::variant::K3;

pub fn run() {
println!("=== K-Coloring -> QUBO Reduction ===\n");
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_ksatisfiability_to_qubo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

use problemreductions::export::*;
use problemreductions::prelude::*;
use problemreductions::variant::K3;

pub fn run() {
println!("=== K-Satisfiability (3-SAT) -> QUBO Reduction ===\n");
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_maximumclique_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Exports `docs/paper/examples/maximumclique_to_ilp.json` and `maximumclique_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::octahedral;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_maximumindependentset_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// Exports `docs/paper/examples/maximumindependentset_to_ilp.json` and `maximumindependentset_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::petersen;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_maximummatching_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// Exports `docs/paper/examples/maximummatching_to_ilp.json` and `maximummatching_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::petersen;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_maximumsetpacking_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Exports `docs/paper/examples/maximumsetpacking_to_ilp.json` and `maximumsetpacking_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;

pub fn run() {
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_minimumdominatingset_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// Exports `docs/paper/examples/minimumdominatingset_to_ilp.json` and `minimumdominatingset_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::petersen;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_minimumsetcovering_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Exports `docs/paper/examples/minimumsetcovering_to_ilp.json` and `minimumsetcovering_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;

pub fn run() {
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_minimumvertexcover_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// Exports `docs/paper/examples/minimumvertexcover_to_ilp.json` and `minimumvertexcover_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::topology::small_graphs::petersen;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_satisfiability_to_kcoloring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use problemreductions::export::*;
use problemreductions::prelude::*;
use problemreductions::topology::{Graph, SimpleGraph};
use problemreductions::variant::K3;

pub fn run() {
// 1. Create SAT instance: 5-variable, 3-clause formula with unit clauses
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_satisfiability_to_ksatisfiability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use problemreductions::export::*;
use problemreductions::prelude::*;
use problemreductions::variant::K3;

pub fn run() {
// 1. Create SAT instance with varied clause sizes to demonstrate padding and splitting:
Expand Down
1 change: 1 addition & 0 deletions examples/reduction_travelingsalesman_to_ilp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Exports `docs/paper/examples/travelingsalesman_to_ilp.json` and `travelingsalesman_to_ilp.result.json`.

use problemreductions::export::*;
use problemreductions::models::optimization::ILP;
use problemreductions::prelude::*;
use problemreductions::solvers::ILPSolver;
use problemreductions::topology::{Graph, SimpleGraph};
Expand Down
6 changes: 4 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,14 @@ pub fn config_to_index(config: &[usize], num_flavors: usize) -> usize {
}

/// Convert a binary configuration to a bitvec-style representation.
pub fn config_to_bits(config: &[usize]) -> Vec<bool> {
#[cfg(test)]
pub(crate) fn config_to_bits(config: &[usize]) -> Vec<bool> {
config.iter().map(|&v| v != 0).collect()
}

/// Convert a bitvec-style representation to a binary configuration.
pub fn bits_to_config(bits: &[bool]) -> Vec<usize> {
#[cfg(test)]
pub(crate) fn bits_to_config(bits: &[bool]) -> Vec<usize> {
bits.iter().map(|&b| if b { 1 } else { 0 }).collect()
}

Expand Down
28 changes: 0 additions & 28 deletions src/graph_types.rs

This file was deleted.

28 changes: 12 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,44 +64,40 @@
pub mod config;
pub mod error;
pub mod export;
pub mod graph_types;
pub mod io;
pub mod models;
pub mod polynomial;
pub(crate) mod polynomial;
pub mod registry;
pub mod rules;
pub mod solvers;
pub mod testing;
pub mod topology;
pub mod traits;
pub mod truth_table;
#[allow(dead_code)]
pub(crate) mod truth_table;
pub mod types;
pub mod variant;

/// Prelude module for convenient imports.
pub mod prelude {
pub use crate::config::{
bits_to_config, config_to_bits, config_to_index, index_to_config, ConfigIterator,
};
pub use crate::error::{ProblemError, Result};
// Problem types
pub use crate::models::graph::{
KColoring, MaxCut, MaximalIS, MaximumClique, MaximumIndependentSet, MaximumMatching,
MinimumDominatingSet, MinimumVertexCover, TravelingSalesman,
};
pub use crate::models::optimization::{
Comparison, LinearConstraint, ObjectiveSense, SpinGlass, VarBounds, ILP, QUBO,
};
pub use crate::models::optimization::{SpinGlass, QUBO};
pub use crate::models::satisfiability::{CNFClause, KSatisfiability, Satisfiability};
pub use crate::models::set::{MaximumSetPacking, MinimumSetCovering};
pub use crate::models::specialized::{BicliqueCover, CircuitSAT, Factoring, PaintShop, BMF};
pub use crate::registry::{ComplexityClass, ProblemInfo, ProblemMetadata};
pub use crate::models::specialized::{BicliqueCover, BMF, CircuitSAT, Factoring, PaintShop};

// Core traits
pub use crate::rules::{ReduceTo, ReductionResult};
pub use crate::solvers::{BruteForce, Solver};
pub use crate::traits::{problem_size, OptimizationProblem, Problem, SatisfactionProblem};
pub use crate::types::{
Direction, NumericSize, One, ProblemSize, SolutionSize, Unweighted, WeightElement,
};
pub use crate::variant::{CastToParent, KValue, VariantParam, K1, K2, K3, K4, K5, KN};

// Types
pub use crate::error::{ProblemError, Result};
pub use crate::types::{Direction, One, ProblemSize, SolutionSize, Unweighted};
}

// Re-export commonly used items at crate root
Expand Down
7 changes: 6 additions & 1 deletion src/models/graph/kcoloring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ impl<K: KValue, G: Graph> KColoring<K, G> {
self.num_colors
}

/// Check if a configuration is a valid coloring.
pub fn is_valid_solution(&self, config: &[usize]) -> bool {
is_valid_coloring(&self.graph, config, self.num_colors)
}

/// Check if a coloring is valid.
fn is_valid_coloring(&self, config: &[usize]) -> bool {
for (u, v) in self.graph.edges() {
Expand Down Expand Up @@ -150,7 +155,7 @@ impl<K: KValue, G: Graph + VariantParam> SatisfactionProblem for KColoring<K, G>
///
/// # Panics
/// Panics if `coloring.len() != graph.num_vertices()`.
pub fn is_valid_coloring<G: Graph>(graph: &G, coloring: &[usize], num_colors: usize) -> bool {
pub(crate) fn is_valid_coloring<G: Graph>(graph: &G, coloring: &[usize], num_colors: usize) -> bool {
assert_eq!(
coloring.len(),
graph.num_vertices(),
Expand Down
11 changes: 10 additions & 1 deletion src/models/graph/max_cut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ impl<G: Graph, W: Clone + Default> MaxCut<G, W> {
pub fn edge_weights(&self) -> Vec<W> {
self.edge_weights.clone()
}

/// Compute the cut size for a given partition configuration.
pub fn cut_size(&self, config: &[usize]) -> W::Sum
where
W: WeightElement,
{
let partition: Vec<bool> = config.iter().map(|&c| c != 0).collect();
cut_size(&self.graph, &self.edge_weights, &partition)
}
}

impl<G, W> Problem for MaxCut<G, W>
Expand Down Expand Up @@ -186,7 +195,7 @@ where
/// * `graph` - The graph structure
/// * `edge_weights` - Weights for each edge (same order as `graph.edges()`)
/// * `partition` - Boolean slice indicating which set each vertex belongs to
pub fn cut_size<G, W>(graph: &G, edge_weights: &[W], partition: &[bool]) -> W::Sum
pub(crate) fn cut_size<G, W>(graph: &G, edge_weights: &[W], partition: &[bool]) -> W::Sum
where
G: Graph,
W: WeightElement,
Expand Down
8 changes: 7 additions & 1 deletion src/models/graph/maximal_is.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ impl<G: Graph, W: Clone + Default> MaximalIS<G, W> {
!W::IS_UNIT
}

/// Check if a configuration is a valid maximal independent set.
pub fn is_valid_solution(&self, config: &[usize]) -> bool {
self.is_maximal(config)
}

/// Check if a configuration is an independent set.
fn is_independent(&self, config: &[usize]) -> bool {
for (u, v) in self.graph.edges() {
Expand Down Expand Up @@ -177,7 +182,8 @@ where
///
/// # Panics
/// Panics if `selected.len() != graph.num_vertices()`.
pub fn is_maximal_independent_set<G: Graph>(graph: &G, selected: &[bool]) -> bool {
#[cfg(test)]
pub(crate) fn is_maximal_independent_set<G: Graph>(graph: &G, selected: &[bool]) -> bool {
assert_eq!(
selected.len(),
graph.num_vertices(),
Expand Down
8 changes: 7 additions & 1 deletion src/models/graph/maximum_clique.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ impl<G: Graph, W: Clone + Default> MaximumClique<G, W> {
{
!W::IS_UNIT
}

/// Check if a configuration is a valid clique.
pub fn is_valid_solution(&self, config: &[usize]) -> bool {
is_clique_config(&self.graph, config)
}
}

impl<G, W> Problem for MaximumClique<G, W>
Expand Down Expand Up @@ -168,7 +173,8 @@ fn is_clique_config<G: Graph>(graph: &G, config: &[usize]) -> bool {
///
/// # Panics
/// Panics if `selected.len() != graph.num_vertices()`.
pub fn is_clique<G: Graph>(graph: &G, selected: &[bool]) -> bool {
#[cfg(test)]
pub(crate) fn is_clique<G: Graph>(graph: &G, selected: &[bool]) -> bool {
assert_eq!(
selected.len(),
graph.num_vertices(),
Expand Down
8 changes: 7 additions & 1 deletion src/models/graph/maximum_independent_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ impl<G: Graph, W: Clone + Default> MaximumIndependentSet<G, W> {
{
!W::IS_UNIT
}

/// Check if a configuration is a valid independent set.
pub fn is_valid_solution(&self, config: &[usize]) -> bool {
is_independent_set_config(&self.graph, config)
}
}

impl<G, W> Problem for MaximumIndependentSet<G, W>
Expand Down Expand Up @@ -157,7 +162,8 @@ fn is_independent_set_config<G: Graph>(graph: &G, config: &[usize]) -> bool {
///
/// # Panics
/// Panics if `selected.len() != graph.num_vertices()`.
pub fn is_independent_set<G: Graph>(graph: &G, selected: &[bool]) -> bool {
#[cfg(test)]
pub(crate) fn is_independent_set<G: Graph>(graph: &G, selected: &[bool]) -> bool {
assert_eq!(
selected.len(),
graph.num_vertices(),
Expand Down
8 changes: 7 additions & 1 deletion src/models/graph/maximum_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ impl<G: Graph, W: Clone + Default> MaximumMatching<G, W> {
}

/// Check if a configuration is a valid matching.
pub fn is_valid_solution(&self, config: &[usize]) -> bool {
self.is_valid_matching(config)
}

/// Check if a configuration is a valid matching (internal).
fn is_valid_matching(&self, config: &[usize]) -> bool {
let mut vertex_used = vec![false; self.graph.num_vertices()];

Expand Down Expand Up @@ -213,7 +218,8 @@ where
///
/// # Panics
/// Panics if `selected.len() != graph.num_edges()`.
pub fn is_matching<G: Graph>(graph: &G, selected: &[bool]) -> bool {
#[cfg(test)]
pub(crate) fn is_matching<G: Graph>(graph: &G, selected: &[bool]) -> bool {
assert_eq!(
selected.len(),
graph.num_edges(),
Expand Down
Loading