1use std::any::Any;
2use std::cell::Cell;
3use std::cmp::Ordering;
4use std::marker::PhantomData;
5
6use crate::Mutator;
7
8pub struct AlternationMutator<T, M>
24where
25 T: Clone + 'static,
26 M: Mutator<T>,
27{
28 mutators: Vec<M>,
29 rng: fastrand::Rng,
30 added_complexity: f64,
31 initialized: Cell<bool>,
32 min_complexity: Cell<f64>,
33 max_complexity: Cell<f64>,
34 search_space_complexity: Cell<f64>,
35 _phantom: PhantomData<T>,
36}
37
38impl<T, M> AlternationMutator<T, M>
39where
40 T: Clone + 'static,
41 M: Mutator<T>,
42{
43 #[coverage(off)]
44 pub fn new(mutators: Vec<M>, added_complexity: f64) -> Self {
45 assert!(!mutators.is_empty());
46
47 Self {
48 mutators,
49 rng: fastrand::Rng::default(),
50 added_complexity,
51 initialized: Cell::new(false),
52 min_complexity: Cell::new(std::f64::INFINITY),
53 max_complexity: Cell::new(std::f64::INFINITY),
54 search_space_complexity: Cell::new(std::f64::INFINITY),
55 _phantom: PhantomData,
56 }
57 }
58}
59
60#[doc(hidden)]
61#[derive(Clone)]
62pub struct ArbitraryStep<AS> {
63 inner: Vec<AS>,
64 indices: Vec<usize>,
65 idx: usize,
66}
67
68#[doc(hidden)]
69#[derive(Clone)]
70pub struct MutationStep<MS, AS> {
71 step: usize,
72 mutator_idx: usize,
73 inner: MS,
74 arbitrary: AS,
75}
76
77#[doc(hidden)]
78#[derive(Clone)]
79pub struct Cache<C> {
80 inner: C,
81 mutator_idx: usize,
82}
83
84#[doc(hidden)]
85pub enum UnmutateToken<T, U> {
86 Replace(T),
87 Inner(usize, U),
88}
89
90impl<T, M> AlternationMutator<T, M>
91where
92 T: Clone + 'static,
93 M: Mutator<T>,
94{
95 #[coverage(off)]
96 fn complexity_from_inner(&self, cplx: f64) -> f64 {
97 cplx + self.added_complexity
98 }
99}
100
101impl<T, M> Mutator<T> for AlternationMutator<T, M>
102where
103 T: Clone + 'static + 'static,
104 M: Mutator<T>,
105{
106 #[doc(hidden)]
107 type Cache = Vec<Cache<M::Cache>>;
108 #[doc(hidden)]
109 type MutationStep = Vec<MutationStep<M::MutationStep, Self::ArbitraryStep>>;
110 #[doc(hidden)]
111 type ArbitraryStep = ArbitraryStep<M::ArbitraryStep>;
112 #[doc(hidden)]
113 type UnmutateToken = UnmutateToken<T, M::UnmutateToken>;
114
115 #[doc(hidden)]
116 #[coverage(off)]
117 fn initialize(&self) {
118 for mutator in self.mutators.iter() {
119 mutator.initialize();
120 }
121
122 let complexity_from_choice = crate::mutators::size_to_cplxity(self.mutators.len());
123
124 let search_space_complexity = self
125 .mutators
126 .iter()
127 .map(
128 #[coverage(off)]
129 |m| {
130 let cplx = m.global_search_space_complexity();
131 if cplx == 0. {
132 complexity_from_choice
133 } else {
134 cplx
135 }
136 },
137 )
138 .max_by(
139 #[coverage(off)]
140 |x, y| x.partial_cmp(y).unwrap_or(Ordering::Equal),
141 )
142 .unwrap();
143
144 let max_complexity = self
145 .mutators
146 .iter()
147 .map(
148 #[coverage(off)]
149 |m| m.max_complexity() + self.added_complexity,
150 )
151 .max_by(
152 #[coverage(off)]
153 |x1, x2| x1.partial_cmp(x2).unwrap_or(Ordering::Equal),
154 )
155 .unwrap();
156 let min_complexity = self
157 .mutators
158 .iter()
159 .map(
160 #[coverage(off)]
161 |m| m.min_complexity() + self.added_complexity,
162 )
163 .min_by(
164 #[coverage(off)]
165 |x1, x2| x1.partial_cmp(x2).unwrap_or(Ordering::Equal),
166 )
167 .unwrap();
168
169 self.min_complexity.set(min_complexity);
170 self.max_complexity.set(max_complexity);
171 self.search_space_complexity.set(search_space_complexity);
172
173 for mutator in self.mutators.iter() {
174 mutator.initialize();
175 }
176 self.initialized.set(true);
177 }
178
179 #[doc(hidden)]
180 #[coverage(off)]
181 fn default_arbitrary_step(&self) -> Self::ArbitraryStep {
182 Self::ArbitraryStep {
183 inner: self
184 .mutators
185 .iter()
186 .map(
187 #[coverage(off)]
188 |m| m.default_arbitrary_step(),
189 )
190 .collect(),
191 indices: (0..self.mutators.len()).collect(),
192 idx: 0,
193 }
194 }
195
196 #[doc(hidden)]
197 #[coverage(off)]
198 fn is_valid(&self, value: &T) -> bool {
199 for m in self.mutators.iter() {
200 if m.is_valid(value) {
201 return true;
202 }
203 }
204 false
205 }
206
207 #[doc(hidden)]
208 #[coverage(off)]
209 fn validate_value(&self, value: &T) -> Option<Self::Cache> {
210 let mut caches = vec![];
211 for (idx, mutator) in self.mutators.iter().enumerate() {
212 if let Some(c) = mutator.validate_value(value) {
213 caches.push(Cache {
214 inner: c,
215 mutator_idx: idx,
216 });
217 }
218 }
219 if caches.is_empty() {
220 None
221 } else {
222 Some(caches)
223 }
224 }
225
226 #[doc(hidden)]
227 #[coverage(off)]
228 fn default_mutation_step(&self, value: &T, cache: &Self::Cache) -> Self::MutationStep {
229 cache
230 .iter()
231 .map(
232 #[coverage(off)]
233 |c| {
234 let m = &self.mutators[c.mutator_idx];
235 MutationStep {
236 step: 0,
237 mutator_idx: c.mutator_idx,
238 inner: m.default_mutation_step(value, &c.inner),
239 arbitrary: {
240 let mut step = self.default_arbitrary_step();
241 step.indices.remove(c.mutator_idx);
242 step
243 },
244 }
245 },
246 )
247 .collect()
248 }
249
250 #[doc(hidden)]
251 #[coverage(off)]
252 fn global_search_space_complexity(&self) -> f64 {
253 self.search_space_complexity.get()
254 }
255
256 #[doc(hidden)]
257 #[coverage(off)]
258 fn max_complexity(&self) -> f64 {
259 self.max_complexity.get()
260 }
261
262 #[doc(hidden)]
263 #[coverage(off)]
264 fn min_complexity(&self) -> f64 {
265 self.min_complexity.get()
266 }
267
268 #[doc(hidden)]
269 #[coverage(off)]
270 fn complexity(&self, value: &T, cache: &Self::Cache) -> f64 {
271 let cache = &cache[0];
272 self.complexity_from_inner(self.mutators[cache.mutator_idx].complexity(value, &cache.inner))
273 }
274
275 #[doc(hidden)]
276 #[coverage(off)]
277 fn ordered_arbitrary(&self, step: &mut Self::ArbitraryStep, max_cplx: f64) -> Option<(T, f64)> {
278 if step.indices.is_empty() {
279 return None;
280 }
281 if max_cplx < self.min_complexity() {
282 return None;
283 }
284
285 let idx = step.indices[step.idx % step.indices.len()];
286 let mutator = &self.mutators[idx];
287 let inner_step = &mut step.inner[idx];
288 if let Some((v, c)) = mutator.ordered_arbitrary(inner_step, max_cplx) {
289 step.idx += 1;
290 Some((v, self.complexity_from_inner(c)))
291 } else {
292 step.indices.remove(step.idx % step.indices.len());
293 self.ordered_arbitrary(step, max_cplx)
294 }
295 }
296
297 #[doc(hidden)]
298 #[coverage(off)]
299 fn random_arbitrary(&self, max_cplx: f64) -> (T, f64) {
300 let idx = self.rng.usize(..self.mutators.len());
301 let mutator = &self.mutators[idx];
302
303 let (v, c) = mutator.random_arbitrary(max_cplx);
304 (v, self.complexity_from_inner(c))
305 }
306
307 #[doc(hidden)]
308 #[coverage(off)]
309 fn ordered_mutate(
310 &self,
311 value: &mut T,
312 cache: &mut Self::Cache,
313 step: &mut Self::MutationStep,
314 subvalue_provider: &dyn crate::SubValueProvider,
315 max_cplx: f64,
316 ) -> Option<(Self::UnmutateToken, f64)> {
317 if max_cplx < self.min_complexity() {
318 return None;
319 }
320 if step.is_empty() {
321 return None;
322 }
323
324 if self.rng.usize(..100) == 0 {
325 let (new_value, cplx) = self.random_arbitrary(max_cplx);
326 let old_value = ::std::mem::replace(value, new_value);
327 return Some((UnmutateToken::Replace(old_value), cplx));
328 }
329
330 let step_idx = self.rng.usize(..step.len());
331 let chosen_step = &mut step[step_idx];
332 chosen_step.step += 1;
333 if chosen_step.step < 20 {
337 if let Some((mut v, cplx)) = self.ordered_arbitrary(&mut chosen_step.arbitrary, max_cplx) {
338 std::mem::swap(value, &mut v);
339 return Some((UnmutateToken::Replace(v), cplx));
340 }
341 }
342
343 let mutator_idx = chosen_step.mutator_idx;
344 let chosen_cache = cache
345 .iter_mut()
346 .find(
347 #[coverage(off)]
348 |c| c.mutator_idx == mutator_idx,
349 )
350 .unwrap();
351
352 let idx = chosen_cache.mutator_idx;
353 assert_eq!(idx, mutator_idx);
354
355 let mutator = &self.mutators[idx];
356 if let Some((t, cplx)) = mutator.ordered_mutate(
357 value,
358 &mut chosen_cache.inner,
359 &mut chosen_step.inner,
360 subvalue_provider,
361 max_cplx,
362 ) {
363 Some((UnmutateToken::Inner(idx, t), self.complexity_from_inner(cplx)))
364 } else {
365 if let Some((mut v, cplx)) = self.ordered_arbitrary(&mut chosen_step.arbitrary, max_cplx) {
366 std::mem::swap(value, &mut v);
367 Some((UnmutateToken::Replace(v), cplx))
368 } else {
369 step.remove(step_idx);
370 if step.is_empty() {
371 None
372 } else {
373 self.ordered_mutate(value, cache, step, subvalue_provider, max_cplx)
374 }
375 }
376 }
377 }
378
379 #[doc(hidden)]
380 #[coverage(off)]
381 fn random_mutate(&self, value: &mut T, cache: &mut Self::Cache, max_cplx: f64) -> (Self::UnmutateToken, f64) {
382 let cache_idx = self.rng.usize(..cache.len());
383 let cache = &mut cache[cache_idx];
384
385 let idx = cache.mutator_idx;
386 let mutator = &self.mutators[idx];
387 if self.rng.usize(..100) == 0 || mutator.max_complexity() < 0.1 {
393 let (new_value, cplx) = self.random_arbitrary(max_cplx);
394 let old_value = ::std::mem::replace(value, new_value);
395 return (UnmutateToken::Replace(old_value), cplx);
396 }
397
398 let (t, cplx) = mutator.random_mutate(value, &mut cache.inner, max_cplx);
399 (UnmutateToken::Inner(idx, t), self.complexity_from_inner(cplx))
400 }
401
402 #[doc(hidden)]
403 #[coverage(off)]
404 fn unmutate(&self, value: &mut T, cache: &mut Self::Cache, t: Self::UnmutateToken) {
405 match t {
406 UnmutateToken::Replace(v) => {
407 let _ = std::mem::replace(value, v);
408 }
409 UnmutateToken::Inner(idx, t) => {
410 let mutator = &self.mutators[idx];
411 let cache = cache
412 .iter_mut()
413 .find(
414 #[coverage(off)]
415 |c| c.mutator_idx == idx,
416 )
417 .unwrap();
418 mutator.unmutate(value, &mut cache.inner, t);
419 }
420 }
421 }
422
423 #[doc(hidden)]
424 #[coverage(off)]
425 fn visit_subvalues<'a>(&self, value: &'a T, cache: &'a Self::Cache, visit: &mut dyn FnMut(&'a dyn Any, f64)) {
426 for cache in cache.iter() {
427 let mutator_idx = cache.mutator_idx;
428 let mutator = &self.mutators[mutator_idx];
429 mutator.visit_subvalues(value, &cache.inner, visit);
430 }
431 }
432}