1use crate::prelude::*;
2use std::ops::{Index, IndexMut};
3
4#[derive(Clone, Debug)]
6pub enum Var {
7 VarI { min: i32, max: i32 },
9 VarF { min: f32, max: f32 },
11}
12
13#[derive(Copy, Clone, Debug)]
14pub enum Val {
15 ValI(i32),
17 ValF(f32),
19}
20
21impl Val {
22 pub const fn int(value: i32) -> Self {
24 Val::ValI(value)
25 }
26
27 pub const fn float(value: f32) -> Self {
29 Val::ValF(value)
30 }
31}
32
33impl From<i32> for Val {
34 fn from(value: i32) -> Self {
35 Val::ValI(value)
36 }
37}
38
39impl From<f32> for Val {
40 fn from(value: f32) -> Self {
41 Val::ValF(value)
42 }
43}
44
45impl PartialEq for Val {
46 fn eq(&self, other: &Self) -> bool {
47 match (self, other) {
48 (Val::ValI(a), Val::ValI(b)) => a == b,
49 (Val::ValF(a), Val::ValF(b)) => (a - b).abs() < VAR_EPSILON,
50 _ => false,
51 }
52 }
53}
54
55impl Eq for Val {}
56
57impl PartialOrd for Val {
58 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
59 match (self, other) {
60 (Val::ValI(a), Val::ValI(b)) => a.partial_cmp(b),
61 (Val::ValF(a), Val::ValF(b)) => a.partial_cmp(b),
62 (Val::ValI(a), Val::ValF(b)) => (*a as f32).partial_cmp(b),
63 (Val::ValF(a), Val::ValI(b)) => a.partial_cmp(&(*b as f32)),
64 }
65 }
66}
67
68impl Ord for Val {
69 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
70 self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal)
71 }
72}
73
74impl std::ops::Add for Val {
75 type Output = Val;
76
77 fn add(self, other: Val) -> Val {
78 match (self, other) {
79 (Val::ValI(a), Val::ValI(b)) => Val::ValI(a + b),
80 (Val::ValF(a), Val::ValF(b)) => Val::ValF(a + b),
81 (Val::ValI(a), Val::ValF(b)) => Val::ValF(a as f32 + b),
82 (Val::ValF(a), Val::ValI(b)) => Val::ValF(a + b as f32),
83 }
84 }
85}
86
87impl std::iter::Sum for Val {
88 fn sum<I: Iterator<Item = Val>>(iter: I) -> Self {
89 iter.fold(Val::ValI(0), |acc, x| acc + x)
90 }
91}
92
93impl std::ops::Sub for Val {
94 type Output = Val;
95
96 fn sub(self, other: Val) -> Val {
97 match (self, other) {
98 (Val::ValI(a), Val::ValI(b)) => Val::ValI(a - b),
99 (Val::ValF(a), Val::ValF(b)) => Val::ValF(a - b),
100 (Val::ValI(a), Val::ValF(b)) => Val::ValF(a as f32 - b),
101 (Val::ValF(a), Val::ValI(b)) => Val::ValF(a - b as f32),
102 }
103 }
104}
105
106const VAR_EPSILON: f32 = 1e-6;
107impl Var {
108 pub fn is_assigned(&self) -> bool {
110 match self {
111 Var::VarI { min, max } => min == max,
112 Var::VarF { min, max } => close_enough(*min, *max, VAR_EPSILON),
113 }
114 }
115
116 pub fn mid(&self) -> Val {
118 match self {
119 Var::VarI { min, max } => Val::ValI(min + (max - min) / 2),
120 Var::VarF { min, max } => Val::ValF(*min + (*max - *min) / 2.0),
121 }
122 }
123
124 pub fn get_assignment(&self) -> Val {
130 assert!(self.is_assigned());
131
132 match self {
133 Var::VarI { min, .. } => Val::ValI(*min),
134 Var::VarF { min, .. } => Val::ValF(*min),
135 }
136 }
137}
138
139#[derive(Clone, Debug, Default)]
141pub struct Vars(Vec<Var>);
142
143impl Vars {
144 pub fn new_var_with_bounds(&mut self, min: Val, max: Val) -> VarId {
146 let v = VarId(self.0.len());
147
148 match (min, max) {
149 (Val::ValI(min), Val::ValI(max)) => self.0.push(Var::VarI { min, max }),
150 (Val::ValF(min), Val::ValF(max)) => self.0.push(Var::VarF { min, max }),
151 _ => debug_assert!(false, "Mismatched variable types"),
152 }
153
154 v
155 }
156
157 pub fn get_unassigned_var(&self) -> Option<VarId> {
159 self.0.iter().position(|var| !var.is_assigned()).map(VarId)
160 }
161
162 pub fn is_assigned_all(&self) -> bool {
164 self.get_unassigned_var().is_none()
165 }
166
167 pub fn into_solution(self) -> Solution {
173 let values: Vec<_> = self.0.into_iter().map(|v| v.get_assignment()).collect();
175
176 Solution::from(values)
177 }
178}
179
180#[derive(Clone, Copy, Debug)]
182pub struct VarId(usize);
183
184impl Index<VarId> for Vars {
185 type Output = Var;
186
187 fn index(&self, index: VarId) -> &Self::Output {
188 &self.0[index.0]
189 }
190}
191
192impl IndexMut<VarId> for Vars {
193 fn index_mut(&mut self, index: VarId) -> &mut Self::Output {
194 &mut self.0[index.0]
195 }
196}
197
198impl Index<VarId> for Vec<Var> {
199 type Output = Var;
200
201 fn index(&self, index: VarId) -> &Self::Output {
202 &self[index.0]
203 }
204}
205
206impl IndexMut<VarId> for Vec<Var> {
207 fn index_mut(&mut self, index: VarId) -> &mut Self::Output {
208 &mut self[index.0]
209 }
210}
211
212impl Index<VarId> for Vec<Vec<PropId>> {
213 type Output = Vec<PropId>;
214
215 fn index(&self, index: VarId) -> &Self::Output {
216 &self[index.0]
217 }
218}
219
220impl IndexMut<VarId> for Vec<Vec<PropId>> {
221 fn index_mut(&mut self, index: VarId) -> &mut Self::Output {
222 &mut self[index.0]
223 }
224}
225
226impl Index<VarId> for Vec<Val> {
227 type Output = Val;
228
229 fn index(&self, index: VarId) -> &Self::Output {
230 &self[index.0]
231 }
232}
233
234impl IndexMut<VarId> for Vec<Val> {
235 fn index_mut(&mut self, index: VarId) -> &mut Self::Output {
236 &mut self[index.0]
237 }
238}
239
240#[derive(Clone, Copy, Debug)]
242pub struct VarIdBin(pub(crate) VarId);
243
244