qualitative-qsim
A Python/PyTorch library for qualitative reasoning (QR) about dynamical systems: simulating and analyzing the behavior of continuous systems when the governing equations are only partially known — described by monotonic relationships, signs, orderings, and landmark values rather than exact functions and parameters.
The initial centerpiece is an implementation of QSIM (Kuipers-style qualitative simulation), with the architecture deliberately laid out so other QR formalisms (envisionment, process-based modeling, semi-quantitative refinement) and tensorized/GPU-accelerated execution can slot in alongside it.
Status: functional alpha. The practical QSIM path, core model representation, behavior graphs, serialization, and numeric coverage bridge are the supported alpha core. The broader research surface is deliberately exposed at lower maturity levels rather than implied to have uniform validation. The project is available under the MIT License; APIs are pre-1.0 and may change.
| Maturity | Surface | What the label means |
|---|---|---|
| Core alpha | Model/QSIM practical profile, behavior graphs, schemas, trajectory abstraction and coverage | Supported alpha path; golden, adversarial, integration, and concrete-trajectory soundness checks |
| Experimental | Classic landmark discovery, chatter controls, energy/Lyapunov and phase filters, Q2 refinement, tensor execution and differentiable losses | Semantics and limitations are tested, but configuration and performance contracts may change |
| Research preview | Diagnosis, decomposition, induction, envisionment/guidance, process/device front ends, monotonicity and comparative/causal analysis | Usable and evidence-backed, but narrower scenario coverage; independently audit before consequential use |
The maturity and qualification record lists the evidence and known limits behind each label. The roadmap records implementation scope, not a claim that every module has equal validation depth.
Why qualitative reasoning?
A numeric simulator answers "what does this system with these parameters do from this initial condition?" A qualitative simulator answers a complementary question: "what are all the behaviors any system consistent with this qualitative description can exhibit?"
That makes QR useful for:
- Incomplete models — reasoning when you know
flow increases with levelbut not the pipe's discharge coefficient. - Behavior enumeration — producing the complete branching tree of qualitatively distinct outcomes (overflows / reaches equilibrium / oscillates), with guarantees that no real behavior is missed.
- Abstraction of numeric systems — compressing families of numeric trajectories into a small graph of qualitative states, giving a discrete, symbolic summary of a continuous system's phase portrait.
- Verification and explanation — checking that a fitted or learned numeric model only does things the qualitative physics allows, and explaining behaviors in human terms ("the level rises, decelerating, toward equilibrium").
Shape of the library
Model description Reasoning engines Analysis / bridge
───────────────── ───────────────── ──────────────────
QuantitySpace QSIM simulation Behavior graphs + queries
Variables (mag, dir) Attainable envisionment Trajectory abstraction
Constraints (M+, ADD, Batched/tensorized Coverage oracle
DERIV, MULT, ...) filtering (torch) Sign-structure intake
Corresponding values Semi-quantitative (Q2) Explanation + viz
Operating regions Landmark discovery Landmark harvest/proposal
docs/— design notes: vision, the hands-on tutorial, QR landscape survey, research references and implementation lineage, architecture, QSIM deep-dive, compact constraint syntax, signed-graph consistency, tensorization & GPU strategy, production-shaped scale profiles, numeric bridge, host integration, piecewise-affine analysis, literature survey, roadmap, and open questions.src/qrlib/— the library: core representations, the reference and tensorized engines, the numeric bridge, semi-quantitative refinement, analysis, and visualization (the architecture guide maps the layout).tests/— golden models, equivalence properties, and the soundness harness (concrete ODE instances integrated, abstracted, and verified against predicted behavior graphs).benchmarks/— measured reference-vs-tensor comparisons.
Installation
The supported install includes PyTorch:
pip install qualitative-qsim
PyTorch is imported lazily: ordinary model construction, reference
simulation, analysis, and the pure-Python bridge do not import it, while
SimConfig(backend="auto") uses tensor filtering only when the measured
workload shape benefits; explicit "reference" / "tensor" modes and
qrlib.tensor use the installed dependency directly.
Quick taste
import qrlib as qr
from qrlib import Qdir
from qrlib.analysis import explain
m = qr.Model("bathtub")
m.variable("amount", landmarks=("0", "FULL"))
m.variable("level", landmarks=("0", "TOP"))
m.variable("outflow", landmarks=("0", "OMAX"))
m.variable("inflow", landmarks=("0", "IF*"))
m.variable("netflow", landmarks=("0",), unbounded=True)
m.constrain(qr.MPlus("amount", "level", cvals=(("0", "0"), ("FULL", "TOP"))))
m.constrain(qr.MPlus("level", "outflow", cvals=(("0", "0"), ("TOP", "OMAX"))))
m.constrain(qr.Add("netflow", "outflow", "inflow")) # netflow + outflow = inflow
m.constrain(qr.Deriv("amount", "netflow")) # d(amount)/dt = netflow
m.constrain(qr.Constant("inflow"))
initial = m.state(
amount=("0", Qdir.INC), level=("0", Qdir.INC), outflow=("0", Qdir.INC),
inflow=("IF*", Qdir.STD), netflow=(("0", "+inf"), Qdir.DEC),
)
result = qr.qsim(m, initial)
for b in result.behaviors():
print(explain.narrate(result.graph, b))
yields exactly the three textbook outcomes — equilibrium below FULL, equilibrium exactly at FULL, and overflow. The practical default keeps an intermediate equilibrium unnamed:
Behavior of 'bathtub': 3 states, ending in quiescent.
0. Initially, amount at 0, rising, level at 0, rising, ...
1. Then, over an interval, amount rises into (0, FULL); ...
2. At the next instant, amount levels off in (0, FULL); ...
— the system is in equilibrium ...
SimConfig() is the sound, bounded practical profile: landmark discovery is
off and structurally unobservable direction chatter is merged automatically.
Use SimConfig.classic() when named intermediate extrema and full textbook
QSIM discovery are required; classic runs may not terminate and report
actionable diagnostics when a resource limit is reached.
Constraints may equivalently use the optional compact authoring syntax, for
example m.constrain("Deriv(amount, netflow)"); models still store and
serialize ordinary constraint objects.
From here: qrlib.bridge.coverage checks numeric trajectories against the
graph (witness paths / localized refutations), qrlib.semiquant turns
landmark bounds and monotone-function envelopes into guaranteed value and
transition-time bounds (and prunes numerically impossible behaviors), and
qrlib.viz renders timelines and behavior trees as plain data or SVG.
Additional modules provide total envisionment, temporal-logic guidance,
model induction and diagnosis, comparative/causal analysis, decomposition,
differentiable constraint losses, and process/device modeling front ends.
qrlib.analysis.monotonicity.check_signed_graph additionally certifies
whether all declared M+/M-/Minus relationships admit one consistent
orthant ordering, returning a contradictory signed cycle when they do not.
Design commitments (early)
- Model description is decoupled from every engine. A
Modelis pure data; QSIM, envisioners, tensor engines, and abstraction tools all consume the same description. - PyTorch-native state encoding. Qualitative states have a canonical integer-tensor encoding so that large frontiers, ensembles of models, and batches of numeric trajectories can be processed with batched tensor ops (GPU when it helps; the semantics never require it).
- Numeric systems are first-class neighbors. Interfaces are shaped so a numeric dynamical system (a vector field / trajectory source) can be abstracted into, or checked against, a qualitative model — see the numeric bridge.
- Embeddable by design. Larger dynamical-systems toolkits should be able to build thin adapter modules on top of qrlib — names as canonical identity, no CAS/graph-library dependencies in core, tensors as the only numeric interchange, serializable witness-carrying results — see host integration.
- Soundness is sacred, spuriousness is managed. Like QSIM itself: never drop a real behavior; add filters to prune impossible ones.
Research lineage and citation
The core semantics follow Kuipers1986 and the authoritative Kuipers1994 presentation. Process-centered authoring draws from Forbus1984, device composition and envisionment from deKleerBrown1984, and semi-quantitative refinement from KuipersBerleant1988.
The
canonical annotated bibliography
maps every research-derived feature to its source. Machine-readable records
are in
paper.bib,
software citation metadata is in
CITATION.cff,
and the draft JOSS article is
paper.md.
Metadata
Release files for qualitative-qsim 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| qualitative_qsim-0.1.0.tar.gz | 310.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| qualitative_qsim-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 463.5 kB
Release files / qualitative_qsim-0.1.0.tar.gz
| Download URL | qualitative_qsim-0.1.0.tar.gz |
|---|---|
| Size | 310.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5c56c63f906e0600d89e5f104e3ff5fd93606f92ff0da021b01090373ce059c
|
|
BLAKE2b-256 checksum How to use checksums |
a9a13165759276f517d351314cd8c2ae481ed9cd3fefc2b2ea814443c2f75e96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 26, 2026.
Transparency logRelease files / qualitative_qsim-0.1.0-py3-none-any.whl
| Download URL | qualitative_qsim-0.1.0-py3-none-any.whl |
|---|---|
| Size | 152.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78cfd66a188973150ae442ff35952e1b099d57158da49a3e7f128ee42eda2dd4
|
|
BLAKE2b-256 checksum How to use checksums |
17c81e7dcbc72b52dafef096112990b07b4c2fc593b6a5a98485c66653ffffca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 26, 2026.
Transparency log