morphata 2.0.0__tar.gz → 2.0.1__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.0.0 → morphata-2.0.1}/.claude/settings.local.json +5 -1
- {morphata-2.0.0 → morphata-2.0.1}/.envrc +8 -4
- morphata-2.0.1/.gitattributes +5 -0
- {morphata-2.0.0 → morphata-2.0.1}/.gitignore +3 -0
- {morphata-2.0.0 → morphata-2.0.1}/AGENTS.md +39 -0
- {morphata-2.0.0 → morphata-2.0.1}/CHANGELOG.md +44 -1
- {morphata-2.0.0 → morphata-2.0.1}/CONTRIBUTING.md +16 -10
- {morphata-2.0.0 → morphata-2.0.1}/PKG-INFO +2 -2
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/modules.rst +2 -0
- morphata-2.0.1/docs/api/morphata.logic.psl.rst +15 -0
- morphata-2.0.1/docs/api/morphata.logic.sere.rst +9 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/conf.py +1 -1
- {morphata-2.0.0 → morphata-2.0.1}/docs/index.rst +9 -1
- morphata-2.0.1/justfile +70 -0
- morphata-2.0.1/pixi.lock +5923 -0
- morphata-2.0.1/pixi.toml +114 -0
- {morphata-2.0.0 → morphata-2.0.1}/pyproject.toml +3 -2
- morphata-2.0.1/src/morphata/logic/_common.py +72 -0
- morphata-2.0.1/src/morphata/logic/ltl.py +499 -0
- morphata-2.0.1/src/morphata/logic/psl.py +495 -0
- morphata-2.0.1/src/morphata/logic/sere.py +403 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/operators/matrix.py +3 -1
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/operators/polynomial.py +3 -1
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/symbolic/automaton.py +1 -1
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/symbolic/bdd.py +224 -14
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/symbolic/transforms.py +77 -68
- {morphata-2.0.0/tests/symbolic → morphata-2.0.1/tests}/conftest.py +2 -2
- {morphata-2.0.0 → morphata-2.0.1}/tests/logic/test_ltl.py +122 -69
- morphata-2.0.1/tests/logic/test_psl.py +230 -0
- morphata-2.0.1/tests/logic/test_sere.py +236 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/operators/test_matrix_from_ltl.py +7 -6
- {morphata-2.0.0 → morphata-2.0.1}/tests/operators/test_polynomial_from_ir.py +5 -4
- morphata-2.0.1/tests/symbolic/test_bdd_helpers.py +277 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_from_hoaf.py +2 -2
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_ltlf2dfa_equivalence.py +1 -1
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_step.py +8 -7
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_symbolic_automaton.py +26 -1
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_symbolic_from_ir.py +7 -6
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_transforms.py +47 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_transforms_ir.py +5 -4
- {morphata-2.0.0 → morphata-2.0.1}/tests/symbolic/test_transforms_properties.py +45 -21
- {morphata-2.0.0 → morphata-2.0.1}/uv.lock +105 -81
- morphata-2.0.0/.gitattributes +0 -3
- morphata-2.0.0/docs/changelog.md +0 -4
- morphata-2.0.0/justfile +0 -54
- morphata-2.0.0/src/morphata/logic/ltl.py +0 -448
- morphata-2.0.0/tests/symbolic/test_bdd_helpers.py +0 -143
- {morphata-2.0.0 → morphata-2.0.1}/.basedpyright/baseline.json +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.dockerignore +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.editorconfig +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.envrc.recommended +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.fdignore +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.mailmap +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.python-version +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/.rstcheck.cfg +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/CLAUDE.md +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/LICENSE +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/README.md +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/ci/make-release +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/cliff.toml +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/_static/navigation.html +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.acceptance.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.alphabet.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.automaton.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.builder.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.hoa.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.logic.ltl.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.logic.strel.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.operators.matrix.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.operators.polynomial.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.operators.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/api/morphata.symbolic.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/acceptance.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/hoa.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/index.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/operators.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/spec.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/concepts/weights.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/quick-start.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/docs/symbolic-transforms.rst +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/mypy.ini +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/project.utf-8.add +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/project.utf-8.add.spl +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/pyrefly.toml +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/pyrightconfig.json +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/pytest.toml +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/ruff.toml +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/acceptance.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/alphabet.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/automaton.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/builder.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/__main__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/acc_expr.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/exporter.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/hoa.lark +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/hoa/parser.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/logic/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/logic/strel.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/operators/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/operators/_backend.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/py.typed +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/symbolic/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/src/morphata/symbolic/equivalence.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut1.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut11.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut2.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut3.2.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut3.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut4.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut5.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut6.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut7.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/aut8.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/finite_aut.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/gen_buchi_3.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/gen_cobuchi_2.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/rabin_2pair.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/streett_2pair.hoa +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/test_exporter_basic.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/test_exporter_roundtrip.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/hoa/test_parser.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/logic/__init__.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/logic/test_strel.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/operators/test_matrix_from_ir.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/test_alphabet.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/test_automaton.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/test_builder.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/tests/test_from_parsed.py +0 -0
- {morphata-2.0.0 → morphata-2.0.1}/ty.toml +0 -0
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
"Bash(just test *)",
|
|
12
12
|
"Bash(rg *)",
|
|
13
13
|
"Bash(uv run pytest *)",
|
|
14
|
-
"Bash(uv run mypy *)"
|
|
14
|
+
"Bash(uv run mypy *)",
|
|
15
|
+
"Bash(.venv/bin/python -m pytest *)",
|
|
16
|
+
"Skill(superpowers:writing-plans)",
|
|
17
|
+
"Skill(superpowers:subagent-driven-development)",
|
|
18
|
+
"Bash(grep -v \"AssertionError\\\\|Traceback\\\\|File \\\\|^\\\\s*$\")"
|
|
15
19
|
]
|
|
16
20
|
}
|
|
17
21
|
}
|
|
@@ -12,15 +12,19 @@ if [[ -z "${DEVJAIL:-}" ]] && nvidia_smi="$(type -p "nvidia-smi")" && [[ -n "$nv
|
|
|
12
12
|
if [[ -n "${cuda_major_version:-}" ]]; then
|
|
13
13
|
info "Detected CUDA version: $cuda_major_version"
|
|
14
14
|
export CUDA_VERSION="$cuda_major_version"
|
|
15
|
+
PIXI_ENV="cu$CUDA_VERSION"
|
|
15
16
|
fi
|
|
16
17
|
else
|
|
17
18
|
info "Did not detect nvidia-smi, using non-GPU environment"
|
|
19
|
+
PIXI_ENV="default"
|
|
18
20
|
fi
|
|
21
|
+
export PIXI_ENV
|
|
19
22
|
|
|
20
23
|
dotenv_if_exists
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
watch_file pixi.lock
|
|
26
|
+
eval "$(pixi shell-hook -e "$PIXI_ENV")"
|
|
27
|
+
|
|
28
|
+
if [[ -d "$CONDA_PREFIX" ]]; then
|
|
29
|
+
export VIRTUAL_ENV="$CONDA_PREFIX"
|
|
24
30
|
fi
|
|
25
|
-
source ./.venv/bin/activate
|
|
26
|
-
watch_file pyproject.toml
|
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
It packages structural automaton representations together with semiring-valued
|
|
5
5
|
*operators* that turn an automaton into a computable interpretation.
|
|
6
6
|
|
|
7
|
+
## Development Environment
|
|
8
|
+
|
|
9
|
+
The development shell already has the project virtual environment activated,
|
|
10
|
+
so `pytest`, `mypy`, `ruff`, `sphinx-build`, etc. are on `PATH` directly.
|
|
11
|
+
**Do not** prefix commands with `uv run`, `pixi run`, `poetry run`, or similar.
|
|
12
|
+
Just invoke the tool. If a tool is missing, stop and tell the user rather than
|
|
13
|
+
trying to bootstrap or reinstall the environment.
|
|
14
|
+
|
|
7
15
|
## Core Architecture
|
|
8
16
|
|
|
9
17
|
### IR layer (`morphata.automaton`, `morphata.alphabet`, `morphata.acceptance`)
|
|
@@ -85,6 +93,21 @@ delta - the transition consumes the labelled graph eagerly, so STREL
|
|
|
85
93
|
automata are not symbolically liftable. Operators: Reach, Escape,
|
|
86
94
|
Somewhere, Everywhere. Boolean-only.
|
|
87
95
|
|
|
96
|
+
**`morphata.logic.sere.sere_to_automaton(expr)`** : SERE -> alternating
|
|
97
|
+
finite automaton. Supports ``Concat``, ``Fusion``, ``Repeat`` (bounded
|
|
98
|
+
and unbounded), ``Inter``, ``Alt``, and Boolean leaves over AP.
|
|
99
|
+
Acceptance is always ``Finite``; the accepting-state set is exactly
|
|
100
|
+
the *nullable* states (those that match the empty word).
|
|
101
|
+
|
|
102
|
+
**`morphata.logic.psl.psl_to_automaton(phi, *, finite=False)`** : PSL ->
|
|
103
|
+
alternating automaton. Wraps pure-LTL subformulas in an internal
|
|
104
|
+
``_LTL`` tag and dispatches to the LTL expansion rule; closure
|
|
105
|
+
operators (``{r}!``, ``{r}``, ``!{r}``, ``{r}<>-> f``, ``{r}[]-> f``)
|
|
106
|
+
become their own tagged states with SERE-step expansion. Suffix
|
|
107
|
+
implications follow Spot's overlapping semantics: the last symbol of
|
|
108
|
+
``r`` and the first position of ``f`` coincide. ``finite=True`` ->
|
|
109
|
+
``Finite`` acceptance (PSLf); ``finite=False`` -> ``Buchi``.
|
|
110
|
+
|
|
88
111
|
Hand-written automata are built with ``AutomatonBuilder``; the package
|
|
89
112
|
has no separate ``constructions`` namespace.
|
|
90
113
|
|
|
@@ -211,6 +234,18 @@ is backend-agnostic via `backend=`.
|
|
|
211
234
|
sets of transitions. The HOA parser ingests ``{n}`` markers from
|
|
212
235
|
``State:`` declarations; per-edge ``{n}`` markers are ignored. Convert
|
|
213
236
|
transition-based HOA files to state-based form before loading them.
|
|
237
|
+
- ``psl_to_automaton`` requires the continuation of any
|
|
238
|
+
``SuffixImpliesExist`` / ``SuffixImpliesUniv`` to be a pure-LTL
|
|
239
|
+
formula in v1. Nested PSL closures inside a suffix-implication
|
|
240
|
+
continuation raise ``NotImplementedError``. Likewise, LTL temporal
|
|
241
|
+
operators wrapping a PSL closure at the top level
|
|
242
|
+
(e.g. ``Always(StrongClosure(r))``) are not yet decomposed; lift the
|
|
243
|
+
PSL fragment out of the LTL temporal operator before calling.
|
|
244
|
+
- The PSL Buchi acceptance classification is the natural per-tag rule
|
|
245
|
+
(strong-closure non-accepting, weak-closure accepting, etc.). It has
|
|
246
|
+
not been cross-checked against a published reference for every
|
|
247
|
+
combination of operators; consult ``docs/superpowers/specs/`` before
|
|
248
|
+
relying on omega-language semantics in production.
|
|
214
249
|
|
|
215
250
|
## Testing
|
|
216
251
|
|
|
@@ -334,6 +369,10 @@ matrix_product = algebraic.matmul(arr1, arr2)
|
|
|
334
369
|
- `src/morphata/builder.py` : ``AutomatonBuilder``.
|
|
335
370
|
- `src/morphata/acceptance.py` : expression-based acceptance conditions.
|
|
336
371
|
- `src/morphata/logic/ltl.py` : LTL/LTLf -> AFA conversion.
|
|
372
|
+
- `src/morphata/logic/sere.py` : SERE -> AFA conversion.
|
|
373
|
+
- `src/morphata/logic/psl.py` : PSL -> AFA conversion.
|
|
374
|
+
- `src/morphata/logic/_common.py` : shared BDD scratch-space setup used
|
|
375
|
+
by all three logic converters.
|
|
337
376
|
- `src/morphata/logic/strel.py` : STREL automaton (``Step`` delta).
|
|
338
377
|
- `src/morphata/hoa/` : HOA v1 parser, exporter, grammar.
|
|
339
378
|
- `src/morphata/operators/matrix.py` : ``MatrixOperator``.
|
|
@@ -1,6 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `morphata.logic.sere.sere_to_automaton(formula)` — converts a
|
|
8
|
+
SERE expression to an alternating finite automaton. Supports
|
|
9
|
+
`Concat`, `Fusion`, `Alt`, `Inter` (length-matching), `Repeat`
|
|
10
|
+
(bounded and unbounded), and Boolean leaves (`Literal`, `Variable`,
|
|
11
|
+
`Not`, `And`, `Or`).
|
|
12
|
+
- `morphata.logic.psl.psl_to_automaton(phi, *, finite=False)` —
|
|
13
|
+
converts a PSL expression to an alternating automaton, with
|
|
14
|
+
`Finite` acceptance for PSLf (`finite=True`) and `Büchi` acceptance
|
|
15
|
+
for full PSL (`finite=False`). Supports the strong / weak /
|
|
16
|
+
negated-strong closure operators and existential / universal
|
|
17
|
+
suffix implication. Suffix implications follow Spot's overlapping
|
|
18
|
+
semantics: the last symbol matched by the SERE prefix is shared
|
|
19
|
+
with the first position at which the continuation is evaluated.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- `morphata.logic.ltl` factored its per-call BDD scratch-space
|
|
24
|
+
construction into a shared helper
|
|
25
|
+
`morphata.logic._common.make_logic_context`, reused by the SERE
|
|
26
|
+
and PSL converters. Two LTL helpers (`_aut_symbolic_expansion`,
|
|
27
|
+
`_empty_trace_value`) were renamed to `ltl_symbolic_expansion` /
|
|
28
|
+
`ltl_empty_trace_value` so PSL can delegate to them for pure-LTL
|
|
29
|
+
subformulas.
|
|
30
|
+
|
|
31
|
+
### Known limitations
|
|
32
|
+
|
|
33
|
+
- `psl_to_automaton` does not yet decompose LTL temporal operators
|
|
34
|
+
that wrap PSL closures at the top level
|
|
35
|
+
(e.g. `Always(StrongClosure(r))`). Lift the PSL fragment out of
|
|
36
|
+
the surrounding LTL temporal operator before calling.
|
|
37
|
+
- The continuation of a `SuffixImpliesExist` / `SuffixImpliesUniv`
|
|
38
|
+
must be a pure-LTL formula; nested PSL closures inside a
|
|
39
|
+
continuation raise `NotImplementedError`.
|
|
40
|
+
- The Büchi acceptance classification for PSL has not been
|
|
41
|
+
cross-checked against a published reference for every operator
|
|
42
|
+
combination; finite-trace (PSLf) acceptance is exercised end-to-end
|
|
43
|
+
via `SymbolicAutomaton.accepts` and is high-confidence, but Büchi
|
|
44
|
+
is currently only smoke-tested for construction.
|
|
45
|
+
|
|
46
|
+
## 2.0.0 — 2026-05-23
|
|
4
47
|
|
|
5
48
|
The major version bump folds the old `automatix` package into `morphata`
|
|
6
49
|
and replaces the constellation automata classes with a single typed intermediate
|
|
@@ -6,24 +6,30 @@ The `justfile` defines a set of build, lint, and test commands, which can direct
|
|
|
6
6
|
run as below:
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
The examples below assume the project virtual environment is activated (either
|
|
10
|
+
via `direnv` and `.envrc`, or by sourcing `.venv/bin/activate` manually). With
|
|
11
|
+
the venv active the tools are on `PATH` directly; no `uv run` prefix is needed.
|
|
12
|
+
If you'd rather not activate, prefix each command with `uv run --dev --frozen`
|
|
13
|
+
(or use the `just` recipes, which handle this for you).
|
|
14
|
+
|
|
9
15
|
**Testing** :
|
|
10
16
|
```bash
|
|
11
17
|
# Run all tests (uses --lf for last-failed)
|
|
12
18
|
just test
|
|
13
19
|
# OR
|
|
14
|
-
|
|
20
|
+
pytest --lf
|
|
15
21
|
|
|
16
22
|
# Run all tests verbosely without --lf
|
|
17
|
-
|
|
23
|
+
pytest -v
|
|
18
24
|
|
|
19
25
|
# Run a single test file
|
|
20
|
-
|
|
26
|
+
pytest tests/test_alphabet.py -v
|
|
21
27
|
|
|
22
28
|
# Run a single test function
|
|
23
|
-
|
|
29
|
+
pytest tests/test_alphabet.py::TestBooleanAlphabet::test_powerset_alphabet -v
|
|
24
30
|
|
|
25
31
|
# Run with coverage
|
|
26
|
-
|
|
32
|
+
pytest --cov=morphata --cov-report=term
|
|
27
33
|
```
|
|
28
34
|
|
|
29
35
|
**Linting and Formatting** :
|
|
@@ -31,8 +37,8 @@ uv run --dev --frozen pytest --cov=morphata --cov-report=term
|
|
|
31
37
|
# Format and lint (fixes issues automatically)
|
|
32
38
|
just fmt
|
|
33
39
|
# OR
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
ruff format
|
|
41
|
+
ruff check --output-format concise --fix --exit-non-zero-on-fix
|
|
36
42
|
|
|
37
43
|
# Format + type check
|
|
38
44
|
just lint
|
|
@@ -44,9 +50,9 @@ just lint
|
|
|
44
50
|
just type-check
|
|
45
51
|
|
|
46
52
|
# Run specific type checkers
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
mypy --strict
|
|
54
|
+
ty check --output-format concise
|
|
55
|
+
pyrefly check --output-format min-text
|
|
50
56
|
```
|
|
51
57
|
|
|
52
58
|
**Development Setup** :
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: morphata
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: Representation theory for automata, made practical.
|
|
5
5
|
Project-URL: Documentation, https://docs.anandb.dev/morphata
|
|
6
6
|
Project-URL: Repository, https://git.anandb.dev/morphata.git
|
|
@@ -16,7 +16,7 @@ Requires-Dist: attrs>=25.4.0
|
|
|
16
16
|
Requires-Dist: dd>=0.6.0
|
|
17
17
|
Requires-Dist: jaxtyping>=0.3
|
|
18
18
|
Requires-Dist: lark>=1.3.1
|
|
19
|
-
Requires-Dist: logic-asts>=1.
|
|
19
|
+
Requires-Dist: logic-asts>=1.6.0
|
|
20
20
|
Requires-Dist: networkx
|
|
21
21
|
Requires-Dist: numpy
|
|
22
22
|
Requires-Dist: types-networkx
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
PSL
|
|
2
|
+
===
|
|
3
|
+
|
|
4
|
+
Property Specification Language to Alternating Automaton conversion.
|
|
5
|
+
|
|
6
|
+
Finite-trace (PSLf) and omega-trace (Büchi) acceptance are both
|
|
7
|
+
supported via the ``finite`` keyword argument to
|
|
8
|
+
:func:`~morphata.logic.psl.psl_to_automaton`. Suffix implications
|
|
9
|
+
follow Spot's overlapping semantics: the last symbol matched by the
|
|
10
|
+
SERE prefix is shared with the first position at which the
|
|
11
|
+
continuation is evaluated.
|
|
12
|
+
|
|
13
|
+
.. automodule:: morphata.logic.psl
|
|
14
|
+
:members:
|
|
15
|
+
:show-inheritance:
|
|
@@ -30,6 +30,15 @@ Features
|
|
|
30
30
|
automata.
|
|
31
31
|
- LTL/LTLf to alternating Büchi / finite automata in
|
|
32
32
|
:mod:`morphata.logic.ltl`.
|
|
33
|
+
- SERE (Sequential Extended Regular Expressions) to alternating
|
|
34
|
+
finite automata in :mod:`morphata.logic.sere`. Supports
|
|
35
|
+
concatenation, fusion, alternation, length-matching intersection,
|
|
36
|
+
bounded and unbounded repetition, and Boolean leaves.
|
|
37
|
+
- PSL (Property Specification Language) to alternating automata in
|
|
38
|
+
:mod:`morphata.logic.psl`. Both finite-trace (PSLf) and Büchi
|
|
39
|
+
semantics, covering strong / weak / negated-strong closures and
|
|
40
|
+
existential / universal suffix implication (Spot overlapping
|
|
41
|
+
semantics).
|
|
33
42
|
- Spatio-Temporal Reach and Escape Logic (STREL) over labelled
|
|
34
43
|
graphs in :mod:`morphata.logic.strel`.
|
|
35
44
|
|
|
@@ -128,4 +137,3 @@ For alternating weighted automata in multi-agent systems:
|
|
|
128
137
|
symbolic-transforms
|
|
129
138
|
concepts/index
|
|
130
139
|
api/modules
|
|
131
|
-
changelog
|
morphata-2.0.1/justfile
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Set shell options for safety
|
|
2
|
+
|
|
3
|
+
set shell := ["bash", "-eu", "-o", "pipefail", "-c"]
|
|
4
|
+
set unstable
|
|
5
|
+
|
|
6
|
+
# If we want to use CUDA, the CUDA_VERSION variable should not be empty and contain the
|
|
7
|
+
# version number (either 12 or 13)
|
|
8
|
+
|
|
9
|
+
CUDA_VERSION := env("CUDA_VERSION", "12")
|
|
10
|
+
[private]
|
|
11
|
+
_env := if which("nvidia-smi") == "" { "default" } else { "cu" + CUDA_VERSION }
|
|
12
|
+
PIXI_ENV := env("PIXI_ENV", _env)
|
|
13
|
+
DEFAULT_PIXI_ARGS := "--environment " + PIXI_ENV
|
|
14
|
+
|
|
15
|
+
export PIXI_FROZEN := env("PIXI_FROZEN", "true")
|
|
16
|
+
|
|
17
|
+
# Default: create the dev environment
|
|
18
|
+
default: dev
|
|
19
|
+
|
|
20
|
+
# Set up development environment
|
|
21
|
+
dev: sync-venv
|
|
22
|
+
|
|
23
|
+
# Format and lint code
|
|
24
|
+
[no-cd]
|
|
25
|
+
fmt:
|
|
26
|
+
ruff format
|
|
27
|
+
ruff check --output-format concise --fix --exit-non-zero-on-fix .
|
|
28
|
+
|
|
29
|
+
# Run type checkers
|
|
30
|
+
[no-cd]
|
|
31
|
+
[private]
|
|
32
|
+
ty-check:
|
|
33
|
+
ty check --output-format concise
|
|
34
|
+
|
|
35
|
+
[no-cd]
|
|
36
|
+
[private]
|
|
37
|
+
pyrefly-check:
|
|
38
|
+
pyrefly check --output-format min-text
|
|
39
|
+
|
|
40
|
+
[no-cd]
|
|
41
|
+
[private]
|
|
42
|
+
mypy-check:
|
|
43
|
+
mypy --strict
|
|
44
|
+
|
|
45
|
+
[no-cd]
|
|
46
|
+
[private]
|
|
47
|
+
pyright-check:
|
|
48
|
+
basedpyright
|
|
49
|
+
|
|
50
|
+
# [parallel]
|
|
51
|
+
type-check: mypy-check
|
|
52
|
+
|
|
53
|
+
# pyright-check
|
|
54
|
+
# ty-check pyrefly-check
|
|
55
|
+
|
|
56
|
+
# Run both formatting and type checking
|
|
57
|
+
[no-cd]
|
|
58
|
+
lint: fmt type-check
|
|
59
|
+
|
|
60
|
+
# Run tests
|
|
61
|
+
[no-cd]
|
|
62
|
+
test:
|
|
63
|
+
pytest --lf
|
|
64
|
+
|
|
65
|
+
docs:
|
|
66
|
+
sphinx-build -b html docs/ docs/_build/html
|
|
67
|
+
|
|
68
|
+
# Sync virtual environment
|
|
69
|
+
sync-venv:
|
|
70
|
+
pixi install {{ DEFAULT_PIXI_ARGS }}
|