fugue_evo/genome/trace_genome.rs
1//! The fugue trace encoding of genomes (`ppl` feature).
2//!
3//! This module is the boundary between the classic evolutionary-computation
4//! layer and the PPL-native inference layer: a genome that implements
5//! [`TraceGenome`] can be round-tripped through a [`fugue::Trace`] and
6//! therefore driven by the trace-space machinery in
7//! [`crate::inference`] (MH rejuvenation, tempered SMC, block regeneration).
8//!
9//! The encoding produced by [`TraceGenome::to_trace`] is *canonical* — an
10//! address→value map at the genome's site addresses (`gene#i`, `bit#i`,
11//! `perm#i`, …) with zero stored log-probabilities. Probability mass is never
12//! carried by this encoding; it is recovered by scoring the trace under a
13//! genuine prior model (see [`crate::inference::prior::GenomePrior`]), which is also
14//! how the inference layer decodes a genome from a particle
15//! (`decode`-by-replay).
16
17use fugue::{addr, Address, Trace};
18
19// Re-export ChoiceValue for use in genome trace implementations (relocated
20// from `genome::traits` when the trait was split).
21pub use fugue::ChoiceValue;
22
23use crate::error::GenomeError;
24use crate::genome::traits::EvolutionaryGenome;
25
26/// Extension trait: genomes that can be encoded as fugue traces.
27///
28/// Implementing this trait is what admits a genome to the `ppl` inference
29/// layer. The classic algorithms never require it.
30pub trait TraceGenome: EvolutionaryGenome {
31 /// Convert genome to a fugue trace.
32 ///
33 /// Each gene is stored at an indexed address (e.g., `gene#0`, `gene#1`, …)
34 /// as a pure value; stored log-probabilities are zero. Score the trace
35 /// under a prior model to obtain real probability mass.
36 fn to_trace(&self) -> Trace;
37
38 /// Reconstruct genome from a fugue trace.
39 ///
40 /// This is the inverse of [`Self::to_trace`], extracting gene values from
41 /// the trace's choice map.
42 fn from_trace(trace: &Trace) -> Result<Self, GenomeError>;
43
44 /// Get the address prefix used for trace storage (default: `"gene"`).
45 fn trace_prefix() -> &'static str {
46 "gene"
47 }
48}
49
50/// Helper function to create a gene address for trace storage
51pub fn gene_address(prefix: &str, index: usize) -> Address {
52 addr!(prefix, index)
53}