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;