Skip to main content

SimpliPy:
Efficient Simplification of Mathematical Expressions

PyPI version PyPI license Documentation Status

pytest quality checks CodeQL Advanced

Publications

  • Saegert & Köthe 2026, Breaking the Simplification Bottleneck in Amortized Neural Symbolic Regression (preprint, under review) https://arxiv.org/abs/2602.08885

Usage

pip install simplipy

The compiled Rust extension (simplipy._core) is required: the inline phase (simplify, conversions, validation) runs on it exclusively, and there is no pure-Python fallback. Prebuilt wheels are published for Linux (x86_64/aarch64), macOS (x86_64/arm64) and Windows (x64) on CPython ≥ 3.11, so pip install simplipy does not compile anything for most users. Installing from the source distribution (an unsupported platform, or --no-binary) requires a Rust toolchain (rustup, MSRV 1.83). If the extension is missing at runtime, constructing an engine raises ImportError.

import simplipy as sp

engine = sp.SimpliPyEngine.load("acj-4-3", install=True)   # a published ruleset artifact

# Simplify prefix expressions
engine.simplify(('/', '<constant>', '*', '/', '*', 'x3', '<constant>', 'x3', 'log', 'x3'))
# > ('<mul>', '<constant>', '<div>', 'log', 'x3', '</mul>')

# Simplify infix expressions
engine.simplify('x3 * sin(<constant> + 1) / (x3 * x3)')
# > '<constant>/x3'

Token input returns the engine's native tagged form by default (n-ary +/* bags are delimited: <add> ... </add>, <mul> ... </mul>; tagged output is accepted back as input). The form parameter selects a different projection of the same canonical answer:

expr = ('/', '<constant>', '*', '/', '*', 'x3', '<constant>', 'x3', 'log', 'x3')

engine.simplify(expr, form='infix')      # the pretty rendering (a str)
# > '<constant>/log(x3)'

engine.simplify(expr, form='explicit')   # binary prefix -- what is_valid / prefix_to_infix read
# > ('/', '<constant>', 'log', 'x3')

Normalization

The root-exported normalize_skeleton, normalize_expression, and normalize_variable_token helpers (also available as simplipy.normalization) canonicalize a prefix token sequence so that two expressions that are "the same" up to variable renaming / constant values compare equal. They are pure-string helpers with no engine state, so consumers such as holdout matching and symbolic-recovery scoring share identical behavior by construction.

import simplipy as sp

# Skeleton form: variables -> x{n}, numeric literals -> <constant>
sp.normalize_skeleton(['+', 'v1', '2.5'])
# > ['+', 'x1', '<constant>']

# Expression form: variables canonicalized, numeric literals kept intact
sp.normalize_expression(['+', 'V1', '2.5'])
# > ['+', 'x1', '2.5']

# Classify / canonicalize a single token -> (normalized_token, is_variable)
sp.normalize_variable_token('X3')
# > ('x3', True)
sp.normalize_variable_token('sin')
# > ('sin', False)

More examples can be found in the documentation.

Performance

As of 0.6.0 the simplify hot path defers match-time certificates to completed matches (memoized generationally, never stopping memoization), memoizes whole fixpoint passes and rule-normal subtrees, and runs on interned token ids (~20× fewer allocations per call) — all at byte-identical outputs. On a 65,536-expression training-prior benchmark (measured at 0.11.0), large certificate-bearing rulesets simplify ~59× faster than 0.5.0 and certificate-free rulesets ~2.3× faster; see the CHANGELOG for details. Since 0.7.0 there is a single compiled engine line; the published ruleset artifacts (acj-2-1, acj-3-2, acj-4-3, …) are the distinguishing factor between engines. Rule application always considers every pattern in the loaded artifact (the former max_pattern_length knob was removed in 0.10.0). (To reproduce the historical dev_7-3 / v23.0-era behavior byte-for-byte, install simplipy<=0.6.0.)

The 0.13 line ships a re-designed, pre-registered benchmark suite: three corpora, every arm timed serial single-core, paired per-row scoring with bootstrap confidence intervals. Across 131,600 scored rows the sound engine never inflates an expression (0.00% made-bigger), wins 9–19% of rows against SymPy's simplify on SR-shaped corpora while SymPy inflates ~40%, and runs a paired median ~600–800× faster. Full results and figures: the simplify guide.

Development

Setup

To set up the development environment, run the following commands:

pip install -e .[dev]
pre-commit install

Tests

Test the package with pytest:

pytest tests --cov src --cov-report html

or to skip integration tests,

pytest tests --cov src --cov-report html -m "not integration"

Citation

@misc{saegert2026breakingsimplificationbottleneckamortized,
  title   = {Breaking the Simplification Bottleneck in Amortized Neural Symbolic Regression},
  author  = {Paul Saegert and Ullrich Köthe},
  year    = {2026},
  eprint  = {2602.08885},
  archivePrefix =  {arXiv},
  primaryClass  = {cs.LG},
  url     = {https://arxiv.org/abs/2602.08885},
}

% Optionally
@software{simplipy-2025,
    author = {Paul Saegert},
    title = {Efficient Simplification of Mathematical Expressions},
    year = 2026,
    publisher = {GitHub},
    version = {0.12.0},
    url = {https://github.com/psaegert/simplipy}
}

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simplipy-0.13.1.tar.gz (2.7 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

simplipy-0.13.1-cp312-abi3-win_amd64.whl (1.2 MB view details)

Uploaded CPython 3.12+Windows x86-64

simplipy-0.13.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ x86-64

simplipy-0.13.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.2 MB view details)

Uploaded CPython 3.12+manylinux: glibc 2.17+ ARM64

simplipy-0.13.1-cp312-abi3-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

simplipy-0.13.1-cp312-abi3-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12+macOS 10.12+ x86-64

File details

Details for the file simplipy-0.13.1.tar.gz.

File metadata

  • Download URL: simplipy-0.13.1.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for simplipy-0.13.1.tar.gz
Algorithm Hash digest
SHA256 fbc78cbc02be0027d320f0ab21198dfa525b6fe71d91a65ee249274f7a60bd98
MD5 98aff734a341ba949a137610bb7b87b5
BLAKE2b-256 d0ad34e25af916b201e5139cbaccc0fa1ce12d1888c2e1b00ca17b2e9a078af8

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1.tar.gz:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simplipy-0.13.1-cp312-abi3-win_amd64.whl.

File metadata

  • Download URL: simplipy-0.13.1-cp312-abi3-win_amd64.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: CPython 3.12+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for simplipy-0.13.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a5e78f2bda8378ec89e055ea3e7892a9dff28e25c11d455b7228dd8cf3156abc
MD5 e2ccf35565f8b5dfe715d8aab3cc5b91
BLAKE2b-256 0bc52a5e5afb31b8a6769afa140a6fe0175d1b2e7e3f2e231cee59dfe896ca85

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1-cp312-abi3-win_amd64.whl:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simplipy-0.13.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for simplipy-0.13.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a079bb80f9ffeab90f3df8fe0ce1f0b21d52f3381b4d8911b9a870b51235e3df
MD5 82fca6dbef20c1732d5a23c896b07d78
BLAKE2b-256 ad910fb3c0479b956aa78d8cb66c44c72155f42f59ea743117dc92b621667199

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1-cp312-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simplipy-0.13.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for simplipy-0.13.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 b043b5d973b469c00982ab0a1ec5cebf41df77428c002efc28bf645264774667
MD5 377f11696465993a40fc970131583f6b
BLAKE2b-256 a76d0a37b15268d7e9a5be98609501ed16c5e4400d1c89741a51337e9cac26f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1-cp312-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simplipy-0.13.1-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for simplipy-0.13.1-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 abf348ea359aea8132b9ae663e49602d5de347a47227368ef94e831ea9ec854a
MD5 f7a46ed08413e5f36db93b1e740eee10
BLAKE2b-256 351aab98ae82057cd93d83984b4406eee0ae55070f7e644414780c1cb1836961

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1-cp312-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simplipy-0.13.1-cp312-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for simplipy-0.13.1-cp312-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b540e449861aee3243d16cd7a6dc020cd16412701018efe5451fa366894334df
MD5 96fcbf09544460cc249d246082ba2eef
BLAKE2b-256 dc5260b3ad53c929ee63f17af7db4e6bff58dc72e500f24ee6f3506fb7e670a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for simplipy-0.13.1-cp312-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on psaegert/simplipy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.14.6

6 files

0.14.5

6 files

0.14.4

6 files

0.14.2

6 files

0.14.1

6 files

0.14.0

6 files

This release

0.13.1 This release

6 files

0.13.0

6 files

0.12.0

6 files

0.11.0

6 files

0.10.1

6 files

0.10.0

6 files

0.9.1

6 files

0.9.0

6 files

0.8.0

6 files

0.7.1

6 files

0.7.0

6 files

0.4.2

6 files

0.4.1

6 files

0.4.0

6 files

0.3.1

6 files

0.3.0

6 files

0.2.15

2 files

0.2.14

2 files

0.2.13

2 files

0.2.12

2 files

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.6

2 files

0.2.5

2 files

0.2.4

2 files

0.2.3

2 files

0.2.2

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page