# Elementary cores, abundant reactions, and the union-closed boundary

This standalone toolkit accompanies *Elementary cores, abundant reactions, and the union-closed boundary of autocatalytic reaction systems* (13 September 2026). Original PDF SHA-256: `5d7518980a46f1080e39ca4631539a82ba2c8d91b4362c4b778535ef5fd1fd50`.

An RAF is a nonempty collection of reactions whose reactants can be generated from food and whose catalysts are available in that generated molecular closure. An elementary core is itself an RAF and all its reactions have food reactants. The paper proves that such a core contains a reaction occurring in at least half the RAF family **with the empty set included**. Exterior reactions may consume core products and feed catalysts back into the core.

This is a structural set model. There are no concentrations, rates, thermodynamic assumptions or experimental calibration. Frequency means the fraction of distinct selected reaction sets satisfying the definition; it is not a probability under a kinetic process and does not establish essentiality.

## Run

Python 3.11 or later:

```sh
python -m pip install -r requirements.txt
python -m unittest -v
python example.py --output outputs
```

All scientific calculations use the Python standard library, integer counts and exact fractions. Matplotlib draws the figure. Outputs include the input system, complete RAF families, context-dependent bodies and core subsets, every cell of the counting injection, exact weights, projection-failure witnesses, defect bounds, a cycle-packing certificate, the producer–gate benchmark, all its availability-query answers, CSV tables, a PNG/SVG figure and hashed run metadata.

Edit `FOOD`, `REACTIONS`, `CORE`, `MODULE`, `CONTEXT_WEIGHTS`, `UNION_GROUND` and `UNION_MEMBERS` at the top of `example.py`. Molecular and reaction labels are strings. Reactants, products and catalysts are sets; multiplicities are outside ordinary RAF semantics. The designated core must remain a nonempty food-ready RAF. Weights must be nonnegative and are constant across all compatible core subsets within each exterior context. An omitted context gets zero weight; `report()` without a weights argument uses weight one everywhere. Zero total weight reports no weighted distribution or witness.

## Reusable components

`Reaction` stores the three molecular sets. `CatalyticSystem` supplies synchronous closure stages, food generation, RAF membership, iterative maxRAF pruning, food-ready reactions and exhaustive family enumeration. Closure deliberately ignores catalysts while building molecules. Catalysis is checked only after closure. Merely selecting a reaction does not make its products available if its reactants can never be generated.

`SupportedFamily` implements the horizontal/vertical cell map in the counting proof. Its audit verifies that the additional constraint is upward, every mapped target is an appropriate cell, no two sources collide, and the difference in cell counts equals the core-occupancy slack. This is a finite executable audit, not a rerun of the Lean theorem.

`CoreAnalysis` recomputes each core reaction's support body for every fixed exterior context. Exterior products can make a head automatically supported, but the separate upward constraint still requires joint food generation and exterior catalysis. It checks the reconstructed family against literal RAF membership, computes each fibre slack, sums the global identity, and applies exact context weights. A viable core can contain different abundant reactions under different contexts; the method never assumes one reaction is conditionally abundant everywhere.

`ModuleDiagnostics` uses one maxRAF deletion query per relevant module reaction to decide projection preservation. A failed query returns a genuine global RAF whose intersection with the module fails RAF membership. `defect()` additionally enumerates all rows to measure the exact contribution of these failures. A module is required to be food-ready but need not itself be a RAF.

`FoodReadyGraph` finds a shortest directed cycle by breadth-first search. Its reaction set is a smallest elementary RAF and is guaranteed to contain a globally abundant reaction, without identifying which one. `greedy_packing()` finds disjoint cycles, giving a lower bound on the number of distinct abundant reactions; it does not solve maximum cycle packing. `abundance_candidates()` returns either a cycle certificate, the at-most-two exceptional reactions when there is no elementary core, no RAF, or an explicit result outside the proved structural cases.

`UnionClosedFamily` validates an explicit family and computes its interior and blockers. `FamilyRealization.paired()` constructs the manuscript's producer–gate network using **all** blockers, including an empty blocker for an inactive coordinate. `audit_pairs()` checks the full encoded family, all availability queries including incomplete pairs, frequency preservation through the family bijection, two-round closure, one catalyst per reaction, private catalytic two-cycles, and the exact singleton boundary for elementary RAFs.

`FamilyRealization.exact_ground(predecessors)` implements the separate marker construction for an accessible union-closed family. It realizes its food-feasibility family on the same reaction labels and intersects it with the supplied predecessor-support conditions. It rejects a non-accessible input; it does not search for an unknown antimatroid factorization.

For example, diagnose a larger reaction system without enumerating its RAF family:

```python
from example import Reaction, CatalyticSystem, FoodReadyGraph, ModuleDiagnostics

system = CatalyticSystem({'f'}, {
    'seed': Reaction({'f'}, {'x'}, {'y'}),
    'return': Reaction({'x'}, {'y'}, {'x'}),
})
print(system.max_raf())
print(FoodReadyGraph(system).abundance_candidates())
print(ModuleDiagnostics(system, {'seed'}).projection_queries())
```

Here there is no elementary core: the seed alone lacks its catalyst. The two-reaction RAF nevertheless exists, and the one non-food-ready reaction is an abundance candidate under the separate exceptional-reaction theorem. Projection to the seed fails and the deletion query gives the two-reaction witness.

## What the default demonstration teaches

The four food-ready reactions are the paper's changing-witness example. Core reactions a and b catalyse each other. Exterior g supplies a's catalyst and exterior h supplies b's. The RAF family has 12 members including the empty set, and frequencies are `a=6`, `b=6`, `g=7`, `h=7`.

With exterior g selected, a appears in 2/3 and b in 1/3 of compatible core subsets. With h selected those frequencies reverse. Every context has zero occupancy slack, yet neither core reaction is abundant in both those contexts. The default context weights `(1,3,1,1)` give total weight 18 and core frequencies `5/9` and `4/9`: the weighted theorem guarantees some core witness, not each core reaction. Choosing arbitrary unequal weights for individual RAFs within a context is outside the theorem.

The separate producer–gate benchmark encodes `{empty, ab, ac, bc, abc}` on coordinates `{a,b,c,dead}`. The unused coordinate tests the empty-blocker case. The resulting network has 8 reactions and 14 marker molecules, no elementary RAF, and 256 availability queries. Every answer agrees with the encoded interior on complete producer–gate pairs. Closure always stabilizes within two growth rounds. Despite this sparse catalytic structure, arbitrary reactant requirements can encode any finite union-closed family: the construction demonstrates the boundary of the proved method, **not** a proof of the unrestricted half-frequency conjecture.

The remaining manuscript fixtures demonstrate genuine feedback with preserved projection, failure of a maximal-RAF average bound, and failed projection with a tight defect bound. Seven scientific test groups additionally exhaust all three-head nonempty support-body choices under principal upward constraints, all union-closed families on three coordinates, and compare pruning, shortest cycles and projection queries against exhaustive results in 75 deterministically generated small systems.

## Scale and evidence

Closure, maxRAF, projection queries and shortest-cycle extraction work without enumerating RAF families. Complete families, fibre audits, defect counts, blocker construction and all-query audits are exponential. `ENUMERATION_LIMIT` rejects oversized subset enumerations rather than returning incomplete counts. It bounds the number of subsets in each enumeration, not the total time of nested audits. A linear number of reactions in a realization does not mean a polynomial-size molecule or incidence description: blockers may be exponentially numerous.

The implementation checks concrete finite instances and the displayed counting map. It does not rerun Lean, prove the general theorem anew, or solve the unrestricted union-closed conjecture. The examples add no kinetic interpretation to structural abundance.

## Reuse terms

MIT licensing is proposed pending the owner's decision. This example does not independently grant a new license; confirm repository terms before redistribution.
