mstlo Python Interface
Python bindings for the Online Signal Temporal Logic (STL) monitoring library.
Installation
You can install the mstlo Python interface using pip:
pip install mstlo-python
Quick Start
import mstlo_python as mstlo
# Define an STL formula: Always[0,5](x > 0.5)
formula = mstlo.Formula.always(0, 5, mstlo.Formula.gt("x", 0.5))
# Create a monitor with Rosi semantics
monitor = mstlo.Monitor(formula, semantics="Rosi")
# Feed data and get verdicts
result = monitor.update("x", 1.0, 0.0)
for ts, val in result.verdicts():
print(f"t={ts}: {val}")
# Or access structured data via dictionary
result_dict = result.to_dict()
for evaluation in result_dict['evaluations']:
print(evaluation['outputs'])
Features
Multiple Semantics
The library supports four types of monitoring semantics:
-
DelayedQualitative (
semantics="DelayedQualitative"): Boolean satisfaction with delayed evaluation- Returns:
TrueorFalse - Waits for complete information before producing verdicts
- Returns:
-
EagerQualitative (
semantics="EagerQualitative"): Boolean satisfaction with eager evaluation- Returns:
TrueorFalse - Produces verdicts as soon as possible
- Returns:
-
DelayedQuantitative (
semantics="DelayedQuantitative", default): Quantitative robustness as a single value- Returns: Float value (positive = satisfied, negative = violated)
-
Rosi (
semantics="Rosi"): Robustness as an interval- Returns: Tuple
(min, max)representing robustness interval
- Returns: Tuple
Monitoring Algorithms
- Incremental (
algorithm="Incremental", default): Efficient online monitoring using sliding windows - Naive (
algorithm="Naive"): Simple but less efficient approach
Signal Interpolation
How a signal behaves between its own samples. This is what the formula is evaluated over, so it decides the verdicts.
- ZeroOrderHold (
signal_interpolation="ZeroOrderHold", default): the signal holds its last value until the next sample arrives. - Linear (
signal_interpolation="Linear"): the signal ramps linearly between consecutive samples. A predicate then reports the exact time its threshold is crossed rather than waiting for the next sample. Withx = 6.0@0s, 2.0@4s,x > 4becomes false at2sunder Linear and at4sunder ZeroOrderHold.
Linear is available for the two qualitative semantics only, and requires the
Incremental algorithm. Combining it with DelayedQuantitative or Rosi raises
ValueError: the satisfaction signal of a predicate over a linear signal is still
piecewise constant, so crossings make the qualitative answer exact, but a
piecewise-linear robustness needs its window supremum recovered, which crossings alone
do not give.
Only the samples you supply are ever monitored — no values are synthesized at other
signals' timestamps. A multi-signal formula is evaluated at each signal's own
timestamps, reading the other operands through the interpolation above. The one
exception is each signal's value at t=0, below.
Initial Values
A formula over more than one signal is read from t=0. A signal whose first sample
arrives later would leave a prefix where the formula is read from the other signals
alone, so init_signals= gives each signal the value it holds until its own first
sample:
monitor = mstlo.Monitor(
mstlo.parse_formula("G[0,2]((x > 0) && (y > 0))"),
init_signals={"x": 0.0, "y": 1.0},
)
Anything left out is 0.0. A signal that really is sampled at t=0 overrides its
initial value, so a trace that starts every signal together is monitored exactly as it
is written. A single-signal formula is defined wherever its signal is and ignores
init_signals entirely.
An initial value is data you assert, not data that was measured: with the default
0.0, x > 0 is definitely false until x is first sampled.
Deprecated: synchronization
The synchronization= argument is deprecated. Passing it emits a DeprecationWarning
and selects the signal interpolation of the same name, with "None" meaning
"ZeroOrderHold":
| deprecated | use instead |
|---|---|
synchronization="ZeroOrderHold" |
signal_interpolation="ZeroOrderHold" |
synchronization="None" |
signal_interpolation="ZeroOrderHold" |
synchronization="Linear" |
signal_interpolation="Linear" |
If both are given, signal_interpolation wins. Monitor.get_synchronization_strategy()
is deprecated in the same way; use Monitor.get_signal_interpolation().
Constructing STL Formulas
You can construct STL formulas using the provided API. For example:
# Define a formula: Always[0,5](x > 0.5)
formula = mstlo.Formula.always(0, 5, mstlo.Formula.gt("x", 0.5))
# using parser
formula = mstlo.parse_formula("G[0,5](x > 0.5)")
This creates a formula that states "x should always be greater than 0.5 in the interval [0, 5]". See the API reference for more details on constructing formulas.