pub trait FunctionSet:
Send
+ Sync
+ Debug {
// Required methods
fn num_functions(&self) -> usize;
fn arity(&self, symbol: Symbol) -> usize;
fn max_arity(&self) -> usize;
fn apply(&self, symbol: Symbol, args: &[f32]) -> f32;
}Expand description
The function-opcode contract shared by CGP and GEP.
Implementors describe a fixed table of functions. Each function has an
arity (number of arguments) and an apply
implementation that combines already-evaluated arguments into a result.
The trait is intentionally tiny: it says nothing about terminals, genome
layout, or evaluation order. Callers thread a concrete &F (never
&dyn FunctionSet) through their evaluation hot loops so the opcode
apply inlines.
Required Methods§
Sourcefn num_functions(&self) -> usize
fn num_functions(&self) -> usize
Number of function opcodes. Their ids are 0..num_functions().
Sourcefn arity(&self, symbol: Symbol) -> usize
fn arity(&self, symbol: Symbol) -> usize
Arity (argument count) of a function opcode.
Only meaningful for function symbols (symbol.0 in
0..num_functions()). Out-of-range ids return 0 so callers that
evaluate mutated-but-unrepaired genotypes do not panic.
Sourcefn max_arity(&self) -> usize
fn max_arity(&self) -> usize
Largest arity among all functions.
Drives the GEP tail-length constraint
(tail_len >= head_len * (max_arity - 1) + 1); see
GepConfig::new.
Sourcefn apply(&self, symbol: Symbol, args: &[f32]) -> f32
fn apply(&self, symbol: Symbol, args: &[f32]) -> f32
Applies a function opcode to its already-evaluated arguments.
Callers pass args.len() == self.arity(symbol). For zero-arity
functions (constants such as 1.0), args is empty. Variable and
constant terminals are never passed here — they are resolved by the
caller’s evaluator before apply is reached.
A shorter-than-arity slice does not panic: missing arguments read as
0.0. This keeps a malformed or unrepaired genotype (runtime data) from
aborting a training run, per rules.md §4.
§Numerical
apply performs raw IEEE-754 f32 arithmetic and may return a
non-finite value — overflow yields ±inf, 0.0 / 0.0 yields NaN.
It does not sanitize its result. Finiteness is the caller’s
responsibility at two distinct layers: intermediate node values are
collapsed to 0.0 for phenotype-evaluation stability (see the
finite_or_zero helper), and the final fitness is mapped to −inf by
the crate’s sanitize_fitness per rules.md §3.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".