1use fugue::{addr, ChoiceValue, Trace};
7use rand::Rng;
8use serde::{Deserialize, Serialize};
9
10use crate::error::GenomeError;
11use crate::genome::bounds::MultiBounds;
12use crate::genome::traits::{BinaryGenome, EvolutionaryGenome};
13
14#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
19pub struct BitString {
20 bits: Vec<bool>,
22}
23
24impl BitString {
25 pub fn new(bits: Vec<bool>) -> Self {
27 Self { bits }
28 }
29
30 pub fn zeros(length: usize) -> Self {
32 Self {
33 bits: vec![false; length],
34 }
35 }
36
37 pub fn ones(length: usize) -> Self {
39 Self {
40 bits: vec![true; length],
41 }
42 }
43
44 pub fn from_u64(value: u64, length: usize) -> Self {
46 assert!(length <= 64, "Length must be <= 64 for u64 conversion");
47 let bits = (0..length).map(|i| (value >> i) & 1 == 1).collect();
48 Self { bits }
49 }
50
51 pub fn to_u64(&self) -> Option<u64> {
53 if self.bits.len() > 64 {
54 return None;
55 }
56 let mut value = 0u64;
57 for (i, &bit) in self.bits.iter().enumerate() {
58 if bit {
59 value |= 1 << i;
60 }
61 }
62 Some(value)
63 }
64
65 pub fn len(&self) -> usize {
67 self.bits.len()
68 }
69
70 pub fn is_empty(&self) -> bool {
72 self.bits.is_empty()
73 }
74
75 pub fn get(&self, index: usize) -> Option<bool> {
77 self.bits.get(index).copied()
78 }
79
80 pub fn set(&mut self, index: usize, value: bool) {
82 if let Some(bit) = self.bits.get_mut(index) {
83 *bit = value;
84 }
85 }
86
87 pub fn flip(&mut self, index: usize) {
89 if let Some(bit) = self.bits.get_mut(index) {
90 *bit = !*bit;
91 }
92 }
93
94 pub fn flip_all(&mut self) {
96 for bit in &mut self.bits {
97 *bit = !*bit;
98 }
99 }
100
101 pub fn complement(&self) -> Self {
103 Self {
104 bits: self.bits.iter().map(|b| !b).collect(),
105 }
106 }
107
108 pub fn hamming_distance(&self, other: &Self) -> usize {
110 self.bits
111 .iter()
112 .zip(other.bits.iter())
113 .filter(|(a, b)| a != b)
114 .count()
115 }
116
117 pub fn and(&self, other: &Self) -> Result<Self, GenomeError> {
119 if self.bits.len() != other.bits.len() {
120 return Err(GenomeError::DimensionMismatch {
121 expected: self.bits.len(),
122 actual: other.bits.len(),
123 });
124 }
125 Ok(Self {
126 bits: self
127 .bits
128 .iter()
129 .zip(other.bits.iter())
130 .map(|(a, b)| *a && *b)
131 .collect(),
132 })
133 }
134
135 pub fn or(&self, other: &Self) -> Result<Self, GenomeError> {
137 if self.bits.len() != other.bits.len() {
138 return Err(GenomeError::DimensionMismatch {
139 expected: self.bits.len(),
140 actual: other.bits.len(),
141 });
142 }
143 Ok(Self {
144 bits: self
145 .bits
146 .iter()
147 .zip(other.bits.iter())
148 .map(|(a, b)| *a || *b)
149 .collect(),
150 })
151 }
152
153 pub fn xor(&self, other: &Self) -> Result<Self, GenomeError> {
155 if self.bits.len() != other.bits.len() {
156 return Err(GenomeError::DimensionMismatch {
157 expected: self.bits.len(),
158 actual: other.bits.len(),
159 });
160 }
161 Ok(Self {
162 bits: self
163 .bits
164 .iter()
165 .zip(other.bits.iter())
166 .map(|(a, b)| *a ^ *b)
167 .collect(),
168 })
169 }
170}
171
172impl EvolutionaryGenome for BitString {
173 type Allele = bool;
174 type Phenotype = Vec<bool>;
175
176 fn to_trace(&self) -> Trace {
180 let mut trace = Trace::default();
181 for (i, &bit) in self.bits.iter().enumerate() {
182 trace.insert_choice(addr!("bit", i), ChoiceValue::Bool(bit), 0.0);
183 }
184 trace
185 }
186
187 fn from_trace(trace: &Trace) -> Result<Self, GenomeError> {
191 let mut bits = Vec::new();
192 let mut i = 0;
193 while let Some(val) = trace.get_bool(&addr!("bit", i)) {
194 bits.push(val);
195 i += 1;
196 }
197 if bits.is_empty() {
198 return Err(GenomeError::InvalidStructure(
199 "No bits found in trace".to_string(),
200 ));
201 }
202 Ok(Self { bits })
203 }
204
205 fn decode(&self) -> Self::Phenotype {
206 self.bits.clone()
207 }
208
209 fn dimension(&self) -> usize {
210 self.bits.len()
211 }
212
213 fn generate<R: Rng>(rng: &mut R, bounds: &MultiBounds) -> Self {
214 let bits = (0..bounds.dimension()).map(|_| rng.gen()).collect();
215 Self { bits }
216 }
217
218 fn as_slice(&self) -> Option<&[bool]> {
219 Some(&self.bits)
220 }
221
222 fn as_mut_slice(&mut self) -> Option<&mut [bool]> {
223 Some(&mut self.bits)
224 }
225
226 fn distance(&self, other: &Self) -> f64 {
227 self.hamming_distance(other) as f64
228 }
229
230 fn trace_prefix() -> &'static str {
231 "bit"
232 }
233}
234
235impl BinaryGenome for BitString {
236 fn bits(&self) -> &[bool] {
237 &self.bits
238 }
239
240 fn bits_mut(&mut self) -> &mut [bool] {
241 &mut self.bits
242 }
243
244 fn from_bits(bits: Vec<bool>) -> Result<Self, GenomeError> {
245 Ok(Self { bits })
246 }
247}
248
249impl std::ops::Index<usize> for BitString {
250 type Output = bool;
251
252 fn index(&self, index: usize) -> &Self::Output {
253 &self.bits[index]
254 }
255}
256
257impl From<Vec<bool>> for BitString {
258 fn from(bits: Vec<bool>) -> Self {
259 Self { bits }
260 }
261}
262
263impl From<BitString> for Vec<bool> {
264 fn from(genome: BitString) -> Self {
265 genome.bits
266 }
267}
268
269impl<const N: usize> From<[bool; N]> for BitString {
270 fn from(arr: [bool; N]) -> Self {
271 Self { bits: arr.to_vec() }
272 }
273}
274
275impl IntoIterator for BitString {
276 type Item = bool;
277 type IntoIter = std::vec::IntoIter<bool>;
278
279 fn into_iter(self) -> Self::IntoIter {
280 self.bits.into_iter()
281 }
282}
283
284impl<'a> IntoIterator for &'a BitString {
285 type Item = &'a bool;
286 type IntoIter = std::slice::Iter<'a, bool>;
287
288 fn into_iter(self) -> Self::IntoIter {
289 self.bits.iter()
290 }
291}
292
293impl std::fmt::Display for BitString {
294 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
295 for bit in &self.bits {
296 write!(f, "{}", if *bit { '1' } else { '0' })?;
297 }
298 Ok(())
299 }
300}
301
302#[cfg(test)]
303mod tests {
304 use super::*;
305 use fugue::addr;
306
307 #[test]
308 fn test_bit_string_new() {
309 let bs = BitString::new(vec![true, false, true]);
310 assert_eq!(bs.len(), 3);
311 assert_eq!(bs.bits(), &[true, false, true]);
312 }
313
314 #[test]
315 fn test_bit_string_zeros() {
316 let bs = BitString::zeros(5);
317 assert_eq!(bs.len(), 5);
318 assert!(bs.bits().iter().all(|&b| !b));
319 assert_eq!(bs.count_ones(), 0);
320 assert_eq!(bs.count_zeros(), 5);
321 }
322
323 #[test]
324 fn test_bit_string_ones() {
325 let bs = BitString::ones(5);
326 assert_eq!(bs.len(), 5);
327 assert!(bs.bits().iter().all(|&b| b));
328 assert_eq!(bs.count_ones(), 5);
329 assert_eq!(bs.count_zeros(), 0);
330 }
331
332 #[test]
333 fn test_bit_string_from_u64() {
334 let bs = BitString::from_u64(0b101, 4);
335 assert_eq!(bs.bits(), &[true, false, true, false]);
336 }
337
338 #[test]
339 fn test_bit_string_to_u64() {
340 let bs = BitString::new(vec![true, false, true, false]);
341 assert_eq!(bs.to_u64(), Some(0b0101));
342
343 let long_bs = BitString::zeros(100);
344 assert_eq!(long_bs.to_u64(), None);
345 }
346
347 #[test]
348 fn test_bit_string_get_set() {
349 let mut bs = BitString::zeros(3);
350 assert_eq!(bs.get(0), Some(false));
351 assert_eq!(bs.get(3), None);
352
353 bs.set(1, true);
354 assert_eq!(bs.get(1), Some(true));
355 }
356
357 #[test]
358 fn test_bit_string_flip() {
359 let mut bs = BitString::zeros(3);
360 bs.flip(1);
361 assert_eq!(bs.bits(), &[false, true, false]);
362 }
363
364 #[test]
365 fn test_bit_string_flip_all() {
366 let mut bs = BitString::new(vec![true, false, true]);
367 bs.flip_all();
368 assert_eq!(bs.bits(), &[false, true, false]);
369 }
370
371 #[test]
372 fn test_bit_string_complement() {
373 let bs = BitString::new(vec![true, false, true]);
374 let comp = bs.complement();
375 assert_eq!(comp.bits(), &[false, true, false]);
376 }
377
378 #[test]
379 fn test_bit_string_hamming_distance() {
380 let bs1 = BitString::new(vec![true, false, true, false]);
381 let bs2 = BitString::new(vec![true, true, false, false]);
382 assert_eq!(bs1.hamming_distance(&bs2), 2);
383 }
384
385 #[test]
386 fn test_bit_string_and() {
387 let bs1 = BitString::new(vec![true, true, false, false]);
388 let bs2 = BitString::new(vec![true, false, true, false]);
389 let result = bs1.and(&bs2).unwrap();
390 assert_eq!(result.bits(), &[true, false, false, false]);
391 }
392
393 #[test]
394 fn test_bit_string_or() {
395 let bs1 = BitString::new(vec![true, true, false, false]);
396 let bs2 = BitString::new(vec![true, false, true, false]);
397 let result = bs1.or(&bs2).unwrap();
398 assert_eq!(result.bits(), &[true, true, true, false]);
399 }
400
401 #[test]
402 fn test_bit_string_xor() {
403 let bs1 = BitString::new(vec![true, true, false, false]);
404 let bs2 = BitString::new(vec![true, false, true, false]);
405 let result = bs1.xor(&bs2).unwrap();
406 assert_eq!(result.bits(), &[false, true, true, false]);
407 }
408
409 #[test]
410 fn test_bit_string_dimension_mismatch() {
411 let bs1 = BitString::zeros(3);
412 let bs2 = BitString::zeros(4);
413 assert!(bs1.and(&bs2).is_err());
414 assert!(bs1.or(&bs2).is_err());
415 assert!(bs1.xor(&bs2).is_err());
416 }
417
418 #[test]
419 fn test_bit_string_generate() {
420 let mut rng = rand::thread_rng();
421 let bounds = MultiBounds::symmetric(1.0, 10);
422 let bs = BitString::generate(&mut rng, &bounds);
423 assert_eq!(bs.len(), 10);
424 }
425
426 #[test]
427 fn test_bit_string_distance() {
428 let bs1 = BitString::new(vec![true, false, true, false]);
429 let bs2 = BitString::new(vec![true, true, false, false]);
430 assert_eq!(bs1.distance(&bs2), 2.0);
431 }
432
433 #[test]
434 fn test_bit_string_display() {
435 let bs = BitString::new(vec![true, false, true, true]);
436 assert_eq!(format!("{}", bs), "1011");
437 }
438
439 #[test]
440 fn test_bit_string_indexing() {
441 let bs = BitString::new(vec![true, false, true]);
442 assert!(bs[0]);
443 assert!(!bs[1]);
444 assert!(bs[2]);
445 }
446
447 #[test]
448 fn test_bit_string_from_array() {
449 let bs: BitString = [true, false, true].into();
450 assert_eq!(bs.bits(), &[true, false, true]);
451 }
452
453 #[test]
454 fn test_bit_string_serialization() {
455 let bs = BitString::new(vec![true, false, true]);
456 let serialized = serde_json::to_string(&bs).unwrap();
457 let deserialized: BitString = serde_json::from_str(&serialized).unwrap();
458 assert_eq!(bs, deserialized);
459 }
460
461 #[test]
462 fn test_bit_string_decode() {
463 let bs = BitString::new(vec![true, false, true]);
464 let phenotype = bs.decode();
465 assert_eq!(phenotype, vec![true, false, true]);
466 }
467
468 #[test]
469 fn test_bit_string_to_trace() {
470 let bs = BitString::new(vec![true, false, true, false]);
471 let trace = bs.to_trace();
472
473 assert_eq!(trace.get_bool(&addr!("bit", 0)), Some(true));
474 assert_eq!(trace.get_bool(&addr!("bit", 1)), Some(false));
475 assert_eq!(trace.get_bool(&addr!("bit", 2)), Some(true));
476 assert_eq!(trace.get_bool(&addr!("bit", 3)), Some(false));
477 assert_eq!(trace.get_bool(&addr!("bit", 4)), None);
478 }
479
480 #[test]
481 fn test_bit_string_from_trace() {
482 let mut trace = Trace::default();
483 trace.insert_choice(addr!("bit", 0), ChoiceValue::Bool(true), 0.0);
484 trace.insert_choice(addr!("bit", 1), ChoiceValue::Bool(false), 0.0);
485 trace.insert_choice(addr!("bit", 2), ChoiceValue::Bool(true), 0.0);
486
487 let bs = BitString::from_trace(&trace).unwrap();
488 assert_eq!(bs.bits(), &[true, false, true]);
489 }
490
491 #[test]
492 fn test_bit_string_trace_roundtrip() {
493 let original = BitString::new(vec![true, false, true, true, false]);
494 let trace = original.to_trace();
495 let recovered = BitString::from_trace(&trace).unwrap();
496 assert_eq!(original, recovered);
497 }
498
499 #[test]
500 fn test_bit_string_from_trace_empty() {
501 let trace = Trace::default();
502 let result = BitString::from_trace(&trace);
503 assert!(result.is_err());
504 }
505}