Skip to content
Open
80 changes: 80 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,86 @@

## Unreleased (on master)

#### New: Alias elimination for `ReactionSystem`s

- **New `aliases` field on `ReactionSystem`** for declaring symbol equivalences
(`lhs ~ rhs` means lhs is eliminated in favor of rhs). Aliases are automatically
eliminated during model conversion (`ode_model`, `sde_model`, `jump_model`,
`hybrid_model`, `ss_ode_model`) and problem construction (`ODEProblem`, `SDEProblem`,
`JumpProblem`, `HybridProblem`, `NonlinearProblem`, `SteadyStateProblem`).

Supported alias types (v1):
- Ordinary species to ordinary species
- BC-species to BC-species
- Constant species to constant species
- Non-species unknowns (variables) to non-species unknowns
- Parameters to parameters (with strict metadata matching)

Not supported in v1: Brownian, Poissonian, compound species, binding key, and
observable aliasing. Cross-category aliasing (e.g. species to parameter) is rejected.

- **New `@aliases` DSL option** for declaring aliases in `@reaction_network` and
`@network_component`:
```julia
rn = @reaction_network begin
@aliases begin
A ~ B # Species alias: A eliminated, B survives
k1 ~ k2 # Parameter alias: k1 eliminated, k2 survives
end
k1, A + C --> D
k2, B --> E
end
```

- **New `eliminate_aliases` keyword argument** (`true` by default) on all model
conversion functions and problem constructors. Set to `false` to keep aliases as
algebraic constraints (ODE/SDE paths only; jump systems require elimination).

- **New `remap_alias_inputs` function** for remapping user-provided `u0`/`p` maps
when using the `*_model` → `*Problem(::System, ...)` workflow. Works on any
`AbstractSystem` with alias maps in metadata.

- **Aliases are handled through composition**: `compose(...; aliases=...)` accepts
cross-subsystem aliases, `extend` unions aliases from both systems, and `flatten`
collects aliases from subsystems with namespacing.

- **`isequivalent` compares aliases** (set equality).

- **Serialization of aliases is not yet supported** and will error if attempted.

- **Non-symbolic (function-based) jumps** (`ConstantRateJump`/`VariableRateJump` with
plain Julia functions for rate/affect) are now rejected at `ReactionSystem`
construction time with an informative error. These were never supported by MTKBase.

**Known limitations (v1):**

The following alias types are rejected with an informative error:
- Brownian ↔ Brownian aliasing
- Poissonian ↔ Poissonian aliasing
- Compound species aliasing (either side)
- Aliases involving binding keys (either side)
- Aliases involving observable symbols directly
- Cross-category aliasing (e.g. species ↔ parameter, BC ↔ ordinary species)
- `MassActionJump` in systems with aliases (stoichiometry remapping deferred)

The following metadata mismatches are rejected:
- Parameter type mismatch (e.g. `Int64` ↔ `Float64`)
- Parameter or species/variable unit mismatch
- Time-dependent ↔ non-time-dependent parameter mismatch

Other known limitations:
- Serialization of systems with aliases errors (deferred alongside tstops/brownians/poissonians)
- `eliminate_aliases=false` is not supported for jump systems (algebraic constraints
cannot be carried by jump systems)
- When using the `*_model` → `*Problem(::System, ...)` workflow, users must call
`remap_alias_inputs` manually on `u0`/`p` maps. The automatic remapping only
applies to the `*Problem(::ReactionSystem, ...)` path.
- Substitution is unconditional per-expression (no expression-level early-exit guard);
mitigated by category-level fast paths when alias submaps are empty
- `system_to_reactionsystem` reverse conversion produces an empty `aliases` field
(the original alias declarations are cleared after elimination, though the
substitution maps survive in metadata for `remap_alias_inputs`)

## Catalyst 16.1

- Added `use_jump_ratelaws` keyword argument to `ode_model`, `sde_model`, `hybrid_model`,
Expand Down
54 changes: 54 additions & 0 deletions docs/src/devdocs/dev_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,57 @@ To build the Catalyst documentation locally:

### [Spellchecking in your code](@id devdocs_advice_codespellchecker)
Especially when writing documentation, but also when writing normal code, it can be useful to have a spellchecker running through your texts. While code can be copied into a spellchecker and checked there (which is still useful to check grammar), it can also be very useful to (for users of VSCode) run the [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) extension. This will automatically provide simple spell-checking for code and documentation as you write it.

## [Adding a new field to `ReactionSystem`](@id devdocs_new_field)

When adding a new field to the `ReactionSystem` struct, the following locations
must all be updated. Missing any of these can cause subtle bugs.

### Core struct and constructors
- **`reactionsystem_fields` constant** (`src/reactionsystem.jl`) — add the field
name in the correct position.
- **Struct definition** (`src/reactionsystem.jl`) — add the field with docstring.
- **Inner constructor** (`src/reactionsystem.jl`) — add as positional argument and
in the `new{...}(...)` call.
- **5-argument constructor** (`src/reactionsystem.jl`) — add as keyword argument
with default, pass to inner constructor.
- **`make_ReactionSystem_internal`** (`src/reactionsystem.jl`) — add as keyword
argument, pass through to 5-arg constructor.

### Composition and flattening
- **`flatten`** (`src/reactionsystem.jl`) — collect field from subsystems
(recursively if needed) and pass to constructor.
- **`compose`** (`src/reactionsystem.jl`) — add keyword argument if the field
should be settable at compose time; merge via `@set!`.
- **`extend`** (`src/reactionsystem.jl`) — union/merge field from both systems.

### Accessors
- **`get_*` accessor** (`src/reactionsystem.jl`) — top-level only (uses `getfield`).
- **Recursive accessor** (`src/reactionsystem.jl`) — collects from subsystems with
namespacing (if applicable).
- **Exports** (`src/Catalyst.jl`) — export public accessors.

### Equality and serialization
- **`isequivalent`** (`src/reactionsystem.jl`) — add comparison for the field.
- **`save_reactionsystem`** (`src/reactionsystem_serialisation/serialise_reactionsystem.jl`)
— add serialization support or an error guard if not yet supported.
- **`reactionsystem_uptodate_check`** — automatically covered by `reactionsystem_fields`.

### Conversion pipeline
- **`hybrid_model`** (`src/reactionsystem_conversions.jl`) — pass field through to
`MT.System` constructor if applicable.
- **`ss_ode_model`** (`src/reactionsystem_conversions.jl`) — same (separate code path).
- **`sde_model` legacy path** (`src/reactionsystem_conversions.jl`) — same.
- **`eliminate_aliases`** (`src/alias_elimination.jl`) — substitute through the
field if it contains symbolic expressions.

### DSL
- **`option_keys`** (`src/dsl.jl`) — add if the field has a DSL option.
- **`read_*_option`** (`src/dsl.jl`) — implement the option reader.
- **`make_reaction_system`** (`src/dsl.jl`) — wire into the generated code.

### Other
- **`system_to_reactionsystem`** (`src/reactionsystem_conversions.jl`) — handle in
reverse conversion (or document as lost).
- **Tests** — add to appropriate test file.
- **HISTORY.md** — document for users.
7 changes: 6 additions & 1 deletion src/Catalyst.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Symbolics: SymbolicT
using Symbolics: iscall, sorted_arguments, value
using ModelingToolkitBase: get_unknowns, get_ps, get_iv, get_systems,
get_eqs, toparam, get_var_to_name, get_observed,
getvar, has_iv, JumpType
getvar, has_iv, JumpType, get_noise_eqs

import ModelingToolkitBase: get_variables, namespace_expr, namespace_equation,
modified_unknowns!, namespace_variables,
Expand Down Expand Up @@ -108,6 +108,7 @@ const CatalystEqType = Union{Reaction, Equation}
include("reactionsystem.jl")
export ReactionSystem, isspatial
export species, nonspecies, reactions, nonreactions, speciesmap, paramsmap
export aliases, has_aliases, aliases_present
export numspecies, numreactions, numparams
export make_empty_network
export dependants, dependents, substoichmat, prodstoichmat, netstoichmat
Expand All @@ -126,6 +127,10 @@ include("reactionsystem_metadata.jl")
@public has_u0_map, get_u0_map, set_u0_map
@public has_parameter_map, get_parameter_map, set_parameter_map

# Alias classification, validation, resolution, and elimination.
include("alias_elimination.jl")
export AliasClass

# Conversions of the `ReactionSystem` structure.
include("reactionsystem_conversions.jl")
export ODEProblem, SDEProblem, JumpProblem, NonlinearProblem,
Expand Down
Loading
Loading