Skip to main content

problemreductions/
traits.rs

1//! Core traits for problem definitions.
2
3use crate::types::ProblemParameters;
4
5/// Failure while evaluating one configuration of a valid problem instance.
6#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
7pub enum EvaluationError {
8    #[error("invalid configuration: {0}")]
9    InvalidConfiguration(String),
10    #[error("integer overflow while {0}")]
11    IntegerOverflow(String),
12    #[error("inexact integer-to-float conversion while {0}")]
13    InexactFloatConversion(String),
14    #[error("non-finite floating-point result while {0}")]
15    NonFiniteResult(String),
16}
17
18/// Minimal problem trait — a problem maps a solution to a value or an
19/// evaluation error.
20///
21/// This trait defines the interface for computational problems that can be
22/// evaluated or reduced to other problems.
23pub trait Problem: Clone {
24    /// Base name of this problem type (e.g., "MaximumIndependentSet").
25    const NAME: &'static str;
26    /// Mathematical witness type for this problem.
27    type Solution;
28    /// The evaluation value type.
29    type Value: Clone;
30    /// Canonical parameter names for this problem model.
31    fn parameter_names() -> &'static [&'static str];
32    /// Measure the complete canonical parameters of this concrete instance.
33    fn parameters(&self) -> ProblemParameters;
34    /// Evaluate the problem on a solution.
35    fn evaluate(&self, solution: &Self::Solution) -> Result<Self::Value, EvaluationError>;
36    /// Returns variant attributes derived from type parameters.
37    ///
38    /// Used for generating variant IDs in the reduction graph schema.
39    /// Returns pairs like `[("graph", "SimpleGraph"), ("weight", "i64")]`.
40    fn variant() -> Vec<(&'static str, &'static str)>;
41
42    /// Look up this problem's catalog entry.
43    ///
44    /// Returns the full [`crate::registry::ProblemType`] metadata from the catalog registry.
45    /// The default implementation uses `Self::NAME` to perform the lookup.
46    fn problem_type() -> crate::registry::ProblemType {
47        crate::registry::find_problem_type(Self::NAME)
48            .unwrap_or_else(|| panic!("no catalog entry for Problem::NAME = {:?}", Self::NAME))
49    }
50}
51
52/// Define a problem's canonical parameters from inherent getter methods.
53#[macro_export]
54macro_rules! problem_parameters {
55    ($(($name:literal, $getter:ident)),+ $(,)?) => {
56        fn parameter_names() -> &'static [&'static str] {
57            &[$($name),+]
58        }
59
60        fn parameters(&self) -> $crate::types::ProblemParameters {
61            $crate::types::ProblemParameters::new(vec![
62                $(($name, u64::try_from(self.$getter()).expect(concat!(
63                    "parameter getter `", $name, "` violated its u64 invariant"
64                )))),+
65            ])
66        }
67    };
68}
69
70/// Marker trait for explicitly declared problem variants.
71///
72/// Implemented automatically by `declare_variants!` for each concrete type.
73/// The [`#[reduction]`] proc macro checks this trait at compile time to ensure
74/// all reduction source/target types have been declared.
75pub trait DeclaredVariant {}
76
77#[cfg(test)]
78#[path = "unit_tests/traits.rs"]
79mod tests;