problemreductions/registry/
dyn_problem.rs1use serde::Serialize;
2use serde_json::Value;
3use std::any::Any;
4use std::collections::BTreeMap;
5use std::fmt;
6
7use crate::traits::Problem;
8
9pub fn format_metric<T>(metric: &T) -> String
15where
16 T: fmt::Display,
17{
18 metric.to_string()
19}
20
21pub trait DynProblem: Any {
25 fn evaluate_dyn(&self, config: &[usize]) -> String;
27 fn evaluate_json(&self, config: &[usize]) -> Value;
29 fn serialize_json(&self) -> Value;
31 fn as_any(&self) -> &dyn Any;
33 fn dims_dyn(&self) -> Vec<usize>;
35 fn problem_name(&self) -> &'static str;
37 fn variant_map(&self) -> BTreeMap<String, String>;
39 fn num_variables_dyn(&self) -> usize;
41}
42
43impl<T> DynProblem for T
44where
45 T: Problem + Serialize + 'static,
46 T::Value: fmt::Display + Serialize,
47{
48 fn evaluate_dyn(&self, config: &[usize]) -> String {
49 format_metric(&self.evaluate(config))
50 }
51
52 fn evaluate_json(&self, config: &[usize]) -> Value {
53 serde_json::to_value(self.evaluate(config)).expect("serialize metric failed")
54 }
55
56 fn serialize_json(&self) -> Value {
57 serde_json::to_value(self).expect("serialize failed")
58 }
59
60 fn as_any(&self) -> &dyn Any {
61 self
62 }
63
64 fn dims_dyn(&self) -> Vec<usize> {
65 self.dims()
66 }
67
68 fn problem_name(&self) -> &'static str {
69 T::NAME
70 }
71
72 fn variant_map(&self) -> BTreeMap<String, String> {
73 crate::export::variant_to_map(T::variant())
74 }
75
76 fn num_variables_dyn(&self) -> usize {
77 self.num_variables()
78 }
79}
80
81pub type SolveValueFn = fn(&dyn Any) -> String;
83
84pub type SolveWitnessFn = fn(&dyn Any) -> Option<(Vec<usize>, String)>;
86
87pub struct LoadedDynProblem {
91 inner: Box<dyn DynProblem>,
92 solve_value_fn: SolveValueFn,
93 solve_witness_fn: SolveWitnessFn,
94}
95
96impl std::fmt::Debug for LoadedDynProblem {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.debug_struct("LoadedDynProblem")
99 .field("name", &self.inner.problem_name())
100 .finish()
101 }
102}
103
104impl LoadedDynProblem {
105 pub fn new(
107 inner: Box<dyn DynProblem>,
108 solve_value_fn: SolveValueFn,
109 solve_witness_fn: SolveWitnessFn,
110 ) -> Self {
111 Self {
112 inner,
113 solve_value_fn,
114 solve_witness_fn,
115 }
116 }
117
118 pub fn solve_brute_force_value(&self) -> String {
120 (self.solve_value_fn)(self.inner.as_any())
121 }
122
123 pub fn solve_brute_force_witness(&self) -> Option<(Vec<usize>, String)> {
125 (self.solve_witness_fn)(self.inner.as_any())
126 }
127
128 pub fn solve_brute_force(&self) -> Option<(Vec<usize>, String)> {
130 self.solve_brute_force_witness()
131 }
132}
133
134impl std::ops::Deref for LoadedDynProblem {
135 type Target = dyn DynProblem;
136
137 fn deref(&self) -> &(dyn DynProblem + 'static) {
138 &*self.inner
139 }
140}