use rand::Rng;
use crate::environment::Environment;
use crate::genotype::Genotype;
/// # Aliases
/// Agent, Creature, Individual, Solution
pub trait Phenotype {
/// This is the type used to construct the phenotype.
/// Simple optimization problems may even opt to use the exact same type as the phenotype.
type Genotype: Genotype;
/// This function converts the [`Phenotype`] back into its genetic representation.
/// The main reason for this function is to avoid allocation by storing both
/// presentations in an algorithm and instead simply switch between the two, possibly avoiding
/// allocation and as a bonus likely being a no-op, depending on the types used.
fn to_genotype(self) -> Self::Genotype;
}
/// Constructing a [`Phenotype`] is used to potentially differentiate between the genetic and final
/// representation.
pub trait FromGenotype<GENOTYPE, ENVIRONMENT>: Phenotype
where
GENOTYPE: Genotype,
ENVIRONMENT: Environment,
{
/// [`Phenotypes`] may "grow up" different depending on their environment or random
/// influences - just like their biological counterparts.
fn from_genotype<RNG>(rng: &mut RNG, genotype: GENOTYPE, environment: &ENVIRONMENT) -> Self
where
RNG: Rng;
}