1use crate::{
2 Chromosome, Ecosystem, Front, MetricSet, Objective, Phenotype, Population, Problem, Score,
3 Species, metric_names,
4};
5use std::{
6 sync::{Arc, RwLock},
7 time::Duration,
8};
9
10pub trait Engine {
11 type Chromosome: Chromosome;
12 type Epoch: Epoch<Chromosome = Self::Chromosome>;
13
14 fn next(&mut self) -> Self::Epoch;
15}
16
17pub trait EngineExt<E: Engine> {
18 fn run<F>(&mut self, limit: F) -> E::Epoch
19 where
20 F: Fn(&E::Epoch) -> bool,
21 Self: Sized;
22}
23
24impl<E> EngineExt<E> for E
25where
26 E: Engine,
27{
28 fn run<F>(&mut self, limit: F) -> E::Epoch
29 where
30 F: Fn(&E::Epoch) -> bool,
31 Self: Sized,
32 {
33 loop {
34 let epoch = self.next();
35
36 if limit(&epoch) {
37 break epoch;
38 }
39 }
40 }
41}
42
43pub trait Epoch {
44 type Chromosome: Chromosome;
45 type Value;
46
47 fn value(&self) -> &Self::Value;
48 fn ecosystem(&self) -> &Ecosystem<Self::Chromosome>;
49 fn index(&self) -> usize;
50 fn metrics(&self) -> &MetricSet;
51
52 fn population(&self) -> &Population<Self::Chromosome> {
53 &self.ecosystem().population()
54 }
55
56 fn species(&self) -> Option<&Vec<Species<Self::Chromosome>>> {
57 self.ecosystem().species()
58 }
59
60 fn time(&self) -> Duration {
61 self.metrics()
62 .get(metric_names::EVOLUTION_TIME)
63 .unwrap()
64 .time_sum()
65 .unwrap()
66 }
67
68 fn seconds(&self) -> f64 {
69 self.time().as_secs_f64()
70 }
71}
72
73pub trait EngineStep<C>: Send + Sync
74where
75 C: Chromosome,
76{
77 fn name(&self) -> &'static str {
78 std::any::type_name::<Self>()
79 .split("<")
80 .next()
81 .unwrap_or(std::any::type_name::<Self>())
82 .split("::")
83 .last()
84 .unwrap_or("Unknown Step")
85 }
86
87 fn execute(&mut self, generation: usize, metrics: &mut MetricSet, ecosystem: &mut Ecosystem<C>);
88}
89
90pub struct Context<C, T>
91where
92 C: Chromosome,
93{
94 pub ecosystem: Ecosystem<C>,
95 pub best: T,
96 pub index: usize,
97 pub metrics: MetricSet,
98 pub score: Option<Score>,
99 pub front: Arc<RwLock<Front<Phenotype<C>>>>,
100 pub objective: Objective,
101 pub problem: Arc<dyn Problem<C, T>>,
102}
103
104impl<C, T> Clone for Context<C, T>
105where
106 C: Chromosome,
107 T: Clone,
108{
109 fn clone(&self) -> Self {
110 Context {
111 ecosystem: self.ecosystem.clone(),
112 best: self.best.clone(),
113 index: self.index,
114 metrics: self.metrics.clone(),
115 score: self.score.clone(),
116 front: self.front.clone(),
117 objective: self.objective.clone(),
118 problem: Arc::clone(&self.problem),
119 }
120 }
121}