1use super::crossover_insert_slice::CrossoverInsertSlice;
2use super::crossover_replace_element::CrossoverReplaceElement;
3use super::{
4 arbitrary, copy_element, crossover_insert_slice, crossover_replace_element, insert_element, insert_many_elements,
5 mutate_element, only_choose_length, remove, remove_and_insert_element, swap_elements, VecMutator,
6};
7use crate::mutators::mutations::{Mutation, NoMutation, RevertMutation};
8use crate::mutators::vose_alias::VoseAlias;
9use crate::Mutator;
10
11pub struct WeightedMutation<M> {
12 mutation: M,
13 random_weight: f64,
14 ordered_weight: f64,
15}
16macro_rules! impl_vec_mutation {
17 ($(($i:ident,$t:ty)),*) => {
18 pub enum InnerVectorMutation {
19 $($i($t),)*
20 }
21 pub struct VectorMutation {
22 mutations: Vec<WeightedMutation<InnerVectorMutation>>,
23 }
24 pub enum VectorMutationInnerStep<T, M>
25 where
26 T: Clone + 'static,
27 M: Mutator<T>,
28 {
29 $($i(< $t as Mutation<Vec<T>, VecMutator<T, M>>>::Step),)*
30 }
31 pub struct VectorMutationStep<T, M>
32 where
33 T: Clone + 'static,
34 M: Mutator<T>,
35 {
36 inner_steps: Vec<VectorMutationInnerStep<T, M>>,
37 weights: Vec<f64>,
38 sampling: VoseAlias,
39 }
40 pub enum VectorMutationInnerRandomStep<T, M>
41 where
42 T: Clone + 'static,
43 M: Mutator<T>,
44 {
45 $($i(< $t as Mutation<Vec<T>, VecMutator<T, M>>>::RandomStep),)*
46 }
47 pub struct VectorMutationRandomStep<T, M>
48 where
49 T: Clone + 'static,
50 M: Mutator<T>
51 {
52 inner_steps: Vec<VectorMutationInnerRandomStep<T, M>>,
53 sampling: VoseAlias,
54 }
55 pub enum ConcreteVectorMutation<'a, T, M>
56 where
57 T: Clone + 'static,
58 M: Mutator<T>,
59 {
60 $($i(< $t as Mutation<Vec<T>, VecMutator<T, M>>>::Concrete<'a>),)*
61 }
62 pub enum RevertVectorMutation<T, M>
63 where
64 T: Clone + 'static,
65 M: Mutator<T>,
66 {
67 $($i(< $t as Mutation<Vec<T>, VecMutator<T, M>>>::Revert),)*
68 }
69 impl<T, M> Clone for VectorMutationInnerStep<T, M>
70 where
71 T: Clone + 'static,
72 M: Mutator<T>,
73 {
74 #[coverage(off)]
75 fn clone(&self) -> Self {
76 match self {
77 $(
78 Self::$i(x) => Self::$i(x.clone())
79 ),*
80 }
81 }
82 }
83
84 impl<T, M> Clone for VectorMutationStep<T, M>
85 where
86 T: Clone + 'static,
87 M: Mutator<T>,
88 VectorMutationInnerStep<T, M>: Clone
89 {
90 #[coverage(off)]
91 fn clone(&self) -> Self {
92 Self {
93 inner_steps: self.inner_steps.clone(),
94 weights: self.weights.clone(),
95 sampling: self.sampling.clone(),
96 }
97 }
98 }
99
100 impl<T, M> Clone for VectorMutationInnerRandomStep<T, M>
101 where
102 T: Clone + 'static,
103 M: Mutator<T>,
104 {
105 #[allow(unreachable_code)]
106 #[coverage(off)]
107 fn clone(&self) -> Self {
108 match self {
109 $(
110 Self::$i(x) => Self::$i(x.clone())
111 ),*
112 }
113 }
114 }
115
116 impl<T, M> Clone for VectorMutationRandomStep<T, M>
117 where
118 T: Clone + 'static,
119 M: Mutator<T>,
120 VectorMutationInnerRandomStep<T, M>: Clone
121 {
122 #[coverage(off)]
123 fn clone(&self) -> Self {
124 Self {
125 inner_steps: self.inner_steps.clone(),
126 sampling: self.sampling.clone(),
127 }
128 }
129 }
130
131 impl<T, M> RevertMutation<Vec<T>, VecMutator<T, M>> for RevertVectorMutation<T, M>
132 where
133 T: Clone + 'static,
134 M: Mutator<T>,
135 {
136 #[coverage(off)]
137 fn revert(
138 self,
139 mutator: &VecMutator<T, M>,
140 value: &mut Vec<T>,
141 cache: &mut <VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
142 ) {
143 match self {
144 $(
145 Self::$i(r) => r.revert(mutator, value, cache)
146 ),*
147 }
148 }
149 }
150
151 impl<T, M> Mutation<Vec<T>, VecMutator<T, M>> for VectorMutation
152 where
153 T: Clone + 'static,
154 M: Mutator<T>,
155 {
156 type RandomStep = VectorMutationRandomStep<T, M>;
157 type Step = VectorMutationStep<T, M>;
158 type Concrete<'a> = ConcreteVectorMutation<'a, T, M>;
159 type Revert = RevertVectorMutation<T, M>;
160 #[coverage(off)]
161 fn default_random_step(&self, mutator: &VecMutator<T, M>, value: &Vec<T>) -> Option<Self::RandomStep> {
162 let inner_steps_and_weights: Vec<(_, f64)> = self
163 .mutations
164 .iter()
165 .filter_map(#[coverage(off)] |mutation| {
166 match &mutation.mutation {
167 $(
168 InnerVectorMutation::$i(r) => r
169 .default_random_step(mutator, value)
170 .map(VectorMutationInnerRandomStep::$i)
171 ),*
172 }
173 .map(#[coverage(off)] |inner| (inner, mutation.random_weight))
174 })
175 .collect::<Vec<_>>();
176
177 if inner_steps_and_weights.is_empty() {
178 return None;
179 }
180 let weights = inner_steps_and_weights.iter().map(#[coverage(off)] |x| x.1).collect();
181 let sampling = VoseAlias::new(weights);
182 let inner_steps = inner_steps_and_weights.into_iter().map(#[coverage(off)] |x| x.0).collect();
183
184 Some(VectorMutationRandomStep { inner_steps, sampling })
185 }
186 #[coverage(off)]
187 fn random<'a>(
188 mutator: &VecMutator<T, M>,
189 value: &Vec<T>,
190 cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
191 step: &Self::RandomStep,
192 max_cplx: f64,
193 ) -> Self::Concrete<'a> {
194 let inner_step_idx = step.sampling.sample();
195 let step = &step.inner_steps[inner_step_idx];
196 match step {
197 $(
198 VectorMutationInnerRandomStep::$i(s) =>
199 ConcreteVectorMutation::$i(<$t>::random(mutator, value, cache, s, max_cplx))
200 ),*
201 }
202 }
203 #[coverage(off)]
204 fn default_step(
205 &self,
206 mutator: &VecMutator<T, M>,
207 value: &Vec<T>,
208 cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
209 ) -> Option<Self::Step> {
210 let inner_steps_and_weights: Vec<(VectorMutationInnerStep<_, _>, f64)> = self
211 .mutations
212 .iter()
213 .filter_map(#[coverage(off)] |mutation| {
214 match &mutation.mutation {
215 $(
216 InnerVectorMutation::$i(r) =>
217 r.default_step(mutator, value, cache)
218 .map(VectorMutationInnerStep::$i)
219 ),*
220 }
221 .map(#[coverage(off)] |inner| (inner, mutation.ordered_weight))
222 })
223 .collect::<Vec<_>>();
224
225 if inner_steps_and_weights.is_empty() {
226 return None;
227 }
228
229 let mut inner_steps = Vec::with_capacity(inner_steps_and_weights.len());
230 let mut weights = Vec::with_capacity(inner_steps_and_weights.len());
231 let mut probabilities = Vec::with_capacity(inner_steps_and_weights.len());
232 for (inner_step, weight) in inner_steps_and_weights {
233 inner_steps.push(inner_step);
234 probabilities.push(weight);
235 weights.push(weight);
236 }
237 let sampling = VoseAlias::new(probabilities);
238
239 Some(VectorMutationStep {
240 inner_steps,
241 weights,
242 sampling,
243 })
244 }
245 #[coverage(off)]
246 fn from_step<'a>(
247 mutator: &VecMutator<T, M>,
248 value: &Vec<T>,
249 cache: &<VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
250 step: &'a mut Self::Step,
251 subvalue_provider: &dyn crate::SubValueProvider,
252 max_cplx: f64,
253 ) -> Option<Self::Concrete<'a>> {
254 if step.inner_steps.is_empty() {
255 return None;
256 }
257 let inner_step_idx = step.sampling.sample();
258 let step_raw = step as *mut Self::Step;
259 {
260 let inner_step = &mut step.inner_steps[inner_step_idx];
261
262 let concrete: Option<<VectorMutation as Mutation<Vec<T>, VecMutator<T, M>>>::Concrete<'a>> =
263 match inner_step {
264 $(
265 VectorMutationInnerStep::$i(step) =>
266 <$t>::from_step(mutator, value, cache, step, subvalue_provider, max_cplx)
267 .map(ConcreteVectorMutation::$i)
268 ),*
269 };
270 if let Some(concrete) = concrete {
271 return Some(concrete);
272 }
273 }
274 let step = unsafe { &mut *step_raw };
276 step.weights.remove(inner_step_idx);
278 step.inner_steps.remove(inner_step_idx);
279 if step.weights.is_empty() {
280 None
281 } else {
282 step.sampling = VoseAlias::new(step.weights.clone());
283 Self::from_step(mutator, value, cache, step, subvalue_provider, max_cplx)
284 }
285 }
286 #[coverage(off)]
287 fn apply<'a>(
288 mutation: Self::Concrete<'a>,
289 mutator: &VecMutator<T, M>,
290 value: &mut Vec<T>,
291 cache: &mut <VecMutator<T, M> as Mutator<Vec<T>>>::Cache,
292 subvalue_provider: &dyn crate::SubValueProvider,
293 max_cplx: f64,
294 ) -> (Self::Revert, f64) {
295 match mutation {
296 $(
297 ConcreteVectorMutation::$i(mutation) => {
298 let (revert, cplx) = <$t>::apply(mutation, mutator, value, cache, subvalue_provider, max_cplx);
299 (RevertVectorMutation::$i(revert), cplx)
300 }
301 )*
302 }
303 }
304 }
305 }
306}
307
308impl_vec_mutation! {
309 (NoMutation, NoMutation),
310 (CopyElement, copy_element::CopyElement),
311 (Remove, remove::Remove),
312 (MutateElement, mutate_element::MutateElement),
313 (InsertElement, insert_element::InsertElement),
314 (SwapElements, swap_elements::SwapElements),
315 (InsertManyElements, insert_many_elements::InsertManyElements),
316 (RemoveAndInsertElement, remove_and_insert_element::RemoveAndInsertElement),
317 (OnlyChooseLength, only_choose_length::OnlyChooseLength),
318 (Arbitrary, arbitrary::Arbitrary),
319 (CrossoverReplaceElement, crossover_replace_element::CrossoverReplaceElement),
320 (CrossoverInsertSlice, crossover_insert_slice::CrossoverInsertSlice)
321}
322
323impl<'a, T, M> std::fmt::Debug for ConcreteVectorMutation<'a, T, M>
324where
325 T: Clone + 'static,
326 M: Mutator<T>,
327{
328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
329 match self {
330 ConcreteVectorMutation::NoMutation(_) => {
331 write!(f, "NoMutation")
332 }
333 ConcreteVectorMutation::CopyElement(_) => {
334 write!(f, "CopyElement")
335 }
336 ConcreteVectorMutation::Remove(_) => {
337 write!(f, "Remove")
338 }
339 ConcreteVectorMutation::MutateElement(_) => {
340 write!(f, "MutateElement")
341 }
342 ConcreteVectorMutation::InsertElement(_) => {
343 write!(f, "InsertElement")
344 }
345 ConcreteVectorMutation::SwapElements(_) => {
346 write!(f, "SwapElements")
347 }
348 ConcreteVectorMutation::InsertManyElements(_) => {
349 write!(f, "InsertManyElements")
350 }
351 ConcreteVectorMutation::RemoveAndInsertElement(_) => {
352 write!(f, "RemoveAndInsertElement")
353 }
354 ConcreteVectorMutation::OnlyChooseLength(_) => {
355 write!(f, "OnlyChooseLength")
356 }
357 ConcreteVectorMutation::Arbitrary(_) => {
358 write!(f, "Arbitrary")
359 }
360 ConcreteVectorMutation::CrossoverReplaceElement(_) => {
361 write!(f, "CrossoverReplaceElement")
362 }
363 ConcreteVectorMutation::CrossoverInsertSlice(_) => {
364 write!(f, "CrossoverInsertSlice")
365 }
366 }
367 }
368}
369
370impl Default for VectorMutation {
373 #[coverage(off)]
374 fn default() -> Self {
375 Self {
377 mutations: vec![
378 WeightedMutation {
379 mutation: InnerVectorMutation::CopyElement(copy_element::CopyElement),
380 random_weight: 50.,
381 ordered_weight: 500.,
382 },
383 WeightedMutation {
384 mutation: InnerVectorMutation::OnlyChooseLength(only_choose_length::OnlyChooseLength),
385 random_weight: 1., ordered_weight: 1.,
387 },
388 WeightedMutation {
389 mutation: InnerVectorMutation::Arbitrary(arbitrary::Arbitrary),
390 random_weight: 1.,
391 ordered_weight: 1.,
392 },
393 WeightedMutation {
394 mutation: InnerVectorMutation::Remove(remove::Remove),
395 random_weight: 50.,
396 ordered_weight: 50_000.,
397 },
398 WeightedMutation {
399 mutation: InnerVectorMutation::MutateElement(mutate_element::MutateElement),
400 random_weight: 1000.,
401 ordered_weight: 1000.,
402 },
403 WeightedMutation {
404 mutation: InnerVectorMutation::InsertElement(insert_element::InsertElement),
405 random_weight: 50.,
406 ordered_weight: 50.,
407 },
408 WeightedMutation {
409 mutation: InnerVectorMutation::RemoveAndInsertElement(
410 remove_and_insert_element::RemoveAndInsertElement,
411 ),
412 random_weight: 50.,
413 ordered_weight: 30.,
414 },
415 WeightedMutation {
416 mutation: InnerVectorMutation::SwapElements(swap_elements::SwapElements),
417 random_weight: 20.,
418 ordered_weight: 500.,
419 },
420 WeightedMutation {
421 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
422 nbr_added_elements: 2,
423 repeated: false,
424 }),
425 random_weight: 10.,
426 ordered_weight: 5.,
427 },
428 WeightedMutation {
429 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
430 nbr_added_elements: 3,
431 repeated: false,
432 }),
433 random_weight: 8.,
434 ordered_weight: 4.,
435 },
436 WeightedMutation {
437 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
438 nbr_added_elements: 4,
439 repeated: false,
440 }),
441 random_weight: 6.,
442 ordered_weight: 3.,
443 },
444 WeightedMutation {
445 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
446 nbr_added_elements: 5,
447 repeated: false,
448 }),
449 random_weight: 4.,
450 ordered_weight: 2.,
451 },
452 WeightedMutation {
453 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
454 nbr_added_elements: 2,
455 repeated: true,
456 }),
457 random_weight: 10.,
458 ordered_weight: 5.,
459 },
460 WeightedMutation {
461 mutation: InnerVectorMutation::InsertManyElements(insert_many_elements::InsertManyElements {
462 nbr_added_elements: 3,
463 repeated: true,
464 }),
465 random_weight: 8.,
466 ordered_weight: 4.,
467 },
468 WeightedMutation {
469 mutation: InnerVectorMutation::CrossoverReplaceElement(CrossoverReplaceElement),
470 random_weight: 0.,
471 ordered_weight: 100.,
472 },
473 WeightedMutation {
474 mutation: InnerVectorMutation::CrossoverInsertSlice(CrossoverInsertSlice),
475 random_weight: 0.,
476 ordered_weight: 50.,
477 },
478 ],
495 }
496 }
497}