dtrees_rs/algorithms/optimal/rules/
core.rs1use serde::{Deserialize, Serialize};
2use std::fmt::{Debug, Display};
3
4#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, Eq, PartialEq)]
6pub enum Reason {
7 Done,
9 TimeLimitReached,
11 LowerBoundConstrained,
13 MaxDepthReached,
15 NotEnoughSupport,
17 NoCandidates,
19 PureNode,
21 FromSpecializedAlgorithm,
23 RuleReason,
25 #[default]
27 None,
28}
29
30#[derive(Debug, Clone)]
32pub struct RuleResult {
33 pub continue_search: bool,
35 pub modified_bound: Option<f64>,
37 pub reason: Reason,
39 pub optimal: Option<bool>,
41 pub leaf: Option<bool>,
43}
44
45impl RuleResult {
46 pub fn continue_search() -> Self {
48 Self {
49 continue_search: true,
50 modified_bound: None,
51 reason: Reason::None,
52 optimal: None,
53 leaf: None,
54 }
55 }
56
57 pub fn stop_search(reason: Reason) -> Self {
59 Self {
60 continue_search: false,
61 modified_bound: None,
62 reason,
63 optimal: None,
64 leaf: None,
65 }
66 }
67
68 pub fn stop_with_bound(bound: f64, reason: Reason) -> Self {
70 Self {
71 continue_search: false,
72 modified_bound: Some(bound),
73 reason,
74 optimal: None,
75 leaf: None,
76 }
77 }
78
79 pub fn optimal(mut self) -> Self {
81 self.optimal = Some(true);
82 self
83 }
84
85 pub fn leaf(mut self) -> Self {
87 self.leaf = Some(true);
88 self
89 }
90
91 pub fn with_reason(mut self, reason: Reason) -> Self {
93 self.reason = reason;
94 self
95 }
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
100pub enum RuleState {
101 Active,
102 Relaxed,
103 Disabled,
104}
105
106impl Display for RuleState {
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 match self {
109 RuleState::Active => write!(f, "Active"),
110 RuleState::Relaxed => write!(f, "Relaxed"),
111 RuleState::Disabled => write!(f, "Disabled"),
112 }
113 }
114}
115
116#[derive(Debug)]
118pub struct RuleContext {
119 pub depth: usize,
121 pub upper_bound: f64,
123 pub node_lower_bound: f64,
125 pub node_upper_bound: f64,
127 pub item: usize,
129 pub support: usize,
131 pub position: usize,
133 pub discrepancy: usize,
135 pub gain: f64,
138 pub error: f64,
140 pub leaf_error: f64,
142}
143
144impl Default for RuleContext {
145 fn default() -> Self {
146 Self {
147 depth: 0,
148 upper_bound: 0.0,
149 node_lower_bound: 0.0,
150 node_upper_bound: f64::INFINITY,
151 item: 0,
152 support: 0,
153 position: 0,
154 discrepancy: 0,
155 gain: 0.0,
156 error: f64::INFINITY,
157 leaf_error: f64::INFINITY,
158 }
159 }
160}
161
162impl RuleContext {
163 pub fn depth(&mut self, depth: usize) {
164 self.depth = depth;
165 }
166 pub fn upper_bound(&mut self, upper_bound: f64) {
167 self.upper_bound = upper_bound;
168 }
169
170 pub fn node_lower_bound(&mut self, node_lower_bound: f64) {
171 self.node_lower_bound = node_lower_bound;
172 }
173
174 pub fn node_upper_bound(&mut self, node_upper_bound: f64) {
175 self.node_upper_bound = node_upper_bound;
176 }
177
178 pub fn item(&mut self, item: usize) {
179 self.item = item;
180 }
181
182 pub fn support(&mut self, support: usize) {
183 self.support = support;
184 }
185
186 pub fn position(&mut self, position: usize) {
187 self.position = position;
188 }
189
190 pub fn gain(&mut self, gain: f64) {
191 self.gain = gain;
192 }
193
194 pub fn error(&mut self, error: f64) {
195 self.error = error;
196 }
197
198 pub fn leaf_error(&mut self, error: f64) {
199 self.leaf_error = error;
200 }
201
202 pub fn discrepancy(&mut self, discrepancy: usize) {
203 self.discrepancy = discrepancy;
204 }
205}
206
207pub trait Rule: std::any::Any + Send + Sync {
209 fn evaluate(&self, context: &RuleContext) -> RuleResult;
211
212 fn priority(&self) -> u8;
214
215 fn description(&self) -> String;
217
218 fn state(&self) -> RuleState;
220
221 fn is_active(&self) -> bool {
223 self.state() == RuleState::Active
224 }
225
226 fn activate(&mut self) {}
228
229 fn is_relaxable(&self) -> bool {
232 true
233 }
234
235 fn deactivate(&mut self) {}
237
238 fn relax(&mut self) {}
241
242 fn reset(&mut self) {}
244
245 fn delay(&self) -> u8 {
247 0
248 }
249
250 fn as_any(&self) -> &dyn std::any::Any;
252
253 fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
255}