morphata 2.0.10__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- morphata-2.2.0/.basedpyright/baseline.json +3 -0
- {morphata-2.0.10 → morphata-2.2.0}/.envrc +2 -2
- {morphata-2.0.10 → morphata-2.2.0}/.rstcheck.cfg +2 -0
- morphata-2.2.0/AGENTS.md +40 -0
- {morphata-2.0.10 → morphata-2.2.0}/CHANGELOG.md +134 -20
- {morphata-2.0.10 → morphata-2.2.0}/CONTRIBUTING.md +10 -48
- morphata-2.2.0/PKG-INFO +134 -0
- morphata-2.2.0/README.rst +104 -0
- morphata-2.2.0/bench/conftest.py +32 -0
- {morphata-2.0.10 → morphata-2.2.0}/bench/test_equivalence_perf.py +11 -19
- morphata-2.2.0/bench/test_hoa_exporter_perf.py +151 -0
- {morphata-2.0.10 → morphata-2.2.0}/bench/test_hoa_parser_perf.py +26 -10
- morphata-2.2.0/bench/test_sere_nlm_perf.py +107 -0
- morphata-2.2.0/bench/test_transforms_perf.py +120 -0
- morphata-2.2.0/docs/Makefile +20 -0
- {morphata-2.0.10 → morphata-2.2.0}/docs/api/modules.rst +6 -11
- morphata-2.2.0/docs/api/morphata.acc_expr.rst +6 -0
- morphata-2.2.0/docs/api/morphata.acceptance.rst +6 -0
- morphata-2.2.0/docs/api/morphata.alphabet.rst +6 -0
- morphata-2.2.0/docs/api/morphata.builder.rst +6 -0
- morphata-2.2.0/docs/api/morphata.hoa.rst +43 -0
- morphata-2.2.0/docs/api/morphata.logic.rst +11 -0
- morphata-2.2.0/docs/api/morphata.operators.rst +12 -0
- morphata-2.2.0/docs/api/morphata.symbolic.rst +38 -0
- morphata-2.2.0/docs/changelog.md +2 -0
- {morphata-2.0.10 → morphata-2.2.0}/docs/concepts/acceptance.rst +26 -13
- morphata-2.2.0/docs/concepts/hoa.rst +138 -0
- {morphata-2.0.10 → morphata-2.2.0}/docs/concepts/index.rst +3 -1
- morphata-2.2.0/docs/concepts/operators.rst +229 -0
- morphata-2.2.0/docs/concepts/symbolic.rst +99 -0
- morphata-2.2.0/docs/concepts/weights.rst +150 -0
- morphata-2.2.0/docs/conf.py +186 -0
- morphata-2.2.0/docs/index.rst +135 -0
- morphata-2.2.0/docs/quick-start.rst +221 -0
- {morphata-2.0.10 → morphata-2.2.0}/justfile +8 -5
- {morphata-2.0.10 → morphata-2.2.0}/pixi.lock +3423 -1260
- {morphata-2.0.10 → morphata-2.2.0}/pixi.toml +26 -16
- {morphata-2.0.10 → morphata-2.2.0}/pyproject.toml +40 -10
- morphata-2.2.0/pyrightconfig.json +26 -0
- {morphata-2.0.10 → morphata-2.2.0}/pytest.toml +2 -1
- morphata-2.2.0/rules/no-derivative-multiarg.yml +11 -0
- morphata-2.2.0/rules/no-typing-as-ty.yml +8 -0
- morphata-2.2.0/sgconfig.yml +2 -0
- morphata-2.2.0/src/morphata/__init__.py +21 -0
- {morphata-2.0.10/src/morphata/hoa → morphata-2.2.0/src/morphata}/acc_expr.py +39 -8
- morphata-2.2.0/src/morphata/acceptance.py +1174 -0
- morphata-2.2.0/src/morphata/alphabet.py +92 -0
- morphata-2.2.0/src/morphata/builder.py +190 -0
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/hoa/__init__.py +4 -8
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/hoa/__main__.py +3 -1
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/hoa/parser.py +121 -12
- morphata-2.2.0/src/morphata/logic/__init__.py +14 -0
- morphata-2.2.0/src/morphata/logic/__init__.pyi +25 -0
- morphata-2.2.0/src/morphata/logic/_common.py +383 -0
- morphata-2.2.0/src/morphata/logic/ltl.py +109 -0
- morphata-2.2.0/src/morphata/logic/psl.py +75 -0
- morphata-2.2.0/src/morphata/logic/sere.py +201 -0
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/operators/_backend.py +8 -5
- morphata-2.2.0/src/morphata/operators/matrix.py +326 -0
- morphata-2.2.0/src/morphata/operators/polynomial.py +438 -0
- morphata-2.2.0/src/morphata/symbolic/__init__.py +14 -0
- morphata-2.2.0/src/morphata/symbolic/automaton.py +811 -0
- morphata-2.2.0/src/morphata/symbolic/bdd.py +1162 -0
- morphata-2.2.0/src/morphata/symbolic/utils.py +718 -0
- morphata-2.2.0/src/morphata/utils.py +200 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/conftest.py +64 -34
- morphata-2.2.0/tests/hoa/test_exporter.py +230 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/test_parser.py +5 -3
- morphata-2.2.0/tests/logic/test_ltl.py +315 -0
- morphata-2.2.0/tests/logic/test_psl.py +176 -0
- morphata-2.2.0/tests/logic/test_sere.py +381 -0
- morphata-2.2.0/tests/operators/test_matrix.py +328 -0
- morphata-2.2.0/tests/operators/test_polynomial.py +128 -0
- morphata-2.2.0/tests/symbolic/test_bdd_helpers.py +652 -0
- morphata-2.2.0/tests/symbolic/test_compose.py +177 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/symbolic/test_from_hoaf.py +31 -3
- morphata-2.2.0/tests/symbolic/test_language_equivalence.py +156 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/symbolic/test_ltlf2dfa_equivalence.py +75 -46
- morphata-2.2.0/tests/symbolic/test_symbolic_automaton.py +385 -0
- morphata-2.2.0/tests/symbolic/test_to_hoa.py +97 -0
- morphata-2.2.0/tests/symbolic/test_transforms.py +530 -0
- morphata-2.2.0/tests/test_acceptance_validation.py +79 -0
- morphata-2.2.0/tests/test_alphabet.py +50 -0
- morphata-2.2.0/tests/test_builder.py +138 -0
- morphata-2.2.0/uv.lock +3358 -0
- morphata-2.0.10/.basedpyright/baseline.json +0 -854
- morphata-2.0.10/.claude/settings.local.json +0 -35
- morphata-2.0.10/.codegraph/.gitignore +0 -16
- morphata-2.0.10/.codegraph/codegraph.db +0 -0
- morphata-2.0.10/.codegraph/codegraph.db-shm +0 -0
- morphata-2.0.10/.codegraph/codegraph.db-wal +0 -0
- morphata-2.0.10/.codegraph/daemon.pid +0 -6
- morphata-2.0.10/AGENTS.md +0 -421
- morphata-2.0.10/PKG-INFO +0 -137
- morphata-2.0.10/README.md +0 -106
- morphata-2.0.10/bench/conftest.py +0 -53
- morphata-2.0.10/bench/test_hoa_exporter_perf.py +0 -124
- morphata-2.0.10/bench/test_sere_nlm_perf.py +0 -84
- morphata-2.0.10/bench/test_successors_for_alphabet_perf.py +0 -124
- morphata-2.0.10/cliff.toml +0 -59
- morphata-2.0.10/docs/api/morphata.acceptance.rst +0 -8
- morphata-2.0.10/docs/api/morphata.alphabet.rst +0 -8
- morphata-2.0.10/docs/api/morphata.automaton.rst +0 -11
- morphata-2.0.10/docs/api/morphata.builder.rst +0 -8
- morphata-2.0.10/docs/api/morphata.hoa.rst +0 -29
- morphata-2.0.10/docs/api/morphata.logic.ltl.rst +0 -8
- morphata-2.0.10/docs/api/morphata.logic.psl.rst +0 -15
- morphata-2.0.10/docs/api/morphata.logic.sere.rst +0 -9
- morphata-2.0.10/docs/api/morphata.logic.strel.rst +0 -8
- morphata-2.0.10/docs/api/morphata.operators.matrix.rst +0 -8
- morphata-2.0.10/docs/api/morphata.operators.polynomial.rst +0 -9
- morphata-2.0.10/docs/api/morphata.operators.rst +0 -9
- morphata-2.0.10/docs/api/morphata.symbolic.rst +0 -48
- morphata-2.0.10/docs/concepts/hoa.rst +0 -119
- morphata-2.0.10/docs/concepts/operators.rst +0 -184
- morphata-2.0.10/docs/concepts/spec.rst +0 -133
- morphata-2.0.10/docs/concepts/weights.rst +0 -167
- morphata-2.0.10/docs/conf.py +0 -69
- morphata-2.0.10/docs/index.rst +0 -139
- morphata-2.0.10/docs/quick-start.rst +0 -139
- morphata-2.0.10/docs/symbolic-transforms.rst +0 -187
- morphata-2.0.10/pyrefly.toml +0 -2
- morphata-2.0.10/pyrightconfig.json +0 -14
- morphata-2.0.10/ruff.toml +0 -11
- morphata-2.0.10/src/morphata/__init__.py +0 -29
- morphata-2.0.10/src/morphata/acceptance.py +0 -421
- morphata-2.0.10/src/morphata/alphabet.py +0 -178
- morphata-2.0.10/src/morphata/automaton.py +0 -295
- morphata-2.0.10/src/morphata/builder.py +0 -155
- morphata-2.0.10/src/morphata/hoa/exporter.py +0 -756
- morphata-2.0.10/src/morphata/logic/__init__.py +0 -15
- morphata-2.0.10/src/morphata/logic/_common.py +0 -136
- morphata-2.0.10/src/morphata/logic/ltl.py +0 -363
- morphata-2.0.10/src/morphata/logic/psl.py +0 -372
- morphata-2.0.10/src/morphata/logic/sere.py +0 -517
- morphata-2.0.10/src/morphata/logic/strel.py +0 -545
- morphata-2.0.10/src/morphata/operators/matrix.py +0 -276
- morphata-2.0.10/src/morphata/operators/polynomial.py +0 -350
- morphata-2.0.10/src/morphata/symbolic/__init__.py +0 -52
- morphata-2.0.10/src/morphata/symbolic/automaton.py +0 -621
- morphata-2.0.10/src/morphata/symbolic/bdd.py +0 -822
- morphata-2.0.10/src/morphata/symbolic/compose.py +0 -462
- morphata-2.0.10/src/morphata/symbolic/equivalence.py +0 -187
- morphata-2.0.10/src/morphata/symbolic/persistence.py +0 -381
- morphata-2.0.10/src/morphata/symbolic/transforms.py +0 -674
- morphata-2.0.10/tests/hoa/test_exporter_basic.py +0 -125
- morphata-2.0.10/tests/hoa/test_exporter_roundtrip.py +0 -43
- morphata-2.0.10/tests/hoa/test_exporter_streaming.py +0 -298
- morphata-2.0.10/tests/logic/test_ltl.py +0 -346
- morphata-2.0.10/tests/logic/test_psl.py +0 -179
- morphata-2.0.10/tests/logic/test_sere.py +0 -489
- morphata-2.0.10/tests/logic/test_sere_properties.py +0 -132
- morphata-2.0.10/tests/logic/test_strel.py +0 -244
- morphata-2.0.10/tests/operators/test_matrix_from_ir.py +0 -241
- morphata-2.0.10/tests/operators/test_matrix_from_ltl.py +0 -62
- morphata-2.0.10/tests/operators/test_polynomial_from_ir.py +0 -102
- morphata-2.0.10/tests/symbolic/test_alphabet_aware_transitions.py +0 -168
- morphata-2.0.10/tests/symbolic/test_bdd_helpers.py +0 -277
- morphata-2.0.10/tests/symbolic/test_compose.py +0 -337
- morphata-2.0.10/tests/symbolic/test_composition_map.py +0 -264
- morphata-2.0.10/tests/symbolic/test_equivalence_naive_property.py +0 -130
- morphata-2.0.10/tests/symbolic/test_persistence.py +0 -251
- morphata-2.0.10/tests/symbolic/test_step.py +0 -73
- morphata-2.0.10/tests/symbolic/test_symbolic_automaton.py +0 -380
- morphata-2.0.10/tests/symbolic/test_symbolic_from_ir.py +0 -55
- morphata-2.0.10/tests/symbolic/test_to_hoa.py +0 -163
- morphata-2.0.10/tests/symbolic/test_transforms.py +0 -537
- morphata-2.0.10/tests/symbolic/test_transforms_ir.py +0 -41
- morphata-2.0.10/tests/symbolic/test_transforms_properties.py +0 -118
- morphata-2.0.10/tests/test_alphabet.py +0 -195
- morphata-2.0.10/tests/test_automaton.py +0 -208
- morphata-2.0.10/tests/test_builder.py +0 -124
- morphata-2.0.10/tests/test_from_parsed.py +0 -97
- morphata-2.0.10/ty.toml +0 -7
- morphata-2.0.10/uv.lock +0 -3271
- {morphata-2.0.10 → morphata-2.2.0}/.dockerignore +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.editorconfig +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.envrc.recommended +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.fdignore +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.gitattributes +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.gitignore +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.mailmap +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/.python-version +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/CLAUDE.md +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/LICENSE +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/bench/README.md +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/bench/__init__.py +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/ci/make-release +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/docs/_static/navigation.html +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/mypy.ini +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/project.utf-8.add +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/project.utf-8.add.spl +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/hoa/hoa.lark +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/operators/__init__.py +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/src/morphata/py.typed +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut1.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut11.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut2.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut3.2.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut3.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut4.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut5.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut6.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut7.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/aut8.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/finite_aut.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/gen_buchi_3.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/gen_cobuchi_2.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/rabin_2pair.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/hoa/streett_2pair.hoa +0 -0
- {morphata-2.0.10 → morphata-2.2.0}/tests/logic/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
|
|
3
|
-
set -euo pipefail
|
|
3
|
+
# set -euo pipefail
|
|
4
4
|
|
|
5
5
|
info() {
|
|
6
6
|
DIRENV_LOG_FORMAT="envrc: %s" log_status "$@"
|
|
@@ -23,4 +23,4 @@ export PIXI_ENV
|
|
|
23
23
|
dotenv_if_exists
|
|
24
24
|
|
|
25
25
|
watch_file pixi.lock
|
|
26
|
-
eval "$(pixi shell-hook -e "$PIXI_ENV")"
|
|
26
|
+
eval "$(pixi shell-hook --as-is -e "$PIXI_ENV")"
|
morphata-2.2.0/AGENTS.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Morphata: Agent Context
|
|
2
|
+
|
|
3
|
+
`morphata` does representation theory for automata, and makes it practical.
|
|
4
|
+
It packages structural automaton representations together with semiring-valued
|
|
5
|
+
*operators* that turn an automaton into a computable interpretation.
|
|
6
|
+
|
|
7
|
+
## What Agents Are for Here
|
|
8
|
+
|
|
9
|
+
This codebase is written and maintained by a single, highly opinionated author.
|
|
10
|
+
The default mode for an LLM here is **read-only**: understand the code, explain it,
|
|
11
|
+
answer questions, and locate things.
|
|
12
|
+
That is the job.
|
|
13
|
+
|
|
14
|
+
**Do not write or restructure code.**
|
|
15
|
+
Assume every design decision was made deliberately.
|
|
16
|
+
If you think something should change, say so and stop — do not implement it.
|
|
17
|
+
In particular, never:
|
|
18
|
+
|
|
19
|
+
- introduce new modules, abstractions, or layers of indirection;
|
|
20
|
+
- refactor, rename, or "clean up" working code;
|
|
21
|
+
- add compatibility shims, fallbacks, or defensive scaffolding;
|
|
22
|
+
- broaden an API or generalize past what was asked;
|
|
23
|
+
- follow a tangent into a rabbit hole.
|
|
24
|
+
When the task grows past a line or two of obvious change,
|
|
25
|
+
stop and report instead of chasing it.
|
|
26
|
+
|
|
27
|
+
The narrow exception: a **surgical, already-decided edit** the author has spelled out
|
|
28
|
+
(a typo, a one-line fix, a mechanical sweep).
|
|
29
|
+
Do exactly that and nothing more.
|
|
30
|
+
When unsure whether a change qualifies, treat it as out of scope and ask.
|
|
31
|
+
|
|
32
|
+
## Development Environment
|
|
33
|
+
|
|
34
|
+
The development shell already has the project virtual environment activated,
|
|
35
|
+
so `pytest`, `zuban`, `basedpyright`, `ruff`, `sphinx-build`,
|
|
36
|
+
etc. are on `PATH` directly.
|
|
37
|
+
**Do not** prefix commands with `uv run`, `pixi run`, `poetry run`, or similar.
|
|
38
|
+
Just invoke the tool.
|
|
39
|
+
If a tool is missing, stop and tell the user rather than trying to bootstrap
|
|
40
|
+
or reinstall the environment.
|
|
@@ -1,5 +1,125 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.2.0 — 2026-08-19
|
|
4
|
+
|
|
5
|
+
This is a major release as it cleans up a lot of bad code,
|
|
6
|
+
attempts to make the design choices more consistent,
|
|
7
|
+
and increase the surface area of properly typed code.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add finite-word composition directly to `SymbolicAutomaton`: `&`, `|`, `^`,
|
|
12
|
+
and `~` implement intersection, union, symmetric difference, and complement.
|
|
13
|
+
The variadic `compose_automata`, `is_language_equivalent`,
|
|
14
|
+
and `forward_bisim_reduction` helpers cover composition, equivalence checking,
|
|
15
|
+
and language-preserving quotienting without leaving the symbolic representation.
|
|
16
|
+
- Add a typed `BDDManager`/`Function` API and symbolic utilities for replacing a
|
|
17
|
+
manager, reindexing or quotienting states, materializing sinks, traversing reachable
|
|
18
|
+
states, and constructing universal acceptors and rejectors.
|
|
19
|
+
- Support arbitrary HOA v1 acceptance expressions through `GenericCondition`,
|
|
20
|
+
in addition to the concrete finite, Büchi, co-Büchi, generalized Büchi/co-Büchi,
|
|
21
|
+
Rabin, and Streett conditions.
|
|
22
|
+
Omega acceptance remains structural only:
|
|
23
|
+
run evaluation and transforms still implement finite-word semantics.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- **The primary automaton API is now `SymbolicAutomaton`.**
|
|
28
|
+
The intermediate `morphata.automaton.Automaton` representation has been removed.
|
|
29
|
+
Logic conversion, hand construction, transforms, composition, HOA conversion,
|
|
30
|
+
and operators now work directly with the BDD-backed type.
|
|
31
|
+
Migrate logic calls to `formula_to_automaton(...)`
|
|
32
|
+
or `SymbolicAutomaton.from_specification(...)`,
|
|
33
|
+
and use the instance methods `remove_alternation()`, `determinize()`,
|
|
34
|
+
and `to_min_dfa()` instead of the old transform functions.
|
|
35
|
+
- `AutomatonBuilder` now accepts integer state identifiers
|
|
36
|
+
and `build()` returns a `SymbolicAutomaton`; pass a `labeling_fn`
|
|
37
|
+
(and optionally a shared `BDDManager`).
|
|
38
|
+
Set-valued successors are disjunctions;
|
|
39
|
+
use a Boolean state expression for an alternating conjunction.
|
|
40
|
+
The old `variant`/`DeltaKind` construction API is gone.
|
|
41
|
+
- Alphabets now separate symbol labeling from guard weighting.
|
|
42
|
+
`BooleanAlphabet.labeling` returns an `AP -> bool` mapping, while operator weight
|
|
43
|
+
functions receive guards in sum-of-products form. `Alphabet`, `WeightedAlphabet`,
|
|
44
|
+
and `weighted_alphabet` are replaced by `BooleanAlphabet`, `SemiringAlphabet`,
|
|
45
|
+
`powerset_alphabet`, and `finite_alphabet`.
|
|
46
|
+
- `MatrixOperator` and `PolynomialOperator` are constructed with
|
|
47
|
+
`from_symbolic_automaton` or `from_specification`.
|
|
48
|
+
Pass `weight_fn` directly rather than an alphabet;
|
|
49
|
+
matrix construction also requires `backend`.
|
|
50
|
+
Their `accepts()` methods return a scalar `AlgebraicArray`,
|
|
51
|
+
and transition generation is exposed as `op.delta(symbol)`.
|
|
52
|
+
- HOA conversion now goes through `ParsedAutomaton`:
|
|
53
|
+
use `SymbolicAutomaton.from_hoaf(parsed, alphabet=...)` and `str(aut.to_hoaf())`.
|
|
54
|
+
State IDs need not be dense, and states without outgoing edges survive round trips.
|
|
55
|
+
|
|
56
|
+
### Fixed
|
|
57
|
+
|
|
58
|
+
- Correct symbolic derivatives for negated variables and SERE nodes.
|
|
59
|
+
- Fix breadth-first traversal ordering, symbolic language equivalence, and transition
|
|
60
|
+
partitioning when multiple guards have the same residual.
|
|
61
|
+
- Correct `step()` labeling and the structural checks for deterministic and
|
|
62
|
+
forward-progressing automata.
|
|
63
|
+
- Make builders, HOA conversion, and both operators handle sparse external state IDs
|
|
64
|
+
consistently by using dense indices only internally.
|
|
65
|
+
|
|
66
|
+
### Removed
|
|
67
|
+
|
|
68
|
+
- Remove the old `morphata.automaton` IR, STREL translator,
|
|
69
|
+
BDD-JSON persistence/cache API, and the former `symbolic.transforms`,
|
|
70
|
+
`symbolic.equivalence`, and `symbolic.compose` modules.
|
|
71
|
+
Their surviving operations now live on `SymbolicAutomaton` or in `morphata.symbolic`;
|
|
72
|
+
there is no replacement for STREL or BDD-JSON persistence in this release.
|
|
73
|
+
- Remove the specialized composition-map/transition-enumeration APIs and structural
|
|
74
|
+
`prune`; use general symbolic composition and `forward_bisim_reduction` where those
|
|
75
|
+
semantics fit.
|
|
76
|
+
|
|
77
|
+
## 2.1.0 — 2026-06-11
|
|
78
|
+
|
|
79
|
+
### Added
|
|
80
|
+
|
|
81
|
+
- Add `morphata.symbolic.prune` that does a cheap,
|
|
82
|
+
language-preserving structural pruning of an AFA.
|
|
83
|
+
The idea here is to try and reduce the number of states in the AFA
|
|
84
|
+
(no guarantees)
|
|
85
|
+
by performing a forward reachability pass, dead-state pruning,
|
|
86
|
+
and a parameterized number of passes for one-step acceptance-partition deduplication.
|
|
87
|
+
|
|
88
|
+
### Changed
|
|
89
|
+
|
|
90
|
+
- `MatrixOperator` and `PolynomialOperator` are generic now —
|
|
91
|
+
`MatrixOperator[Symbol, AP]` and `PolynomialOperator[Symbol, AP]`,
|
|
92
|
+
just like `SymbolicAutomaton`.
|
|
93
|
+
When I first banged these out I left them un-parameterized
|
|
94
|
+
(read: `Any` smeared everywhere),
|
|
95
|
+
so now the symbol and AP types actually flow through
|
|
96
|
+
and `MatrixOperator[frozenset[str], str]` means something.
|
|
97
|
+
Nothing changes at runtime;
|
|
98
|
+
the one thing you might notice is your type-checker nudging you to fill in the params
|
|
99
|
+
if you were annotating a bare `MatrixOperator` or `PolynomialOperator`.
|
|
100
|
+
- The BDD-JSON sidecar cache jumped to schema **v2**.
|
|
101
|
+
Acceptance conditions now (de)serialize through `cattrs` instead of the hand-rolled
|
|
102
|
+
`meta.get(...)` dance, and Rabin/Streett pairs are written as objects
|
|
103
|
+
(`{"rejecting": ..., "accepting": ...}`) rather than nested lists.
|
|
104
|
+
Heads up: old `v1` `.bdd.json` caches will politely refuse to load
|
|
105
|
+
(clean error, not a silent miscompile) --- just regenerate them and you're good.
|
|
106
|
+
Remember, this is a *cache*, not a portable format,
|
|
107
|
+
so this shouldn't bite anyone hard.
|
|
108
|
+
- STREL conversion shed ~120 lines.
|
|
109
|
+
All the timed-interval unrolling
|
|
110
|
+
(`G[a,b]`, `F[a,b]`, `U[t1,t2]`, `X[n]`)
|
|
111
|
+
and the spatial `Somewhere`/`Everywhere` desugaring used to be hand-rolled in
|
|
112
|
+
`strel.py`, but `logic-asts` already does all of it in `.expand()` — so I ripped them
|
|
113
|
+
out and just lean on the upstream rules.
|
|
114
|
+
This needs the newer `logic-asts`
|
|
115
|
+
(the one with the spatial `expand()` rules), so that dep gets bumped along with it.
|
|
116
|
+
|
|
117
|
+
### Miscellaneous
|
|
118
|
+
|
|
119
|
+
- Housekeeping, but worth saying:
|
|
120
|
+
the whole package now type-checks clean under *both* `zuban` and `basedpyright`
|
|
121
|
+
(0 errors, 0 warnings), so contributing should be a bit less whack-a-mole.
|
|
122
|
+
|
|
3
123
|
## 2.0.10 — 2026-06-08
|
|
4
124
|
|
|
5
125
|
### Fixed
|
|
@@ -10,8 +130,8 @@
|
|
|
10
130
|
|
|
11
131
|
### Performance
|
|
12
132
|
|
|
13
|
-
- The HOA grammar is now LALR compatible!
|
|
14
|
-
even for pretty large automata.
|
|
133
|
+
- The HOA grammar is now LALR compatible!
|
|
134
|
+
This means we get a huge performance boost even for pretty large automata.
|
|
15
135
|
- Similar thing was done in `logic-asts` and thus, the version will be bumped.
|
|
16
136
|
|
|
17
137
|
## 2.0.9 — 2026-06-04
|
|
@@ -87,7 +207,7 @@
|
|
|
87
207
|
### Fixed
|
|
88
208
|
|
|
89
209
|
- A major regression where the streaming `to_hoa` stuff changed the label enumeration
|
|
90
|
-
semantics to be
|
|
210
|
+
semantics to be *minterms* instead of *cubes*.
|
|
91
211
|
This is now fixed.
|
|
92
212
|
|
|
93
213
|
### Added
|
|
@@ -308,8 +428,7 @@ which will be summarized below.
|
|
|
308
428
|
The reverse direction is deliberately omitted —
|
|
309
429
|
recovering Boolean semantics from arbitrary `V` needs an ordering and a cut (cf.
|
|
310
430
|
STL), and pretending otherwise would silently produce garbage.
|
|
311
|
-
- **Ergonomic construction.**
|
|
312
|
-
`AutomatonBuilder` replaces the old NFA builder.
|
|
431
|
+
- **Ergonomic construction.** `AutomatonBuilder` replaces the old NFA builder.
|
|
313
432
|
Add states, add transitions with a guard and a successor
|
|
314
433
|
(single state, set of states, or a raw `BoolExpr` for full alternation),
|
|
315
434
|
and `build()` cleans up by merging rows that share a successor.
|
|
@@ -337,11 +456,9 @@ which will be summarized below.
|
|
|
337
456
|
The BDD cofactor path works for any `BooleanAlphabet`,
|
|
338
457
|
so you can feed a `SymbolicAutomaton` over integers, graph nodes, whatever —
|
|
339
458
|
as long as you can write a labeling.
|
|
340
|
-
- **The AFA-to-min-DFA pipeline actually exists now.**
|
|
341
|
-
`
|
|
342
|
-
|
|
343
|
-
`minimize` (Hopcroft) — all share one BDD manager
|
|
344
|
-
and successively tighten the invariants on successor BDDs.
|
|
459
|
+
- **The AFA-to-min-DFA pipeline actually exists now.** `nfa_from_afa` (dealternation),
|
|
460
|
+
`determinize` (subset construction with a sink), `minimize` (Hopcroft) —
|
|
461
|
+
all share one BDD manager and successively tighten the invariants on successor BDDs.
|
|
345
462
|
`SymbolicAutomaton.to_min_dfa` chains the three.
|
|
346
463
|
Finite-word only for now; omega-regular determinisation is a different beast.
|
|
347
464
|
- **DFA equivalence checks.**
|
|
@@ -352,19 +469,17 @@ which will be summarized below.
|
|
|
352
469
|
|
|
353
470
|
### Operators
|
|
354
471
|
|
|
355
|
-
- **One per-step shape.**
|
|
356
|
-
`SymbolicAutomaton`, `MatrixOperator`,
|
|
472
|
+
- **One per-step shape.** `SymbolicAutomaton`, `MatrixOperator`,
|
|
357
473
|
and `PolynomialOperator` all expose the same `step(current, symbol)` / `run(word)` /
|
|
358
474
|
`accepts(word)` shape.
|
|
359
475
|
Each binds its alphabet at construction
|
|
360
476
|
(matching how the semiring / algebra were already bound),
|
|
361
477
|
so the per-call API is monomorphic and `V` is pinned end-to-end.
|
|
362
478
|
Wanted symmetry between the layers; got it.
|
|
363
|
-
- **`PolynomialOperator` evaluates lazily.**
|
|
364
|
-
`
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
and you really don't want to materialise `2^|AP|` polynomials up front.
|
|
479
|
+
- **`PolynomialOperator` evaluates lazily.** `step` evaluates guards against
|
|
480
|
+
`alphabet.weight` on the fly, with no per-symbol precomputation — important because
|
|
481
|
+
the natural LTL alphabet is `Σ = 2^AP`, and you really don't want to materialise
|
|
482
|
+
`2^|AP|` polynomials up front.
|
|
368
483
|
The AFA's row structure stays static
|
|
369
484
|
(good for JAX tracing), and the alphabet decides whether to memoise.
|
|
370
485
|
- **Polynomial performance.**
|
|
@@ -374,9 +489,8 @@ which will be summarized below.
|
|
|
374
489
|
|
|
375
490
|
### Tooling and Tests
|
|
376
491
|
|
|
377
|
-
- **Hand-written changelogs.**
|
|
378
|
-
|
|
379
|
-
as well write them by hand.
|
|
492
|
+
- **Hand-written changelogs.** `git cliff` was producing entries
|
|
493
|
+
that needed enough editing that I might as well write them by hand.
|
|
380
494
|
`ci/make-release` no longer touches `CHANGELOG.md` or tag messages.
|
|
381
495
|
Run `git cliff` separately if you want a draft to crib from.
|
|
382
496
|
- **Tests.**
|
|
@@ -39,20 +39,21 @@ just fmt
|
|
|
39
39
|
# OR
|
|
40
40
|
ruff format
|
|
41
41
|
ruff check --output-format concise --fix --exit-non-zero-on-fix
|
|
42
|
-
|
|
43
|
-
# Format + type check
|
|
44
|
-
just lint
|
|
45
42
|
```
|
|
46
43
|
|
|
47
44
|
**Type Checking** :
|
|
48
45
|
```bash
|
|
49
46
|
# Run all type checkers
|
|
50
47
|
just type-check
|
|
51
|
-
|
|
48
|
+
# OR
|
|
52
49
|
# Run specific type checkers
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
zuban check
|
|
51
|
+
basedpyright
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Formatting + Type Checking together**:
|
|
55
|
+
```bash
|
|
56
|
+
just lint
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
**Development Setup** :
|
|
@@ -60,7 +61,7 @@ pyrefly check --output-format min-text
|
|
|
60
61
|
# Set up dev environment (sync dependencies)
|
|
61
62
|
just dev
|
|
62
63
|
# OR
|
|
63
|
-
|
|
64
|
+
pixi install
|
|
64
65
|
|
|
65
66
|
# For CUDA support (set CUDA_VERSION=12 or 13)
|
|
66
67
|
CUDA_VERSION=12 just dev
|
|
@@ -74,7 +75,7 @@ One can also copy the included `.envrc.recommended` file to `.envrc` and use it
|
|
|
74
75
|
|
|
75
76
|
### Type Annotations
|
|
76
77
|
|
|
77
|
-
- All code must pass `
|
|
78
|
+
- All code must pass `zuban` and `basedpyright`. Use explicit type annotations.
|
|
78
79
|
- Use Python 3.12+ syntax: `type` aliases, `|` for unions, generic classes and functions
|
|
79
80
|
with `[T]`
|
|
80
81
|
- Always specify return types, including `-> None`
|
|
@@ -89,42 +90,3 @@ One can also copy the included `.envrc.recommended` file to `.envrc` and use it
|
|
|
89
90
|
- Format: NumPy-style docstrings with sections: Parameters, Returns,
|
|
90
91
|
Raises, Notes, Examples.
|
|
91
92
|
- Inline comments should say _why_ something is done, not _what_.
|
|
92
|
-
|
|
93
|
-
## Source Layout
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
morphata/
|
|
97
|
-
├── src/morphata/
|
|
98
|
-
│ ├── automaton.py # Automaton IR + Outgoing/Step deltas
|
|
99
|
-
│ ├── alphabet.py # Input alphabet + characteristic function
|
|
100
|
-
│ ├── builder.py # AutomatonBuilder (mutable IR builder)
|
|
101
|
-
│ ├── acceptance.py # Finite + omega-regular acceptance
|
|
102
|
-
│ ├── weights.py # Guard-based weight predicates
|
|
103
|
-
│ ├── logic/
|
|
104
|
-
│ │ ├── ltl.py # LTL/LTLf -> AFA
|
|
105
|
-
│ │ └── strel.py # STREL automaton (Step delta)
|
|
106
|
-
│ ├── hoa/ # Extended HOA v1 parser
|
|
107
|
-
│ │ ├── parser.py
|
|
108
|
-
│ │ ├── exporter.py # placeholder; not yet implemented
|
|
109
|
-
│ │ └── acc_expr.py
|
|
110
|
-
│ ├── operators/ # Semiring-valued morphisms
|
|
111
|
-
│ │ ├── matrix.py # MatrixOperator (weighted NFAs)
|
|
112
|
-
│ │ ├── polynomial.py # PolynomialOperator (AFAs)
|
|
113
|
-
│ │ └── _backend.py # backend resolution + JAX pytree aux
|
|
114
|
-
│ └── symbolic/ # BDD-backed structural layer
|
|
115
|
-
│ ├── automaton.py # SymbolicAutomaton
|
|
116
|
-
│ ├── bdd.py # BoolExpr <-> dd.Function bridge
|
|
117
|
-
│ ├── transforms.py # determinize, minimize, nfa_from_afa
|
|
118
|
-
│ └── equivalence.py # language_equivalent, isomorphic, canonical_form
|
|
119
|
-
│
|
|
120
|
-
└── tests/ # Mirrors the package layout
|
|
121
|
-
├── test_alphabet.py
|
|
122
|
-
├── test_automaton.py
|
|
123
|
-
├── test_builder.py
|
|
124
|
-
├── test_from_parsed.py
|
|
125
|
-
├── test_weights.py
|
|
126
|
-
├── hoa/
|
|
127
|
-
├── logic/
|
|
128
|
-
├── operators/
|
|
129
|
-
└── symbolic/
|
|
130
|
-
```
|
morphata-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: morphata
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: Representation theory for automata, made practical.
|
|
5
|
+
Project-URL: Documentation, https://docs.anandb.dev/morphata
|
|
6
|
+
Project-URL: Repository, https://git.anandb.dev/morphata.git
|
|
7
|
+
Project-URL: Changelog, https://docs.anandb.dev/morphata/changelog.html
|
|
8
|
+
Author-email: Anand Balakrishnan <anandbala1597@gmail.com>
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Requires-Dist: algebraic-arrays>=1.3.0
|
|
15
|
+
Requires-Dist: attrs>=25.4.0
|
|
16
|
+
Requires-Dist: cattrs>=26.1.0
|
|
17
|
+
Requires-Dist: dd>=0.6.0
|
|
18
|
+
Requires-Dist: jaxtyping>=0.3
|
|
19
|
+
Requires-Dist: lark>=1.3.1
|
|
20
|
+
Requires-Dist: logic-asts>=1.8
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: typing-extensions>=4.14
|
|
23
|
+
Provides-Extra: dot
|
|
24
|
+
Requires-Dist: pydot>=4.0.1; extra == 'dot'
|
|
25
|
+
Provides-Extra: jax
|
|
26
|
+
Requires-Dist: jax>=0.8; extra == 'jax'
|
|
27
|
+
Provides-Extra: torch
|
|
28
|
+
Requires-Dist: torch>=2.0; extra == 'torch'
|
|
29
|
+
Description-Content-Type: text/x-rst
|
|
30
|
+
|
|
31
|
+
Morphata
|
|
32
|
+
========
|
|
33
|
+
|
|
34
|
+
**morphata** does representation theory for automata.
|
|
35
|
+
An automaton -- its states, transitions,
|
|
36
|
+
and acceptance condition -- is a *structural* object.
|
|
37
|
+
``SymbolicAutomaton`` is the BDD-backed structural representation.
|
|
38
|
+
``MatrixOperator`` and ``PolynomialOperator`` interpret that structure over
|
|
39
|
+
semiring and bounded-distributive-lattice domains.
|
|
40
|
+
|
|
41
|
+
It builds on `algebraic <https://docs.anandb.dev/algebraic>`_ for
|
|
42
|
+
backend-agnostic semiring algebra (NumPy, JAX, PyTorch).
|
|
43
|
+
|
|
44
|
+
To install the latest release of ``morphata``, install from
|
|
45
|
+
`PyPI <https://pypi.org/project/morphata/>`_:
|
|
46
|
+
|
|
47
|
+
.. code-block:: bash
|
|
48
|
+
|
|
49
|
+
pip install morphata
|
|
50
|
+
|
|
51
|
+
Or from the latest Git head:
|
|
52
|
+
|
|
53
|
+
.. code-block:: bash
|
|
54
|
+
|
|
55
|
+
pip install 'morphata @ git+https://git.anandb.dev/morphata.git@main'
|
|
56
|
+
|
|
57
|
+
For more, see the `documentation <https://docs.anandb.dev/morphata>`_.
|
|
58
|
+
|
|
59
|
+
.. code-block:: python
|
|
60
|
+
|
|
61
|
+
>>> import logic_asts as logic
|
|
62
|
+
>>> import logic_asts.ltl as ltl
|
|
63
|
+
|
|
64
|
+
>>> from morphata.alphabet import powerset_alphabet
|
|
65
|
+
>>> from morphata.logic import formula_to_automaton
|
|
66
|
+
|
|
67
|
+
>>> a = logic.Variable("a")
|
|
68
|
+
>>> aut = formula_to_automaton(
|
|
69
|
+
... ltl.Eventually(a), alphabet=powerset_alphabet({"a"}), finite=True
|
|
70
|
+
... )
|
|
71
|
+
>>> aut.accepts([set(), {"a"}])
|
|
72
|
+
True
|
|
73
|
+
|
|
74
|
+
Omega-regular conditions are supported structurally, but infinite-run acceptance
|
|
75
|
+
evaluation is not implemented. See the full documentation for details.
|
|
76
|
+
|
|
77
|
+
Citation
|
|
78
|
+
--------
|
|
79
|
+
|
|
80
|
+
To cite the use of this package or the papers
|
|
81
|
+
that are derived from it you can use the below BibTeX entries.
|
|
82
|
+
|
|
83
|
+
- For differentiable weighted automata in general:
|
|
84
|
+
|
|
85
|
+
.. code-block:: bibtex
|
|
86
|
+
|
|
87
|
+
@inproceedings{balakrishnan2024differentiable,
|
|
88
|
+
title = {Differentiable {{Weighted Automata}}},
|
|
89
|
+
booktitle = {{{ICML}} 2024 {{Workshop}} on {{Differentiable Almost Everything}}: {{Differentiable Relaxations}}, {{Algorithms}}, {{Operators}}, and {{Simulators}}},
|
|
90
|
+
author = {Balakrishnan, Anand and Deshmukh, Jyotirmoy V.},
|
|
91
|
+
year = 2024,
|
|
92
|
+
month = jun,
|
|
93
|
+
url = {https://openreview.net/forum?id=k2hIQYqHTh},
|
|
94
|
+
copyright = {All rights reserved},
|
|
95
|
+
langid = {english}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
- For weighted automata in motion planning:
|
|
99
|
+
|
|
100
|
+
.. code-block:: bibtex
|
|
101
|
+
|
|
102
|
+
@inproceedings{balakrishnan2024motion,
|
|
103
|
+
title = {Motion {{Planning}} for {{Automata-based Objectives}} Using {{Efficient Gradient-based Methods}}},
|
|
104
|
+
booktitle = {2024 {{IEEE}}/{{RSJ International Conference}} on {{Intelligent Robots}} and {{Systems}} ({{IROS}})},
|
|
105
|
+
author = {Balakrishnan, Anand and Atasever, Merve and Deshmukh, Jyotirmoy V.},
|
|
106
|
+
year = 2024,
|
|
107
|
+
month = oct,
|
|
108
|
+
pages = {13734--13740},
|
|
109
|
+
issn = {2153-0866},
|
|
110
|
+
doi = {10.1109/IROS58592.2024.10802177}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
- For alternating weighted automata in multi-agent systems:
|
|
114
|
+
|
|
115
|
+
.. code-block:: bibtex
|
|
116
|
+
|
|
117
|
+
@inproceedings{balakrishnan2025monitoring,
|
|
118
|
+
title = {Monitoring {{Spatially Distributed Cyber-Physical Systems}} with {{Alternating Finite Automata}}},
|
|
119
|
+
booktitle = {Proceedings of the 28th {{ACM International Conference}} on {{Hybrid Systems}}: {{Computation}} and {{Control}}},
|
|
120
|
+
author = {Balakrishnan, Anand and Paul, Sheryl and Silvetti, Simone and Nenzi, Laura and Deshmukh, Jyotirmoy V.},
|
|
121
|
+
year = 2025,
|
|
122
|
+
month = may,
|
|
123
|
+
pages = {1--11},
|
|
124
|
+
publisher = {ACM},
|
|
125
|
+
address = {Irvine CA USA},
|
|
126
|
+
doi = {10.1145/3716863.3718033},
|
|
127
|
+
isbn = {979-8-4007-1504-4},
|
|
128
|
+
langid = {english}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
License
|
|
132
|
+
-------
|
|
133
|
+
|
|
134
|
+
See the ``LICENSE`` file for details.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Morphata
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
**morphata** does representation theory for automata.
|
|
5
|
+
An automaton -- its states, transitions,
|
|
6
|
+
and acceptance condition -- is a *structural* object.
|
|
7
|
+
``SymbolicAutomaton`` is the BDD-backed structural representation.
|
|
8
|
+
``MatrixOperator`` and ``PolynomialOperator`` interpret that structure over
|
|
9
|
+
semiring and bounded-distributive-lattice domains.
|
|
10
|
+
|
|
11
|
+
It builds on `algebraic <https://docs.anandb.dev/algebraic>`_ for
|
|
12
|
+
backend-agnostic semiring algebra (NumPy, JAX, PyTorch).
|
|
13
|
+
|
|
14
|
+
To install the latest release of ``morphata``, install from
|
|
15
|
+
`PyPI <https://pypi.org/project/morphata/>`_:
|
|
16
|
+
|
|
17
|
+
.. code-block:: bash
|
|
18
|
+
|
|
19
|
+
pip install morphata
|
|
20
|
+
|
|
21
|
+
Or from the latest Git head:
|
|
22
|
+
|
|
23
|
+
.. code-block:: bash
|
|
24
|
+
|
|
25
|
+
pip install 'morphata @ git+https://git.anandb.dev/morphata.git@main'
|
|
26
|
+
|
|
27
|
+
For more, see the `documentation <https://docs.anandb.dev/morphata>`_.
|
|
28
|
+
|
|
29
|
+
.. code-block:: python
|
|
30
|
+
|
|
31
|
+
>>> import logic_asts as logic
|
|
32
|
+
>>> import logic_asts.ltl as ltl
|
|
33
|
+
|
|
34
|
+
>>> from morphata.alphabet import powerset_alphabet
|
|
35
|
+
>>> from morphata.logic import formula_to_automaton
|
|
36
|
+
|
|
37
|
+
>>> a = logic.Variable("a")
|
|
38
|
+
>>> aut = formula_to_automaton(
|
|
39
|
+
... ltl.Eventually(a), alphabet=powerset_alphabet({"a"}), finite=True
|
|
40
|
+
... )
|
|
41
|
+
>>> aut.accepts([set(), {"a"}])
|
|
42
|
+
True
|
|
43
|
+
|
|
44
|
+
Omega-regular conditions are supported structurally, but infinite-run acceptance
|
|
45
|
+
evaluation is not implemented. See the full documentation for details.
|
|
46
|
+
|
|
47
|
+
Citation
|
|
48
|
+
--------
|
|
49
|
+
|
|
50
|
+
To cite the use of this package or the papers
|
|
51
|
+
that are derived from it you can use the below BibTeX entries.
|
|
52
|
+
|
|
53
|
+
- For differentiable weighted automata in general:
|
|
54
|
+
|
|
55
|
+
.. code-block:: bibtex
|
|
56
|
+
|
|
57
|
+
@inproceedings{balakrishnan2024differentiable,
|
|
58
|
+
title = {Differentiable {{Weighted Automata}}},
|
|
59
|
+
booktitle = {{{ICML}} 2024 {{Workshop}} on {{Differentiable Almost Everything}}: {{Differentiable Relaxations}}, {{Algorithms}}, {{Operators}}, and {{Simulators}}},
|
|
60
|
+
author = {Balakrishnan, Anand and Deshmukh, Jyotirmoy V.},
|
|
61
|
+
year = 2024,
|
|
62
|
+
month = jun,
|
|
63
|
+
url = {https://openreview.net/forum?id=k2hIQYqHTh},
|
|
64
|
+
copyright = {All rights reserved},
|
|
65
|
+
langid = {english}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
- For weighted automata in motion planning:
|
|
69
|
+
|
|
70
|
+
.. code-block:: bibtex
|
|
71
|
+
|
|
72
|
+
@inproceedings{balakrishnan2024motion,
|
|
73
|
+
title = {Motion {{Planning}} for {{Automata-based Objectives}} Using {{Efficient Gradient-based Methods}}},
|
|
74
|
+
booktitle = {2024 {{IEEE}}/{{RSJ International Conference}} on {{Intelligent Robots}} and {{Systems}} ({{IROS}})},
|
|
75
|
+
author = {Balakrishnan, Anand and Atasever, Merve and Deshmukh, Jyotirmoy V.},
|
|
76
|
+
year = 2024,
|
|
77
|
+
month = oct,
|
|
78
|
+
pages = {13734--13740},
|
|
79
|
+
issn = {2153-0866},
|
|
80
|
+
doi = {10.1109/IROS58592.2024.10802177}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
- For alternating weighted automata in multi-agent systems:
|
|
84
|
+
|
|
85
|
+
.. code-block:: bibtex
|
|
86
|
+
|
|
87
|
+
@inproceedings{balakrishnan2025monitoring,
|
|
88
|
+
title = {Monitoring {{Spatially Distributed Cyber-Physical Systems}} with {{Alternating Finite Automata}}},
|
|
89
|
+
booktitle = {Proceedings of the 28th {{ACM International Conference}} on {{Hybrid Systems}}: {{Computation}} and {{Control}}},
|
|
90
|
+
author = {Balakrishnan, Anand and Paul, Sheryl and Silvetti, Simone and Nenzi, Laura and Deshmukh, Jyotirmoy V.},
|
|
91
|
+
year = 2025,
|
|
92
|
+
month = may,
|
|
93
|
+
pages = {1--11},
|
|
94
|
+
publisher = {ACM},
|
|
95
|
+
address = {Irvine CA USA},
|
|
96
|
+
doi = {10.1145/3716863.3718033},
|
|
97
|
+
isbn = {979-8-4007-1504-4},
|
|
98
|
+
langid = {english}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
License
|
|
102
|
+
-------
|
|
103
|
+
|
|
104
|
+
See the ``LICENSE`` file for details.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""pytest fixtures for the morphata bench suite.
|
|
2
|
+
|
|
3
|
+
The bench/ tree is opt-in: invoke with `pytest bench/` (or
|
|
4
|
+
`pytest bench/test_sere_nlm_perf.py`). It is not collected by the
|
|
5
|
+
default `pytest` invocation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import gc
|
|
11
|
+
from collections.abc import Iterator
|
|
12
|
+
|
|
13
|
+
import pytest
|
|
14
|
+
|
|
15
|
+
from morphata.symbolic.bdd import BDDManager
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture
|
|
19
|
+
def bench_mgr() -> Iterator[BDDManager[str, int]]:
|
|
20
|
+
"""Shared BDD manager scoped to one bench test (= many benchmark rounds).
|
|
21
|
+
|
|
22
|
+
Bench tests pass this manager to ``sere_to_automaton(..., manager=mgr)``
|
|
23
|
+
so the per-call ``BDDManager()`` allocation is skipped. That path leaks
|
|
24
|
+
~12 MB of CUDD-internal state per call, which compounds across the
|
|
25
|
+
~100-1000 rounds pytest-benchmark runs per test and exhausts host
|
|
26
|
+
RAM. Sharing the manager keeps RSS flat.
|
|
27
|
+
"""
|
|
28
|
+
manager = BDDManager[str, int]()
|
|
29
|
+
try:
|
|
30
|
+
yield manager
|
|
31
|
+
finally:
|
|
32
|
+
_ = gc.collect()
|