1use std::any::Any;
2use std::cell::Cell;
3use std::marker::PhantomData;
4
5use fastrand::Rng;
6
7use super::CrossoverStep;
8use crate::{Mutator, CROSSOVER_RATE};
9
10pub struct FixedLenVecMutator<T, M>
14where
15 T: Clone + 'static,
16 M: Mutator<T>,
17{
18 pub rng: Rng,
19 mutators: Vec<M>,
20 initialized: Cell<bool>,
21 min_complexity: Cell<f64>,
22 max_complexity: Cell<f64>,
23 search_space_complexity: Cell<f64>,
24 has_inherent_complexity: bool,
25 inherent_complexity: Cell<f64>,
26 _phantom: PhantomData<T>,
27}
28impl<T, M> FixedLenVecMutator<T, M>
29where
30 T: Clone + 'static,
31 M: Mutator<T> + Clone,
32{
33 #[coverage(off)]
34 pub fn new_with_repeated_mutator(mutator: M, len: usize) -> Self {
35 Self::new(vec![mutator; len])
36 }
37}
38
39impl<T, M> FixedLenVecMutator<T, M>
40where
41 T: Clone + 'static,
42 M: Mutator<T>,
43{
44 #[coverage(off)]
71 pub fn new_without_inherent_complexity(mutators: Vec<M>) -> Self {
72 assert!(!mutators.is_empty());
73
74 Self {
75 rng: Rng::default(),
76 mutators,
77 initialized: Cell::new(false),
78 min_complexity: Cell::new(std::f64::INFINITY),
79 max_complexity: Cell::default(),
80 search_space_complexity: Cell::default(),
81 has_inherent_complexity: false,
82 inherent_complexity: Cell::default(),
83 _phantom: PhantomData,
84 }
85 }
86
87 #[coverage(off)]
88 pub fn new(mutators: Vec<M>) -> Self {
89 assert!(!mutators.is_empty());
90
91 Self {
92 rng: Rng::default(),
93 mutators,
94 initialized: Cell::new(false),
95 min_complexity: Cell::new(std::f64::INFINITY),
96 max_complexity: Cell::new(std::f64::INFINITY),
97 search_space_complexity: Cell::new(std::f64::INFINITY),
98 has_inherent_complexity: true,
99 inherent_complexity: Cell::default(),
100 _phantom: PhantomData,
101 }
102 }
103}
104
105#[derive(Clone)]
106pub struct MutationStep<T, S> {
107 inner: Vec<S>,
108 element_step: usize,
109 crossover_steps: Vec<CrossoverStep<T>>,
110}
111
112#[derive(Clone)]
113pub struct VecMutatorCache<C> {
114 inner: Vec<C>,
115 sum_cplx: f64,
116}
117impl<C> Default for VecMutatorCache<C> {
118 #[coverage(off)]
119 fn default() -> Self {
120 Self {
121 inner: Vec::new(),
122 sum_cplx: 0.0,
123 }
124 }
125}
126
127pub enum UnmutateVecToken<T: Clone + 'static, M: Mutator<T>> {
128 ReplaceElement(usize, T),
129 Element(usize, M::UnmutateToken),
130 Elements(Vec<(usize, M::UnmutateToken)>),
131 Replace(Vec<T>),
132}
133
134impl<T: Clone + 'static, M: Mutator<T>> FixedLenVecMutator<T, M> {
135 #[coverage(off)]
136 fn len(&self) -> usize {
137 self.mutators.len()
138 }
139 #[coverage(off)]
140 fn mutate_elements(
141 &self,
142 value: &mut [T],
143 cache: &mut VecMutatorCache<M::Cache>,
144 idcs: &[usize],
145 current_cplx: f64,
146 max_cplx: f64,
147 ) -> (UnmutateVecToken<T, M>, f64) {
148 let mut cplx = current_cplx;
149 let mut tokens = vec![];
150 for &idx in idcs {
151 let spare_cplx = max_cplx - cplx;
152 let mutator = &self.mutators[idx];
153 let el = &mut value[idx];
154 let el_cache = &mut cache.inner[idx];
155
156 let old_cplx = mutator.complexity(el, el_cache);
157
158 let (token, new_cplx) = mutator.random_mutate(el, el_cache, spare_cplx + old_cplx);
159 tokens.push((idx, token));
160 cplx = cplx - old_cplx + new_cplx;
161 }
162 (UnmutateVecToken::Elements(tokens), cplx)
163 }
164 #[coverage(off)]
165 fn mutate_element(
166 &self,
167 value: &mut [T],
168 cache: &mut VecMutatorCache<M::Cache>,
169 step: &mut MutationStep<T, M::MutationStep>,
170 subvalue_provider: &dyn crate::SubValueProvider,
171 idx: usize,
172 current_cplx: f64,
173 spare_cplx: f64,
174 ) -> Option<(UnmutateVecToken<T, M>, f64)> {
175 let mutator = &self.mutators[idx];
176 let el = &mut value[idx];
177 let el_cache = &mut cache.inner[idx];
178 let el_step = &mut step.inner[idx];
179
180 let old_cplx = mutator.complexity(el, el_cache);
181
182 if let Some((token, new_cplx)) =
183 mutator.ordered_mutate(el, el_cache, el_step, subvalue_provider, spare_cplx + old_cplx)
184 {
185 Some((
186 UnmutateVecToken::Element(idx, token),
187 current_cplx - old_cplx + new_cplx,
188 ))
189 } else {
190 None
191 }
192 }
193
194 #[coverage(off)]
195 fn new_input_with_complexity(&self, target_cplx: f64) -> (Vec<T>, f64) {
196 let mut v = Vec::with_capacity(self.len());
197 let mut sum_cplx = 0.0;
198 let mut remaining_cplx = target_cplx;
199 let mut remaining_min_complexity = self.min_complexity();
200 for (i, mutator) in self.mutators.iter().enumerate() {
201 let mut max_cplx_element = (remaining_cplx / ((self.len() - i) as f64)) - remaining_min_complexity;
202 let min_cplx_el = mutator.min_complexity();
203 if min_cplx_el >= max_cplx_element {
204 max_cplx_element = min_cplx_el;
205 }
206 let (x, x_cplx) = mutator.random_arbitrary(max_cplx_element);
207 v.push(x);
208 sum_cplx += x_cplx;
209 remaining_cplx -= x_cplx;
210 remaining_min_complexity -= mutator.min_complexity();
211 }
212 (v, sum_cplx)
213 }
214}
215
216impl<T: Clone + 'static, M: Mutator<T>> Mutator<Vec<T>> for FixedLenVecMutator<T, M> {
217 #[doc(hidden)]
218 type Cache = VecMutatorCache<M::Cache>;
219 #[doc(hidden)]
220 type MutationStep = MutationStep<T, M::MutationStep>;
221 #[doc(hidden)]
222 type ArbitraryStep = ();
223 #[doc(hidden)]
224 type UnmutateToken = UnmutateVecToken<T, M>;
225
226 #[doc(hidden)]
227 #[coverage(off)]
228 fn initialize(&self) {
229 for mutator in self.mutators.iter() {
230 mutator.initialize();
231 }
232 let inherent_complexity = if self.has_inherent_complexity {
234 1.0 + if self.mutators[0].min_complexity() == 0.0 {
235 self.mutators.len() as f64
236 } else {
237 0.0
238 }
239 } else {
240 0.0
241 };
242
243 let max_complexity = self.mutators.iter().fold(
244 0.0,
245 #[coverage(off)]
246 |cplx, m| cplx + m.max_complexity(),
247 ) + inherent_complexity;
248 let min_complexity = self.mutators.iter().fold(
249 0.0,
250 #[coverage(off)]
251 |cplx, m| cplx + m.min_complexity(),
252 ) + inherent_complexity;
253 let search_space_complexity = self.mutators.iter().fold(
254 0.0,
255 #[coverage(off)]
256 |cplx, m| cplx + m.global_search_space_complexity(),
257 );
258 self.inherent_complexity.set(inherent_complexity);
259 self.min_complexity.set(min_complexity);
260 self.max_complexity.set(max_complexity);
261 self.search_space_complexity.set(search_space_complexity);
262
263 self.initialized.set(true);
264 }
265
266 #[doc(hidden)]
267 #[coverage(off)]
268 fn default_arbitrary_step(&self) -> Self::ArbitraryStep {}
269
270 #[doc(hidden)]
271 #[coverage(off)]
272 fn is_valid(&self, value: &Vec<T>) -> bool {
273 if value.len() != self.mutators.len() {
274 return false;
275 }
276 for (m, v) in self.mutators.iter().zip(value.iter()) {
277 if !m.is_valid(v) {
278 return false;
279 }
280 }
281 true
282 }
283
284 #[doc(hidden)]
285 #[coverage(off)]
286 fn validate_value(&self, value: &Vec<T>) -> Option<Self::Cache> {
287 if value.len() != self.mutators.len() {
288 return None;
289 }
290 let inner_caches: Vec<_> = value
291 .iter()
292 .zip(self.mutators.iter())
293 .map(
294 #[coverage(off)]
295 |(x, mutator)| mutator.validate_value(x),
296 )
297 .collect::<Option<_>>()?;
298
299 let sum_cplx = value.iter().zip(self.mutators.iter()).zip(inner_caches.iter()).fold(
300 0.0,
301 #[coverage(off)]
302 |cplx, ((v, mutator), cache)| cplx + mutator.complexity(v, cache),
303 );
304
305 let cache = VecMutatorCache {
306 inner: inner_caches,
307 sum_cplx,
308 };
309 Some(cache)
310 }
311
312 #[doc(hidden)]
313 #[coverage(off)]
314 fn default_mutation_step(&self, value: &Vec<T>, cache: &Self::Cache) -> Self::MutationStep {
315 let inner = value
316 .iter()
317 .zip(cache.inner.iter())
318 .zip(self.mutators.iter())
319 .map(
320 #[coverage(off)]
321 |((v, c), m)| m.default_mutation_step(v, c),
322 )
323 .collect::<Vec<_>>();
324 MutationStep {
325 inner,
326 element_step: 0,
327 crossover_steps: vec![CrossoverStep::default(); value.len()],
328 }
329 }
330
331 #[doc(hidden)]
332 #[coverage(off)]
333 fn global_search_space_complexity(&self) -> f64 {
334 self.search_space_complexity.get()
335 }
336
337 #[doc(hidden)]
338 #[coverage(off)]
339 fn max_complexity(&self) -> f64 {
340 self.max_complexity.get()
341 }
342
343 #[doc(hidden)]
344 #[coverage(off)]
345 fn min_complexity(&self) -> f64 {
346 self.min_complexity.get()
347 }
348
349 #[doc(hidden)]
350 #[coverage(off)]
351 fn complexity(&self, _value: &Vec<T>, cache: &Self::Cache) -> f64 {
352 cache.sum_cplx + self.inherent_complexity.get()
353 }
354
355 #[doc(hidden)]
356 #[coverage(off)]
357 fn ordered_arbitrary(&self, _step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(Vec<T>, f64)> {
358 if max_cplx < self.min_complexity() {
359 return None;
360 }
361 Some(self.random_arbitrary(max_cplx))
362 }
363
364 #[doc(hidden)]
365 #[coverage(off)]
366 fn random_arbitrary(&self, max_cplx: f64) -> (Vec<T>, f64) {
367 assert!(self.initialized.get());
368 let target_cplx = crate::mutators::gen_f64(&self.rng, 1.0..max_cplx);
369 let (v, sum_cplx) = self.new_input_with_complexity(target_cplx);
370 (v, sum_cplx + self.inherent_complexity.get())
371 }
372
373 #[doc(hidden)]
374 #[coverage(off)]
375 fn ordered_mutate(
376 &self,
377 value: &mut Vec<T>,
378 cache: &mut Self::Cache,
379 step: &mut Self::MutationStep,
380 subvalue_provider: &dyn crate::SubValueProvider,
381 max_cplx: f64,
382 ) -> Option<(Self::UnmutateToken, f64)> {
383 if max_cplx < self.min_complexity() {
384 return None;
385 }
386 if value.is_empty() || self.rng.usize(0..100) == 0 {
387 let (mut v, cplx) = self.random_arbitrary(max_cplx);
388 std::mem::swap(value, &mut v);
389 return Some((UnmutateVecToken::Replace(v), cplx));
390 }
391 if self.rng.u8(..CROSSOVER_RATE) == 0 {
392 let choice = self.rng.usize(..value.len());
393 let step = &mut step.crossover_steps[choice];
394 let old_el_cplx = self.mutators[choice].complexity(&value[choice], &cache.inner[choice]);
395 let current_cplx = self.complexity(value, cache);
396 let max_el_cplx = current_cplx - old_el_cplx - self.inherent_complexity.get();
397 if let Some((el, new_el_cplx)) = step.get_next_subvalue(subvalue_provider, max_el_cplx)
398 && self.mutators[choice].is_valid(el)
399 {
400 let mut el = el.clone();
401 std::mem::swap(&mut value[choice], &mut el);
402 let cplx = cache.sum_cplx - old_el_cplx + new_el_cplx + self.inherent_complexity.get();
403 let token = UnmutateVecToken::ReplaceElement(choice, el);
404 return Some((token, cplx));
405 }
406 }
407 let current_cplx = self.complexity(value, cache);
408 if value.len() > 1 && self.rng.usize(..20) == 0 {
409 let mut idcs = (0..value.len()).collect::<Vec<_>>();
410 self.rng.shuffle(&mut idcs);
411 let count = self.rng.usize(2..=value.len());
412 let idcs = &idcs[..count];
413 Some(self.mutate_elements(value, cache, idcs, current_cplx, max_cplx))
414 } else {
415 let spare_cplx = max_cplx - current_cplx - self.inherent_complexity.get();
416 let idx = step.element_step % value.len();
417 step.element_step += 1;
418 self.mutate_element(value, cache, step, subvalue_provider, idx, current_cplx, spare_cplx)
419 .or_else(
420 #[coverage(off)]
421 || Some(self.random_mutate(value, cache, max_cplx)),
422 )
423 }
424 }
425
426 #[doc(hidden)]
427 #[coverage(off)]
428 fn random_mutate(&self, value: &mut Vec<T>, cache: &mut Self::Cache, max_cplx: f64) -> (Self::UnmutateToken, f64) {
429 if value.is_empty() || self.rng.usize(0..100) == 0 {
430 let (mut v, cplx) = self.random_arbitrary(max_cplx);
431 std::mem::swap(value, &mut v);
432 return (UnmutateVecToken::Replace(v), cplx);
433 }
434 let current_cplx = self.complexity(value, cache);
435 if value.len() > 1 && self.rng.usize(..20) == 0 {
436 let mut idcs = (0..value.len()).collect::<Vec<_>>();
437 self.rng.shuffle(&mut idcs);
438 let count = self.rng.usize(2..=value.len());
439 let idcs = &idcs[..count];
440 return self.mutate_elements(value, cache, idcs, current_cplx, max_cplx);
441 }
442 let spare_cplx = max_cplx - current_cplx;
443
444 let idx = self.rng.usize(0..value.len());
445 let el = &mut value[idx];
446 let el_cache = &mut cache.inner[idx];
447
448 let old_el_cplx = self.mutators[idx].complexity(el, el_cache);
449 let (token, new_el_cplx) = self.mutators[idx].random_mutate(el, el_cache, spare_cplx + old_el_cplx);
450
451 (
452 UnmutateVecToken::Element(idx, token),
453 current_cplx - old_el_cplx + new_el_cplx,
454 )
455 }
456
457 #[doc(hidden)]
458 #[coverage(off)]
459 fn unmutate(&self, value: &mut Vec<T>, cache: &mut Self::Cache, t: Self::UnmutateToken) {
460 match t {
461 UnmutateVecToken::Element(idx, inner_t) => {
462 let el = &mut value[idx];
463 self.mutators[idx].unmutate(el, &mut cache.inner[idx], inner_t);
464 }
465 UnmutateVecToken::Elements(tokens) => {
466 for (idx, token) in tokens {
467 let el = &mut value[idx];
468 self.mutators[idx].unmutate(el, &mut cache.inner[idx], token);
469 }
470 }
471 UnmutateVecToken::Replace(new_value) => {
472 let _ = std::mem::replace(value, new_value);
473 }
474 UnmutateVecToken::ReplaceElement(idx, el) => {
475 let _ = std::mem::replace(&mut value[idx], el);
476 }
477 }
478 }
479
480 #[doc(hidden)]
481 #[coverage(off)]
482 fn visit_subvalues<'a>(&self, value: &'a Vec<T>, cache: &'a Self::Cache, visit: &mut dyn FnMut(&'a dyn Any, f64)) {
483 if !value.is_empty() {
484 for idx in 0..value.len() {
485 let cplx = self.mutators[idx].complexity(&value[idx], &cache.inner[idx]);
486 visit(&value[idx], cplx);
487 }
488 for ((el, el_cache), mutator) in value.iter().zip(cache.inner.iter()).zip(self.mutators.iter()) {
489 mutator.visit_subvalues(el, el_cache, visit);
490 }
491 }
492 }
493}
494#[cfg(test)]
495mod tests {
496 use super::FixedLenVecMutator;
497 use crate::mutators::integer::U8Mutator;
498 use crate::Mutator;
499 #[test]
500 #[coverage(off)]
501 fn test_constrained_length_mutator() {
502 let m = FixedLenVecMutator::<u8, U8Mutator>::new_with_repeated_mutator(U8Mutator::default(), 3);
503 m.initialize();
504 for _ in 0..100 {
505 let (x, _) = m.ordered_arbitrary(&mut (), 800.0).unwrap();
506 eprintln!("{:?}", x);
507 }
508 }
509}