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.

  • Male and Female cover standard gonosomal sex determination
  • None is used for species without genetic sex, such as hermaphrodites
  • Other(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 string
  • genome - The full set of chromosomes carried by this individual
  • father - Name of the paternal parent, or None if unknown or absent
  • mother - Name of the maternal parent, or None if 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

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 individual
  • ploidity - Number of chromosome copies per individual
  • is_fertile - Predicate that determines whether an individual can reproduce
  • genes - 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

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 via encode_sex
  • "fertile" — boolean
  • "mother" — parent name string or null
  • "father" — parent name string or null
  • "phenotype" — object mapping gene names to expressed phenotype strings
  • "genome" — the full chromosome set encoded via chromosome.encode_set
Search Document