lineage/individual
Represents a single organism within a simulation.
An individual carries a genome, optional references to its parents, and is governed by a set of species rules that determine its sex, fertility, and which genes it expresses.
Types
The genetic sex of an individual.
MaleandFemalecover standard gonosomal sex determinationNoneis used for species without genetic sex, such as hermaphroditesOther(name)accommodates non-standard sex systems
pub type GeneticSex {
Male
Female
None
Hermaphrodite
Other(name: String)
}
Constructors
-
Male -
Female -
None -
Hermaphrodite -
Other(name: String)
A single organism within the simulation.
Fields
name- A unique identifier for the individual, typically a UUID v4 stringgenome- The full set of chromosomes carried by this individualfather- Name of the paternal parent, orNoneif unknown or absentmother- Name of the maternal parent, orNoneif unknown or absent
pub type Individual {
Individual(
name: String,
genome: dict.Dict(
chromosome.ChromosomeIndex,
List(dict.Dict(Int, String)),
),
father: option.Option(String),
mother: option.Option(String),
)
}
Constructors
-
Individual( name: String, genome: dict.Dict( chromosome.ChromosomeIndex, List(dict.Dict(Int, String)), ), father: option.Option(String), mother: option.Option(String), )
A function that determines whether an individual is capable of reproducing
pub type IsFertile =
fn(Individual) -> Bool
The number of chromosome copies present in each cell of an individual.
Diploid organisms have a ploidity of 2, triploid of 3, and so on.
pub type Ploidity =
Int
pub type RelabelNames =
fn(List(Individual)) -> dict.Dict(String, String)
A function that inspects an individual’s genome and returns its genetic sex
pub type SexPredicate =
fn(Individual) -> GeneticSex
The complete set of rules governing a species.
Species rules are passed to most functions that create or evaluate individuals, acting as a single configuration bundle for the simulation.
Fields
sex- Predicate that determines the genetic sex of an individualploidity- Number of chromosome copies per individualis_fertile- Predicate that determines whether an individual can reproducegenes- The list of genes that make up the species genome
pub type SpeciesRules {
SpeciesRules(
sex: fn(Individual) -> GeneticSex,
ploidity: Int,
is_fertile: fn(Individual) -> Bool,
genes: List(gene.Gene),
)
}
Constructors
-
SpeciesRules( sex: fn(Individual) -> GeneticSex, ploidity: Int, is_fertile: fn(Individual) -> Bool, genes: List(gene.Gene), )
Values
pub fn always_fertile(arg: Individual) -> Bool
A fertility predicate that always returns True.
Examples
always_fertile(some_individual)
// -> True
pub fn encode_parent(parent: option.Option(String)) -> json.Json
Encodes an optional parent name as JSON.
A known parent is encoded as the name string; an absent parent as null.
Examples
encode_parent(option.Some("abc-123")) |> json.to_string
// -> "\"abc-123\""
encode_parent(option.None) |> json.to_string
// -> "null"
pub fn encode_sex(sex: GeneticSex) -> json.Json
Encodes a GeneticSex value as JSON.
Male and Female are encoded as their lowercase string equivalents,
Other(name) as the given name string, and None as null.
Examples
encode_sex(Male) |> json.to_string
// -> "\"male\""
encode_sex(None) |> json.to_string
// -> "null"
pub fn hermaphrodite(arg: Individual) -> GeneticSex
pub fn mate(father: Individual, mother: Individual) -> Individual
Creates a new offspring individual from two parents.
Each parent produces a gamete via chromosome.create_gamete, which
randomly selects half of each parent’s chromosomes. The two gametes are
then merged into the offspring’s genome. The offspring receives a new UUID
and records the names of both parents.
Examples
let offspring = mate(father, mother)
offspring.father
// -> option.Some(father.name)
offspring.mother
// -> option.Some(mother.name)
pub fn new(rules: SpeciesRules) -> Individual
Creates a new individual with a random UUID name and a randomly sampled genome.
Parent references are set to None. The genome is built from the species
rules by sampling each gene’s alleles at the given ploidity.
Examples
let individual = new(pea.rules())
// individual.name is a UUID v4 string
// individual.father and individual.mother are None
pub fn no_sex(arg: Individual) -> GeneticSex
A sex predicate that always returns None.
Suitable for hermaphroditic or asexual species where genetic sex is not relevant to the simulation.
Examples
no_sex(some_individual)
// -> None
pub fn phenotype(
individual: Individual,
genes: List(gene.Gene),
) -> dict.Dict(String, String)
Returns the expressed phenotype of each gene, keyed by gene name.
Equivalent to phenotype_by_gene, but the result is indexed by the
human-readable gene name rather than the full Gene struct. Useful for
serialisation and display.
Examples
let result = phenotype(individual, pea.genome())
dict.get(result, "Flower/seed coat color")
// -> Ok("purple")
pub fn phenotype_by_gene(
individual: Individual,
genes: List(gene.Gene),
) -> dict.Dict(gene.Gene, String)
Returns the expressed phenotype of each gene, keyed by the Gene struct.
For each gene, the collected alleles from the individual’s genome are passed
to the gene’s expression function if one is set. If the expression returns
None, or if no expression is set, the alleles are joined into a raw string
as a fallback.
Use phenotype instead if you need the result keyed by gene name.
Examples
let result = phenotype_by_gene(individual, pea.genome())
// -> dict.Dict(gene.Gene, String) with one entry per gene
pub fn to_json(
individual: Individual,
rules: SpeciesRules,
) -> json.Json
Encodes an individual as a JSON object.
The species rules are required to determine sex, fertility, and phenotype. The resulting object contains the following fields:
"name"— UUID string identifying the individual"sex"— encoded viaencode_sex"fertile"— boolean"mother"— parent name string ornull"father"— parent name string ornull"phenotype"— object mapping gene names to expressed phenotype strings"genome"— the full chromosome set encoded viachromosome.encode_set