File size: 5,184 Bytes
0fff343
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# Prompt β€” raise caps, spell out "GP" as "genetic programming", and add DSL operator-usage

Three changes, verified against the code (`web/app/Lab.tsx`, `api/app.py`, `engine_v2/gp.py`). Airgap untouched. `pytest` + `tsc` after.

## 1. Raise the Generations / Population ceilings (web/app/Lab.tsx)
The parameter list (~lines 1202-1208) caps `generations` at `max: 100` and `population` at `max: 500`. Raise both:
- `generations` β†’ `max: 1000`
- `population` β†’ `max: 3000`
Keep them BOUNDED (not removed) so an accidental huge value can't hang the backend. Leave min/step and the other params unchanged.
(Context, not a code requirement: with the current early convergence, more generations alone won't help much β€” the useful long run is "Maintain diversity" ON + larger population.)

## 2. Spell out "GP" as "genetic programming" in all USER-FACING copy (web/app/Lab.tsx)
Replace the abbreviation everywhere it appears in visible text β€” captions, tooltips, headings, labels, axis titles, sort buttons, table headers. Use "genetic programming" in prose; for the compact fitness label use **"Genetic-programming fitness"** (hyphenated; wraps fine). Known locations (search for `GP` to catch any others):
- Parameters subtitle (~1222): "GP knobs…" β†’ "Genetic-programming knobs…"
- Run subtitle (~1374): "Starts a GP run on the backend." β†’ "Starts a genetic-programming run on the backend."
- Copy/tooltips at ~197, 227, 244, 2119, 2588-2591, 4012, 4586 β†’ "genetic programming" / "the genetic-programming search".
- The **"GP fitness"** label everywhere shown: the sort-key label (~4617 `["gp_fitness", "GP fitness"]`), the table header (~4682 `<th>GP fitness</th>`), the scatter axis title (~4233), the scatter heading (~4008 "Landscape β€” GP fitness Γ— Synergy"), the median-guide label (~4185), and the tooltip dt (~4407) β†’ **"Genetic-programming fitness"** (scatter heading β†’ "Genetic-programming fitness Γ— Synergy"; axis β†’ "Genetic-programming fitness β€” what the engine preferred β†’").
- Code COMMENTS that say "GP" (~286, 2160, 2237, 2435, 3800, 4156) are not user-facing β€” optional. **Do NOT change the internal field/key name `gp_fitness`** (API contract) β€” only human-readable labels.

## 3. DSL operator-usage across the whole search (API + frontend)
Show, after a run completes, how often each DSL operator (Select, Reduce, Combine, Split, Associate, Effect, Fit/Apply, Search) was used across **every candidate program in every generation** (Generations Γ— population). Airgap-safe β€” operator names are DSL keywords, no gene names.

### 3a. API β€” new endpoint `GET /runs/{run_id}/operator-usage`
Mirror `_compute_module_ranking` (which already walks `run.log`):
- Iterate every candidate in every persisted generation (`run.log[*].candidates`). Each candidate has a `program_repr` string (e.g. `Combine(Reduce(Select(M,[…]),min),Reduce(Select(M,[…]),var),protected_div)`; built in `engine_v2/gp.py` ~line 132).
- Per operator, count occurrences of its token `Name(` in `program_repr` β€” `Select(`, `Reduce(`, `Combine(`, `Split(`, `Associate(`, `Effect(`, `FitApply(`, `Search(`. (Matching `Name(` avoids false hits; `MatrixTerminal`/`M` is not an operator.) Sum across ALL candidates across ALL generations.
- Return per operator: `total_uses` (sum of occurrences) and `programs_using` (count of candidate-instances containing it β‰₯ once); plus run totals (`n_generations`, `n_candidates`). Note that persistent elites are counted once per generation they appear in (the "Generations Γ— population" grid the user asked for).
- Opaque/airgap-safe (operator keywords + integer counts only). Cache per run; 425 while running, 404 unknown.

### 3b. Frontend β€” show it on the "DSL vocabulary" tiles
After a run completes, fetch `/runs/{id}/operator-usage` and on each operator tile show its usage:
- Under each description: **"used 12,431Γ— β€” in 38% of programs"** (`total_uses`, and `programs_using / n_candidates`).
- A small inline bar per tile (relative to the most-used operator) so the distribution is scannable β€” Select/Reduce dominate; Effect/Split/Fit-Apply/Search are rare or 0 (Search off by default β†’ 0).
- Before a run / while running, tiles show just descriptions (gate the counts to a completed run).
- Tile-panel "?" / caption: "Counts every use of each operator across all programs the search tried (generations Γ— population). Select and Reduce are the backbone; Effect, Split, Fit/Apply and Search appear only where the engine reached for them."

## CONSTRAINTS
- Airgap: the operator-usage endpoint emits keywords + counts only β€” no gene IDs/names. Engine/GP search untouched. `gp_fitness` data key unchanged.
- Frontend reads the new endpoint; no change to the run flow.

## Checkpoint
- Generations accepts up to 1000, Population up to 3000.
- No visible "GP" remains in the UI ("genetic programming" / "Genetic-programming fitness"); `gp_fitness` key unchanged.
- `GET /runs/{id}/operator-usage` returns per-operator counts over all generations Γ— population, opaque-safe; tiles show count + share + bar after a completed run (Search reads 0 when off).
- `pytest` green; airgap untouched; `tsc` clean.