Python bindings for the sentil engine. pip install sentil and import it.
SENTIL has three main capabilities. Deterministic STL monitoring, offline over a recorded trace or streaming one sample at a time. Probabilistic monitoring, which fits a noise model to sensor data and estimates satisfaction probability with confidence bounds. And synthesis, from a specification to a control input to an online controller.
Your first monitor
import sentil
trace = sentil.Trace([0, 1, 2, 3, 4], {"speed": [12, 9, 7, 4, 6]})
phi = sentil.Formula.parse("always (speed > 5)")
print(phi.robustness(trace)) # -1.0
The robustness is -1 because the speed dips to 4 at t = 3, one unit under the bound, so the property fails by exactly one. A non-negative value would mean it holds, and the magnitude is the margin. Formulas compose with Python operators, and a trace behaves like a mapping from a name to a NumPy array:
from sentil import var, always, eventually
phi = always(var("speed") > 5) & eventually(var("gap") > 2)
trace["speed"] # the values, as an ndarray
Online streaming
An OnlineMonitor folds one timed reading at a time, at O(1) amortized cost per sample and memory that scales with the window, not the length of the trace. The verdict carries resolved, satisfied, and value, so you can watch a live system and stop the moment it breaks.
import math
import sentil
monitor = sentil.OnlineMonitor("always[0, 10] (x > -0.9)")
for t in range(60):
x = math.sin(t * 0.3)
verdict = monitor.update(float(t), {"x": x})
if verdict.resolved and not verdict.satisfied:
print(f"violated at t={t}, robustness={verdict.value:.3f}")
break
else:
print("held over the whole stream")
satisfied only carries a verdict once resolved is true; until then the monitor is still filling the window, so bound the horizon on a future-time operator.
Probabilistic monitoring
A P~p operator asks whether a formula holds with probability at least (or at most) p. Register a noise model for each sensor; SENTIL lifts every reading into an ensemble, evaluates the formula on each, and returns the probability with a Wilson confidence interval.
import sentil
from sentil import Formula, LiftingRegistry, NoiseModel, SmcConfig
trace = sentil.Trace(list(range(20)), {"x": [0.4 + 0.05 * i for i in range(20)]})
lifting = LiftingRegistry()
lifting.register("x", NoiseModel.gaussian(0.0, 0.3))
phi = Formula.parse("P>=0.9 (always (x > 0))")
result = phi.check(trace, lifting, SmcConfig(samples=5000))
print(f"probability {result.probability:.3f}, "
f"interval [{result.interval.lower:.3f}, {result.interval.upper:.3f}], "
f"holds {result.holds}")
Specifications
The premade library is on the Python side too: vetted specifications across ten domains (aerospace, automotive, controls, financial, industrial, medical, networking, power, robotics, UAV), each with a description, a citation, default parameters, and a deterministic and a probabilistic form. Reach for one instead of writing your own.
import sentil
phi = (
sentil.SpecBuilder("automotive/safe_following_distance")
.with_param("rho", 1.0) # the follower's reaction time
.build_formula()
)
# phi monitors gap, v_r, and v_f against the RSS safe-distance bound
List them with sentil.SpecBuilder.available(), or browse them under specifications/.
Benchmarks
These plots put Python and the Rust core against the baseline tools, from the same runs.
Per-sample streaming cost across the bindings, with the Rust core in front. The offline baselines have no online mode, so nothing else can stream a sample at a time.
Offline cost over the trace length, Python and the core against RTAMT, MoonLight, and Banquo.
Peak memory over the length of the stream.
The full set, including the dense-time, statistical model checking, rare-event, and synthesis benchmarks, is in benchmarks/, and all the results are in docs/CLAIMS.md.
Install
Package manager
From PyPI, with pip:
pip install sentil
or with uv:
uv add sentil
The optional extras pull their dependencies: sentil[pandas] for DataFrame ingest, sentil[plotting] for the robustness plots.
Prebuilt release
Every tagged release attaches prebuilt wheels to the GitHub release; download the one for your Python and platform and install it directly.
Linux and macOS
The shell expands the wildcard to the file you downloaded:
pip install ./sentil-0.3.1-*.whl
Windows
Pass the exact filename, since the shell leaves the wildcard unexpanded:
pip install .\sentil-0.3.1-cp38-abi3-win_amd64.whl
Build from source
You need a Rust toolchain and maturin.
git clone https://github.com/sedislab/SENTIL
cd SENTIL/sentil-py
maturin develop --release
python -m pytest tests
Contributing
Build the extension into your environment and run the suite:
maturin develop --release
python -m pytest tests
The pull-request flow is in the repository CONTRIBUTING.md.
Documentation
The documentation site carries the guides, the specification syntax, and the long-form tutorial.
Citation
If SENTIL is useful in your work, please cite the paper:
@misc{quansah2026sentilruntimeverificationtool,
title={SENTIL: A Runtime Verification Tool for Probabilistic Temporal Logic},
author={Paapa Kwesi Quansah and Ernest Bonnah},
year={2026},
eprint={2605.21676},
archivePrefix={arXiv},
primaryClass={cs.LO},
url={https://arxiv.org/abs/2605.21676}
}
License
SENTIL is by Paapa Kwesi Quansah and Ernest Bonnah at the SEDIS lab, Baylor University. It is dual licensed under either MIT or Apache-2.0, at your option.
Metadata
Release files for sentil 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sentil-0.3.1.tar.gz | 262.8 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| sentil-0.3.1-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details |
| sentil-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details |
| sentil-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ ARM64 | Details |
| sentil-0.3.1-cp38-abi3-macosx_11_0_arm64.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64 | Details |
| sentil-0.3.1-cp38-abi3-macosx_10_12_x86_64.whl | CPython 3.8 | abi3 | macOS 10.12+ x86-64 | Details |
Total release size: 19.7 MB
Release files / sentil-0.3.1.tar.gz
| Download URL | sentil-0.3.1.tar.gz |
|---|---|
| Size | 262.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7b985f43daabda2722e18e1d1de482dad1bd3338f3a7f406c3df88dab9af6165
|
|
BLAKE2b-256 checksum How to use checksums |
4439c2dc9f097bfae07d7d305637c1ae050e47fb4a3f3e950778b64ff721e0d2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / sentil-0.3.1-cp38-abi3-win_amd64.whl
| Download URL | sentil-0.3.1-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 4.5 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
f644c8e1bb8d8ab5c83bc54960e0afcf248c57a962e6f4ab84c738ebc2a263e1
|
|
BLAKE2b-256 checksum How to use checksums |
4b1cf43f2b3ab7cb9706996269af1f5e1065b40954c4b87ce6fd08afed60e3d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / sentil-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | sentil-0.3.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.2 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
37f3c685857911db10403fb7a4d8ba6aaeee288fd97137752a2f52e6bae2db65
|
|
BLAKE2b-256 checksum How to use checksums |
601683b90fb2c70f7f2b224e1a9054a163af907e9bd346c2467bce204e6f06e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / sentil-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | sentil-0.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 3.8 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
ecf5b982d07964e638df91fe31a97388599903eeaf781484bd7283de5dad6e69
|
|
BLAKE2b-256 checksum How to use checksums |
7433466c6e80e2ef004590d05a565f91f016f458f88c29c92938bb86c3c19047
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / sentil-0.3.1-cp38-abi3-macosx_11_0_arm64.whl
| Download URL | sentil-0.3.1-cp38-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 3.4 MB |
| Tags | CPython 3.8 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
09d74de317c7e4ddc4642ab5b2c0280e96216a6985ad406dd6af78670ab7afe8
|
|
BLAKE2b-256 checksum How to use checksums |
04eed0748f8ed3862ffa1e659461974a022e2f18b0b443c5ba18b2ca0446c3dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / sentil-0.3.1-cp38-abi3-macosx_10_12_x86_64.whl
| Download URL | sentil-0.3.1-cp38-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 3.7 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
107cd56ceb8994f0877248fc990f6865a01fe27ee2ad445c1013595e90c83fd3
|
|
BLAKE2b-256 checksum How to use checksums |
d94557bcf7ed8c8e8b3d78250f40022c6e3847f4eeb023eb86e2d5ed4c288377
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log