Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions predpreygrass/evolutionary/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ sustainability numbers.
genuine per-individual search decoupled from the shared PPO policy.
Sustainability/coexistence solved; selection-driven drift **null (reversed on the
headline metric)** after replication — see `RESULTS.md`.
* **[eco_evolutionary_cultural_plasticity](eco_evolutionary_cultural_plasticity)** —
a structurally different mechanism, not another single-scalar trait: gene-culture
coevolution (dual inheritance). A heritable `plasticity` gene sets how readily an
agent's live, socially-transmitted `dialect` tracks the local same-species
majority; dialect-matching at a catch/graze event earns a coordination-game energy
bonus. Implemented and unit-tested; no training pilot or replication run launched
yet — see `RESULTS.md`.

See **[RESULTS.md](RESULTS.md)** for the full cross-module trial log — the sequence of
attempts, why each pivot happened, and the current state of the search.
Expand Down
54 changes: 54 additions & 0 deletions predpreygrass/evolutionary/RESULTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,60 @@ direction) not yet made.

---

## Trial 8 — `eco_evolutionary_cultural_plasticity` — implemented, not yet run

**Mechanism, not just another trait.** Trials 1-7 all share one structural
property regardless of trait shape: a single heritable channel feeding a
shared per-species PPO policy. This trial adds a **second, independent
inheritance channel** instead — gene-culture coevolution / dual inheritance
(Boyd & Richerson, 1985; Cavalli-Sforza & Feldman, 1981), not a variant of
the same single-channel design tried seven times so far.

**The two channels:** `dialect` (categorical, one of 4 arbitrary same-species
coordination codes) is a *live, mutable* per-agent state — seeded from a
heritable founder value at birth, but free to change many times within one
agent's own lifetime via social learning from neighbors within
`culture_range`. `plasticity` (continuous, `[0,1]`, standard Gaussian-mutation
genome trait) is the actual gene under test: it sets how readily an agent's
live dialect updates toward the local same-species majority. The gene does
not encode behavior directly — it encodes capacity to adopt culture, which is
the literal Baldwin/dual-inheritance mechanism.

**Why this targets the diagnosis in the theoretical note below more directly
than Trial 7 did.** A catch/graze event grants an energy bonus when an
agent's live dialect matches its local majority at that moment — a
coordination game, not a gradient. Unlike Trial 7's combinatorial
needle-in-a-haystack (still null, both species, reversed on the headline
metric), which fixes gap #1 (a rugged landscape) but only partially addresses
gap #2 (genuine individual-lifetime search), this design's social-learning
update is frequency-dependent and history-dependent by construction, and the
gene being tested (`plasticity`) has direct, continuously-measurable leverage
over how fast that individual-level process runs — a tighter version of gap
#2 than Trial 7's per-step joint-guess mechanism, which the genome could not
influence at all (only zero-vs-nonzero WRONG-loci viability gated it).

**Reverse leg, addressed directly instead of left unconfirmed.** Every prior
module kept the genome invisible to the policy's observation space. This
module deliberately breaks that convention (`include_culture_in_obs`): the
policy observes its own live dialect and local-majority-match status, so PPO
can learn to condition movement/hunting on cultural state — a plausible route
to the "genome/culture shift feeds back into learned behavior" leg no prior
trial confirmed.

**What's ported unchanged:** satiation-throttle sustainability mechanism,
reproduction/energy dynamics, and the `genome_neutral_drift_control` /
Mann-Whitney multi-seed replication methodology — all directly from
`eco_evolutionary_metabolic_code`. `plasticity` uses the |deviation from
founder| test (à la `metabolic_rate`/`investment`), not Trial 7's directional
one, since plasticity has no a-priori predicted drift direction.

**Status:** implemented, 27 unit tests passing, 300-step random-policy smoke
run clean. No PPO training pilot or replication run launched yet — see
`eco_evolutionary_cultural_plasticity/RESULTS.md` for what remains before a
real Darwin-signal test can be read from this module.

---

## Theoretical note — Hinton & Nowlan (1987), a candidate future trait direction

This motivated the Trial 7 pivot above (`eco_evolutionary_metabolic_code`) — recorded here in full since it's the theoretical basis for that module's design, not just a historical note anymore.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Cultural Plasticity: Gene-Culture Coevolution (Dual Inheritance)

## Why this module exists

Every prior module in this family (`eco_evolutionary_metabolic_rate`,
`eco_evolutionary_investment`, `eco_evolutionary_cooperation`,
`eco_evolutionary_metabolic_code`) evolves a **single heritable channel**: a
genome trait feeding a shared per-species PPO policy. All four came back null
on selection-driven drift after proper neutral-drift-control replication (see
`predpreygrass/evolutionary/RESULTS.md`, Trials 1-7) — either because the trait
sits on a smooth fitness landscape ordinary selection can already climb
unassisted (Hinton & Nowlan's diagnosis for Trials 1-6), or, for the one
genuinely rugged trait tried (`metabolic_code`'s combinatorial loci, Trial 7),
still null.

This module tries a structurally different mechanism instead of another
variation on "one gene, one shared policy": **dual inheritance / gene-culture
coevolution** (Boyd & Richerson, 1985; Cavalli-Sforza & Feldman, 1981). Two
inheritance channels, not one, evolving at different speeds:

- **Genetic** (slow, vertical-only, mutation-selection): `plasticity`, a
continuous trait inherited through the existing `Genome` machinery.
- **Cultural** (fast, vertical *and* horizontal, imitation-driven): `dialect`,
a live, mutable, per-agent state that can change many times within one
agent's own lifetime via social learning from neighbors.

Critically, the gene does **not** encode behavior directly — it encodes
*capacity to adopt culture*. This is the literal Baldwin/dual-inheritance
move, and it targets a landscape that is inherently non-smooth (a
coordination game, not a scalar optimum), which is the shape prior modules'
theoretical note said was missing for a Baldwin effect to have anything to
act on.

## The two channels

**`dialect`** (categorical, one of `n_dialects` = 4 arbitrary codes, no code
intrinsically better than another): every agent has a *founder* dialect,
inherited like any other genome field, and a separate *live* dialect
(`agent_live_dialect`), seeded from the founder value at birth but free to
change within that agent's own lifetime. Every `plasticity_check_interval`
steps, each agent looks at the live dialects of same-species neighbors within
`culture_range` (Chebyshev distance) and, with probability equal to its own
`plasticity`, adopts the local majority (`_apply_cultural_learning`). This is
a genuinely per-individual lifetime process, deliberately independent of the
shared PPO policy — the same architectural move `eco_evolutionary_metabolic_code`
used for its per-individual loci-solving, but here decoupled at a landscape
that is frequency-dependent rather than a fixed combination lock.

**`plasticity`** (continuous, `[0, 1]`, Gaussian mutation on reproduction,
same convention as every prior module's scalar trait): the actual Darwinian
gene under test. It sets how readily an agent's culture tracks the local
consensus. High-plasticity lineages track a locally-advantageous dialect
fast; low-plasticity lineages stay put. This is the trait the replication
methodology below tests for selection-driven drift on — not `dialect` itself
(frequency-dependent drift on `dialect` is close to a foregone conclusion and
not informative on its own).

## Fitness effect: a coordination game, not a gradient

A catch (predator) or graze (prey) event grants `coordination_bonus_multiplier`
(default 1.5x) on the energy gained *if* the agent's current live dialect
matches its local same-species majority at that moment
(`_dialect_match_bonus`). This is deliberately **not** a smooth function of
any single scalar — whether a given dialect pays off depends entirely on what
neighbors currently do, which itself depends on the history of social
learning in that neighborhood. A dialect that is locally dominant in one
region may be a minority elsewhere. This is the "needle in a haystack" shape
Hinton & Nowlan's own limitation note says a Baldwin effect needs, achieved
through a coordination game instead of a combinatorial lock.

## The reverse leg: policy conditioned on cultural state

`include_culture_in_obs` (default `True`) adds two observation channels: the
agent's own live dialect (normalized) and whether it currently matches the
local majority. This lets the shared PPO policy learn to condition
movement/hunting on rapidly-changing cultural state (e.g., clustering with
same-dialect neighbors) — a plausible route to the "genome/culture shift
feeds back into learned behavior" leg that every prior module left
unconfirmed. Every prior module kept the genome fully invisible to the
policy; this module is a deliberate departure from that convention because
the reverse leg specifically requires the policy to be able to *see* the
state genes have leverage over.

## What's deliberately unchanged

- **Offspring investment** is a fixed, non-heritable constant
(`offspring_investment_fraction`, default 0.35) — the heritable channels
here are plasticity/dialect, not investment fraction.
- **Sustainability mechanism** (predator satiation cooldown + per-catch
energy cap) is ported unchanged from `eco_evolutionary_metabolic_rate` /
`eco_evolutionary_investment` / `eco_evolutionary_metabolic_code` — an
already-validated, orthogonal concern (criteria 1/2 of the project goal),
not something this trial re-tests.
- **Reproduction/energy dynamics** are otherwise identical to
`eco_evolutionary_metabolic_code`.

## Predictions and what to watch in training

1. **Primary (dual-inheritance Darwin-signal) test:** live-population mean
`plasticity` should drift away from the founder mean (0.1) under real
selection, and — critically — should drift **further than the
neutral-drift control** (`genome_neutral_drift_control=True`, same
mechanism ported from every prior module). This is the headline
comparison in `analyze_replication_seeds.py`
(`live_culture/{species}_plasticity_mean`), using the |deviation from
founder| methodology (no a-priori direction, unlike `metabolic_code`'s
directional mean-WRONG-loci test).
2. **Individual-level cross-check:** `{species}_plasticity_repro_spearman`
(genome plasticity vs. binary reproduced-or-not, this episode) — a more
direct test than the population-mean metric, since it doesn't need
selection to move the aggregate before it's detectable.
3. **Secondary (cultural dynamics) signals, not the headline test:**
`{species}_dialect_entropy` (0 = one dialect has fixed locally; `ln(4)` =
maximum diversity) and `{species}_dialect_match_rate` (fraction of
catch/graze events that earned the coordination bonus) — these should
move even under the neutral control (culture is not genetically
inherited in the sense being tested), so they're diagnostic of the
cultural-learning mechanism working at all, not of selection on
`plasticity`.

Metrics are logged both per-step (`live_culture/*`, currently-alive
population only — `_build_live_culture_metrics`) and per-episode
(`eco_evolution/*`, live + completed agents this episode —
`_build_episode_training_metrics`), mirroring the dual-metric pattern used by
every prior module in this family.

## Methodology this module inherits

Directly ported from `eco_evolutionary_metabolic_code` / `eco_evolutionary_investment`:
- **Satiation-throttle sustainability** — validated, not re-tested here.
- **`genome_neutral_drift_control`** — severs genome inheritance from
reproductive success (offspring template becomes a uniformly random
currently-alive same-species agent instead of the true parent); population/
energy dynamics unchanged. Isolates mutation + finite-population sampling
noise from genuine selection.
- **Pilot-first discipline** — a short single-seed pilot before committing to
a full 3-seed-per-group Mann-Whitney replication. Every prior module in
this project paid for skipping this step at least once.

## Status

Implemented and unit-tested (27 tests covering genome sampling/mutation for
both channels, the cultural-learning update rule and its plasticity-gating,
the coordination-bonus energy-gain hook, neutral-drift-control template
selection, and the metrics builders), plus a 300-step random-policy smoke run
with no errors. No PPO training pilot or replication run launched yet —
launching one is a separate, expensive decision, not automatic once
implementation lands. See `predpreygrass/evolutionary/RESULTS.md`'s Trial 8
entry for the current state of that decision, and `RESULTS.md` in this
directory for the (currently empty) run log.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Training Analysis — eco_evolutionary_cultural_plasticity

**Status: implementation + verification only. No PPO training pilot or
replication run has been launched yet.** See `README.md` for the trait
design (dual inheritance: `plasticity` genetic, `dialect` cultural) and
`predpreygrass/evolutionary/RESULTS.md`'s Trial 8 entry for the cross-module
framing and the current state of the follow-up decision on whether/when to
launch a real run.

---

## 1. What's been done so far

- **Implementation.** `predpreygrass_rllib_env.py`, `utils/genome.py`, and
the config pair (`config_env_eco_evolutionary.py` /
`config_env_eco_evolutionary_neutral_control.py`) built by adapting
`eco_evolutionary_metabolic_code`'s scaffold: same reproduction/energy/
satiation-throttle mechanics, new dual-inheritance genome
(`plasticity` + `dialect`), new `_apply_cultural_learning` /
`_local_majority_dialect` / `_dialect_match_bonus` mechanism, two new
observation channels (`include_culture_in_obs`), and `live_culture/*` /
`eco_evolution/*` metrics (`_build_live_culture_metrics`,
`_build_episode_training_metrics`).
- **Unit tests.** 27 tests in `tests/test_eco_evolutionary_validation.py`,
all passing: genome founder sampling and bounds for both the continuous
(`plasticity`) and categorical (`dialect`) fields; zero- and full-rate
mutation behavior for both fields; the cultural-learning update rule
(check-interval gating, plasticity-gated adoption, zero-plasticity never
adopts); `_local_majority_dialect` correctness (excluding the focal
agent's own vote); the coordination-bonus energy-gain hook on both match
and mismatch; `genome_neutral_drift_control` template selection; the
RLlib multi-agent contract tests (termination/truncation/observation
bookkeeping) ported unchanged from `eco_evolutionary_metabolic_code`;
dialect-entropy and the dependency-free Spearman helper (including the
tie-averaging fix needed because one of its two inputs, reproduced-or-not,
is binary and ties heavily).
- **Smoke runs.** 300 steps under a uniform-random policy (real config) and
100 steps under the neutral-drift-control config, both to completion with
no errors, plausible-looking `plasticity`/`dialect_entropy`/
`dialect_match_rate` metrics at episode end. This is not a training run —
no learning occurred — it only exercises the full step/reproduction/
cultural-learning/metrics code path at realistic population scale.

## 2. Not yet done

- **Sustainability/coexistence pilot** under PPO training (criteria 1/2 of
the project's Darwin/Baldwin goal). The satiation-throttle constants are
ported unchanged from already-validated modules, so this is expected to
transfer, but hasn't been confirmed for this specific environment variant
(the two new observation channels and the coordination-bonus energy
dynamics are new).
- **Real vs. neutral-control multi-seed replication** on `plasticity` drift
(criterion 3 — the actual dual-inheritance selection test). Requires the
pilot above first, per this project's own established discipline (every
prior module paid for skipping straight to replication at least once).
- **Parameter tuning.** `n_dialects=4`, `culture_range=3`,
`coordination_bonus_multiplier=1.5`, `plasticity_check_interval=5`, and
the founder `plasticity_mean=0.1` are reasonable starting defaults, not
validated against real training data.

## 3. Next step

Launch a short single-seed pilot (a few hundred iterations) to check
sustainability/coexistence before committing to a full replication —
same pilot-first discipline used by every prior module in this family.
Loading
Loading