Inference-first 0.3.0: likelihoods as programs, optimizer mode, Pareto posterior, prior-owned encodings - #20
Merged
Merged
Conversation
…eto posterior, prior-owned encodings Closes the three caveats left by the 0.2.0 refactor, completing the "implementation of fugue for running evolutionary algorithms as Bayesian inference" identity: Fix A — likelihoods as programs (inference/likelihood.rs): - GenomeLikelihood<G>: observation program p(data|g) with observes, factors, and latent nuisance parameters jointly inferred with the genome. - tempered_observe helper; FactorFitness adapter (black-box mode = explicit Gibbs/generalized-Bayes posterior); NoLikelihood; MemoizedFitness (exact-key shared cache). - EvolutionModel<P, L> generalization; new(prior, fitness) still works via FactorFitness; from_likelihood accepts any observation program. - GaussianRegression with NoiseSpec::Infer: observation noise as a latent site, posterior read off particle traces (test recovers sigma=0.3). Fix B1 — optimizer mode: EvolutionSMC::anneal continues the tempering ladder past beta=1 (fugue primitives only: incremental reweight, normalize, resample, rejuvenate, optional crossover sweep), concentrating on optima with uncertainty attached. Head-to-head example vs SimpleGA. Fix B2 — multi-objective as inference (inference/pareto.rs): ParetoScalarization puts the scalarization weight inside the model (uniform-simplex stick-breaking), so the posterior marginal traces the Pareto front; particle_weights locates each particle on it. Analytic biobjective validation (Pareto set [0,2], x*(w) = 2(1-w)). Fix C — prior-owned encodings: GenomePrior::trace_of (grammar prior overrides with the exact inverse of its generative walk; pinned by inversion + hand-computed PCFG score tests); score/to_weighted_trace work for grammar trees; EvolutionChain::init_from warm-starts from any genome. Fix B3 — identity: `classic` feature gates the EC toolkit (MultiObjectiveFitness moved to core fitness::multi_objective); std,ppl builds inference standalone; std,parallel,checkpoint,classic builds classic fugue-free; README/description lead with the inference identity. All 9 suites green in default config; both minimal configs check clean; clippy/fmt clean; wasm unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmWLBR9Zq6hPG5o7URDuNJ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HmWLBR9Zq6hPG5o7URDuNJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the three caveats left by the 0.2.0 refactor (#19), completing the identity: fugue-evo is an implementation of fugue for running evolutionary algorithms as Bayesian inference (plus a standalone classic EC toolkit). Follow-up to #18.
Fix A — likelihoods as programs
GenomeLikelihood<G>replaces "fitness" as the conditioning abstraction: an observation programp(data|g)that may contain per-datumobservestatements,factors, and — the capability the scalar factor could never express — latent nuisance parameters jointly inferred with the genome. The black-box mode survives as theFactorFitnessadapter, now explicitly labeled as the Gibbs/generalized-Bayes posterior.EvolutionModel::new(prior, fitness)is source-compatible;from_likelihoodaccepts any observation program.Demonstrated where it matters:
GaussianRegressionwithNoiseSpec::Inferputs the observation noise σ at a latent site inside the likelihood —test_symreg_infers_noise_jointlygenerates data with σ=0.3 and recovers it from the particle traces while simultaneously finding the generating program.Fix B1 — optimizer mode
EvolutionSMC::anneal(β_max, steps)continues the tempering ladder past β=1, built entirely from fugue's exported primitives (incremental reweight → normalize → resample → π_β-invariant rejuvenation → optional crossover sweep). On the sphere benchmark it reaches within ~1e-4 of the optimum while still reporting population uncertainty and log-evidence (examples/optimize_by_inference.rs, head-to-head with SimpleGA). Single-objective optimization is no longer the classic layer's monopoly.Fix B2 — multi-objective as inference
ParetoScalarizationputs the scalarization weight inside the model (uniform-simplex stick-breaking Beta sites): the joint posterior's marginal over genomes traces the Pareto front, andparticle_weightsreads each particle's front position off its trace — a posterior over the front, with evidence, which NSGA-II cannot express. Validated analytically: biobjectivef1=x², f2=(x−2)²with Pareto set exactly[0,2]— >90% of mass on the set, both ends covered, and particles sit near their own weight's scalarized optimumx*(w)=2(1−w). (Weighted-sum = convex fronts; Chebyshev is noted future work, same architecture. CMA-ES deliberately stays a baseline — it is not a posterior sampler.)Fix C — prior-owned encodings + cost
GenomePrior::trace_ofencodes a genome under the prior's address scheme (grammar prior overrides with the exact inverse of its generative walk — pinned by an inversion test and a hand-computed PCFG score).EvolutionModel::score/to_weighted_tracenow work for grammar trees, andEvolutionChain::init_fromwarm-starts a chain from any in-support genome — including a classic GA/GP result.MemoizedFitness(exact-key, shared-cache) removes repeated evaluations under replay-heavy inference.Fix B3 — identity
classicfeature (default on) gatesalgorithms/operators/population/hyperparameter/interactive/checkpoint/diagnostics/termination.MultiObjectiveFitness/ClosureMultiObjectivemoved to corefitness::multi_objective(re-exported fromnsga2for compat).--no-default-features --features std,pplbuilds the inference layer with no classic EC code;std,parallel,checkpoint,classicbuilds classic with no fugue. Both configs check clean with--all-targets.Validation
--all-targets.Version
0.2.0 → 0.3.0(pre-1.0 breaking-minor:EvolutionModelgenerics; feature gating).🤖 Generated with Claude Code
https://claude.ai/code/session_01HmWLBR9Zq6hPG5o7URDuNJ