1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Operator compatibility trait for build-time operator validation.
//!
//! `OperatorCompat` is an opt-in trait that lets a chromosome type declare
//! which crossover and mutation operators are valid for it. `Ga::build()`
//! checks these restrictions before the first generation runs, returning
//! `GaError::ConfigurationError` immediately if an incompatible operator is
//! configured.
//!
//! # Semantics
//!
//! - Both methods return `None` by default (no restriction — any operator is
//! allowed). Override them to restrict the valid set.
//! - Return `Some(&[Crossover::Pmx, ...])` / `Some(&[Mutation::Swap, ...])` to
//! declare the allowed operators. A static slice keeps this zero-allocation.
//! - `Ga::build()` compares the configured operator against the valid set and
//! fails fast with `GaError::ConfigurationError` if there is a mismatch.
//!
//! # Example
//!
//! ```rust,no_run
//! // no_run: API illustration — MyChromosome is a user-defined type
//! use genetic_algorithms::operations::{Crossover, Mutation};
//! use genetic_algorithms::traits::OperatorCompat;
//!
//! // impl OperatorCompat for MyChromosome {
//! // fn valid_crossovers() -> Option<&'static [Crossover]> {
//! // Some(&[Crossover::Pmx, Crossover::Order])
//! // }
//! // fn valid_mutations() -> Option<&'static [Mutation]> {
//! // Some(&[Mutation::Swap, Mutation::Inversion])
//! // }
//! // }
//! ```
//!
//! # Design note — no blanket impl
//!
//! This trait intentionally has NO blanket implementation over all `LinearChromosome`
//! types. Such a blanket impl would prevent concrete restriction impls for permutation
//! chromosome types like `UniqueChromosome<T>` on Rust stable (no specialization).
//! Instead, each chromosome type that needs the `OperatorCompat` bound satisfied must
//! add an explicit impl — either empty `{}` (inherits `None` defaults) or with
//! a restricted valid set.
use crate;
/// Opt-in operator-compatibility trait for build-time validation.
///
/// Implement this trait on a chromosome type to declare which crossover and
/// mutation operators are valid for it. `Ga::build()` checks these restrictions
/// before any generation runs.
///
/// Both methods default to `None` (no restriction). Override them to restrict
/// the valid operator set to a `Some(&'static [...])` slice.
///
/// # Examples
///
/// ```rust,no_run
/// use genetic_algorithms::operations::{Crossover, Mutation};
/// use genetic_algorithms::traits::OperatorCompat;
/// use genetic_algorithms::chromosomes::UniqueChromosome;
///
/// // Permutation chromosomes restrict to permutation-preserving operators:
/// // (UniqueChromosome already does this — shown here for illustration)
/// struct MyPermutationChromosome;
/// impl OperatorCompat for MyPermutationChromosome {
/// fn valid_crossovers() -> Option<&'static [Crossover]> {
/// Some(&[Crossover::Pmx, Crossover::Order, Crossover::EdgeRecombination])
/// }
/// fn valid_mutations() -> Option<&'static [Mutation]> {
/// Some(&[Mutation::Swap, Mutation::Inversion, Mutation::Scramble])
/// }
/// }
/// ```