morphata 2.2.3__tar.gz → 2.3.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.2.3 → morphata-2.3.1}/.envrc +2 -0
- morphata-2.3.1/.rstcheck.cfg +43 -0
- {morphata-2.2.3 → morphata-2.3.1}/AGENTS.md +19 -0
- {morphata-2.2.3 → morphata-2.3.1}/CHANGELOG.md +248 -86
- {morphata-2.2.3 → morphata-2.3.1}/PKG-INFO +4 -3
- {morphata-2.2.3 → morphata-2.3.1}/bench/README.md +6 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_distance_perf.py +19 -20
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_transforms_perf.py +129 -10
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/modules.rst +1 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.operators.rst +9 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.storage.rst +19 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.symbolic.rst +11 -1
- morphata-2.3.1/docs/api/morphata.utils.rst +61 -0
- morphata-2.3.1/docs/bibliography.rst +4 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/acceptance.rst +2 -2
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/hoa.rst +3 -3
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/operators.rst +25 -1
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/symbolic.rst +55 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/conf.py +14 -4
- {morphata-2.2.3 → morphata-2.3.1}/docs/index.rst +4 -2
- {morphata-2.2.3 → morphata-2.3.1}/docs/quick-start.rst +2 -2
- morphata-2.3.1/docs/refs.bib +516 -0
- {morphata-2.2.3 → morphata-2.3.1}/pixi.lock +663 -692
- {morphata-2.2.3 → morphata-2.3.1}/pyproject.toml +25 -4
- {morphata-2.2.3 → morphata-2.3.1}/pytest.toml +2 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/_version.py +2 -2
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/acceptance.py +1 -1
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/alphabet.py +128 -17
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/hoa/__init__.py +2 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/__init__.py +8 -1
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/_common.py +5 -2
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/operators/_backend.py +1 -1
- morphata-2.3.1/src/morphata/operators/jax.py +811 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/operators/matrix.py +12 -16
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/operators/polynomial.py +3 -0
- morphata-2.3.1/src/morphata/storage/__init__.py +14 -0
- morphata-2.3.1/src/morphata/storage/run.py +204 -0
- morphata-2.3.1/src/morphata/storage/serialize.py +554 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/storage/signature.py +99 -26
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/symbolic/__init__.py +13 -1
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/symbolic/automaton.py +378 -12
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/symbolic/bdd.py +144 -74
- morphata-2.3.1/src/morphata/symbolic/distance.py +1029 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/symbolic/transforms.py +457 -107
- morphata-2.3.1/src/morphata/utils/__init__.py +22 -0
- morphata-2.3.1/src/morphata/utils/edit_distance.py +624 -0
- morphata-2.3.1/src/morphata/utils/sampling.py +728 -0
- morphata-2.3.1/src/morphata/utils/witness.py +139 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/test_exporter.py +100 -52
- morphata-2.3.1/tests/hoa/test_parser.py +118 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/logic/test_ltl.py +22 -20
- {morphata-2.2.3 → morphata-2.3.1}/tests/logic/test_sere.py +0 -30
- morphata-2.3.1/tests/operators/test_jax.py +81 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/operators/test_matrix.py +78 -20
- {morphata-2.2.3 → morphata-2.3.1}/tests/operators/test_polynomial.py +9 -10
- morphata-2.3.1/tests/operators/test_reductions.py +116 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/storage/test_serialize.py +153 -7
- {morphata-2.2.3 → morphata-2.3.1}/tests/storage/test_signature.py +84 -2
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_bdd_helpers.py +16 -19
- morphata-2.3.1/tests/symbolic/test_distance.py +652 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_language_equivalence.py +146 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_ltlf2dfa_equivalence.py +19 -30
- morphata-2.3.1/tests/symbolic/test_rfsa.py +529 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_symbolic_automaton.py +54 -10
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_transforms.py +156 -1
- morphata-2.3.1/tests/test_alphabet.py +98 -0
- morphata-2.3.1/tests/utils/test_edit_distance.py +499 -0
- {morphata-2.2.3 → morphata-2.3.1}/uv.lock +1031 -863
- morphata-2.2.3/.rstcheck.cfg +0 -13
- morphata-2.2.3/src/morphata/storage/__init__.py +0 -6
- morphata-2.2.3/src/morphata/storage/serialize.py +0 -260
- morphata-2.2.3/src/morphata/symbolic/distance.py +0 -361
- morphata-2.2.3/src/morphata/utils/__init__.py +0 -9
- morphata-2.2.3/tests/hoa/test_parser.py +0 -62
- morphata-2.2.3/tests/symbolic/test_distance.py +0 -150
- morphata-2.2.3/tests/test_alphabet.py +0 -58
- {morphata-2.2.3 → morphata-2.3.1}/.basedpyright/baseline.json +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.dockerignore +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.editorconfig +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.envrc.recommended +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.fdignore +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.gitattributes +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.gitignore +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.mailmap +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/.python-version +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/CLAUDE.md +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/CONTRIBUTING.md +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/LICENSE +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/README.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/__init__.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/conftest.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_equivalence_perf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_hoa_exporter_perf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_hoa_parser_perf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_matrix_operator_perf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/bench/test_sere_nlm_perf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/ci/make-release +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/Makefile +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/_static/navigation.html +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.acc_expr.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.acceptance.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.alphabet.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.builder.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.hoa.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/api/morphata.logic.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/changelog.md +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/index.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/docs/concepts/weights.rst +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/justfile +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/mypy.ini +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/project.utf-8.add +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/project.utf-8.add.spl +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/pyrightconfig.json +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/rules/no-derivative-multiarg.yml +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/rules/no-typing-as-ty.yml +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/sgconfig.yml +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/__init__.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/acc_expr.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/builder.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/hoa/__main__.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/hoa/hoa.lark +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/hoa/parser.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/__init__.pyi +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/ltl.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/psl.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/logic/sere.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/operators/__init__.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/py.typed +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/utils/expressions.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/src/morphata/utils/memory.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/conftest.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut1.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut11.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut2.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut3.2.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut3.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut4.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut5.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut6.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut7.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/aut8.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/finite_aut.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/gen_buchi_3.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/gen_cobuchi_2.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/rabin_2pair.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/hoa/streett_2pair.hoa +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/logic/__init__.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/logic/test_psl.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_compose.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_from_hoaf.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/symbolic/test_to_hoa.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/test_acceptance_validation.py +0 -0
- {morphata-2.2.3 → morphata-2.3.1}/tests/test_builder.py +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[rstcheck]
|
|
2
|
+
ignore_directives =
|
|
3
|
+
automodule,
|
|
4
|
+
autoclass,
|
|
5
|
+
autofunction,
|
|
6
|
+
autotype,
|
|
7
|
+
autodata,
|
|
8
|
+
autoexception,
|
|
9
|
+
bibliography,
|
|
10
|
+
footbibliography
|
|
11
|
+
ignore_roles =
|
|
12
|
+
external:py:mod,
|
|
13
|
+
cite,
|
|
14
|
+
cite:p,
|
|
15
|
+
cite:ps,
|
|
16
|
+
cite:t,
|
|
17
|
+
cite:ts,
|
|
18
|
+
cite:ct,
|
|
19
|
+
cite:cts,
|
|
20
|
+
cite:empty,
|
|
21
|
+
cite:alp,
|
|
22
|
+
cite:alps,
|
|
23
|
+
cite:label,
|
|
24
|
+
cite:labelpar,
|
|
25
|
+
cite:year,
|
|
26
|
+
cite:yearpar,
|
|
27
|
+
cite:author,
|
|
28
|
+
cite:authors,
|
|
29
|
+
cite:authorpar,
|
|
30
|
+
cite:authorpars,
|
|
31
|
+
cite:cauthor,
|
|
32
|
+
cite:cauthors,
|
|
33
|
+
footcite,
|
|
34
|
+
footcite:p,
|
|
35
|
+
footcite:ps,
|
|
36
|
+
footcite:t,
|
|
37
|
+
footcite:ts,
|
|
38
|
+
footcite:ct,
|
|
39
|
+
footcite:cts
|
|
40
|
+
report_level = WARNING
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# vim: set ft=dosini
|
|
@@ -29,6 +29,13 @@ The narrow exception: a **surgical, already-decided edit** the author has spelle
|
|
|
29
29
|
Do exactly that and nothing more.
|
|
30
30
|
When unsure whether a change qualifies, treat it as out of scope and ask.
|
|
31
31
|
|
|
32
|
+
## Project Boundaries
|
|
33
|
+
|
|
34
|
+
Morphata owns automata representations, algebraic operations, semiring operators,
|
|
35
|
+
and execution. Automata Encoders owns symbolic input features, trainable
|
|
36
|
+
encoders, training/evaluation tools, and comparison baselines. Morphata must
|
|
37
|
+
not depend on Automata Encoders.
|
|
38
|
+
|
|
32
39
|
## Development Environment
|
|
33
40
|
|
|
34
41
|
The development shell already has the project virtual environment activated,
|
|
@@ -38,3 +45,15 @@ etc. are on `PATH` directly.
|
|
|
38
45
|
Just invoke the tool.
|
|
39
46
|
If a tool is missing, stop and tell the user rather than trying to bootstrap
|
|
40
47
|
or reinstall the environment.
|
|
48
|
+
|
|
49
|
+
## Tests
|
|
50
|
+
|
|
51
|
+
Write tests to verify the common case and edge cases with distinct failure modes.
|
|
52
|
+
Do not add tests solely to increase coverage. Check expected behavior against
|
|
53
|
+
the public contract or an independent reference; avoid tests that merely repeat
|
|
54
|
+
the implementation. Each test should identify a behavior or failure it checks.
|
|
55
|
+
|
|
56
|
+
## Documentation
|
|
57
|
+
|
|
58
|
+
Use NumPy/numpydoc-style sections for Python docstrings. Use RST math markup
|
|
59
|
+
inside those sections and in the main docstring body.
|
|
@@ -1,5 +1,159 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.3.1 — 2026-11-11
|
|
4
|
+
|
|
5
|
+
This isn't a hefty release,
|
|
6
|
+
but does have some nice QoL things as well as some performance updates and bug fixes.
|
|
7
|
+
A large chunk of these was discovered/needed
|
|
8
|
+
while dogfooding my learned automata embeddings project,
|
|
9
|
+
so I guess they are informed by "real-world" scenarios.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `SymbolicAutomaton.distinguishing_words` finds the shortest words accepted by exactly
|
|
14
|
+
one of two automata.
|
|
15
|
+
You can ask for several witnesses, set a minimum length, and randomize ties.
|
|
16
|
+
Works with alternating automata too, without first determinizing them,
|
|
17
|
+
and the two automata can use different BDD managers.
|
|
18
|
+
|
|
19
|
+
- Persistent automata can now be run directly through `morphata.storage`,
|
|
20
|
+
without reconstructing a symbolic automaton or needing a BDD manager.
|
|
21
|
+
There is a `distinguishing_words` helper for these too.
|
|
22
|
+
|
|
23
|
+
- Edit distances for DFAs given as explicit transition tables,
|
|
24
|
+
through `DFATable` and the `dfa_*` distance functions in `morphata.utils`.
|
|
25
|
+
These cover unsigned and signed directed Levenshtein distances,
|
|
26
|
+
and minimum language separation, without BDD operations.
|
|
27
|
+
Helpers convert deterministic symbolic and persistent automata to tables.
|
|
28
|
+
The unsigned distance also accepts a `cap`,
|
|
29
|
+
useful when you only care how far apart the languages are up to some budget.
|
|
30
|
+
|
|
31
|
+
- `CanonicalDfaHasher.residual_digests_from_table` computes residual digests directly
|
|
32
|
+
from a complete DFA table.
|
|
33
|
+
Gives the same digests as the symbolic path with `minimize=False`,
|
|
34
|
+
without going through BDDs.
|
|
35
|
+
|
|
36
|
+
### Performance
|
|
37
|
+
|
|
38
|
+
- Symbolic language repair distance now starts with small edit budgets
|
|
39
|
+
and increases them until it finds one that works.
|
|
40
|
+
Small distances no longer require building the automaton
|
|
41
|
+
for the full finite-repair bound before the search even starts.
|
|
42
|
+
|
|
43
|
+
- Transition partitioning does less repeated BDD work.
|
|
44
|
+
Transformations also retain known determinism and alternation flags,
|
|
45
|
+
saving checks whose answers the construction already knows.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Matrix operators built from specifications now materialize constant accepting
|
|
50
|
+
and rejecting sinks.
|
|
51
|
+
Those successors need actual states in the matrix representation too.
|
|
52
|
+
|
|
53
|
+
- BDD caches used during partitioning, determinization,
|
|
54
|
+
and dealternation are now cleared when their scope ends,
|
|
55
|
+
fixing memory leaks from retained BDD references.
|
|
56
|
+
|
|
57
|
+
- Alphabet domains are now applied when compiling specifications,
|
|
58
|
+
exposing transition partitions, and reversing DFA transitions.
|
|
59
|
+
Impossible predicate valuations no longer contribute edges in these paths.
|
|
60
|
+
|
|
61
|
+
- Automata with constant initial formulas and no states now compose correctly.
|
|
62
|
+
Previously, composition assumed there was at least one state to remap.
|
|
63
|
+
|
|
64
|
+
### Documentation
|
|
65
|
+
|
|
66
|
+
- The automaton sampling helpers now have API documentation, covering random automata,
|
|
67
|
+
structured language families, and mutations.
|
|
68
|
+
|
|
69
|
+
## 2.3.0 — 2026-10-21
|
|
70
|
+
|
|
71
|
+
This is *another* hefty release,
|
|
72
|
+
and has been the culmination of `morphata` being used to dogfood multiple other
|
|
73
|
+
projects --- I will not reveal the level of success of those other projects though ---
|
|
74
|
+
which has allowed me to harden `morphata` and also add a bunch of relevant features.
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- `BooleanAlphabet.as_guard` turns a concrete symbol into its BDD guard.
|
|
79
|
+
|
|
80
|
+
- `to_min_rfsa`, also available as `SymbolicAutomaton.to_min_rfsa`,
|
|
81
|
+
constructs canonical residual finite-state automata using cover-aware subset
|
|
82
|
+
exploration and language reversal, without building the full DFA.
|
|
83
|
+
Follows the same API as the other transformers.
|
|
84
|
+
|
|
85
|
+
- `SymbolicAutomaton` now has helpers for determining if its language is empty,
|
|
86
|
+
whether it contains the language of another automaton,
|
|
87
|
+
and a helper to return relational edges (for nondeterministic automata only).
|
|
88
|
+
|
|
89
|
+
- `JaxBatchedMatrixOperator` runs batches of integer-encoded words over dense matrix
|
|
90
|
+
operators using JAX's `lax.scan`.
|
|
91
|
+
You can run every word on every operator, or pair each word with one operator.
|
|
92
|
+
Padded words with different lengths are supported too.
|
|
93
|
+
|
|
94
|
+
- A JAX min-max Boolean algebra with a choice of native or smooth surrogate gradients.
|
|
95
|
+
The forward pass still computes exact min and max;
|
|
96
|
+
the surrogate gives the backward pass a smoother signal.
|
|
97
|
+
|
|
98
|
+
- Automaton sampling helpers in `morphata.utils.sampling`,
|
|
99
|
+
covering random DFAs and AFAs, structured language families, temporal specifications,
|
|
100
|
+
and local mutations.
|
|
101
|
+
Useful when you want some variety in the automata you are working with.
|
|
102
|
+
|
|
103
|
+
- `factor_initial=True` on `remove_alternation`, `determinize`,
|
|
104
|
+
and `to_min_dfa` transforms the components of the initial formula separately,
|
|
105
|
+
then combines them smallest-first.
|
|
106
|
+
Another option for constructions where exploring everything together gets large.
|
|
107
|
+
|
|
108
|
+
- `EditDistanceAutomaton` converts a given symbolic automaton to a min-plus weighted
|
|
109
|
+
automaton that computes the edit distance between a word and the given automaton.
|
|
110
|
+
Additionally, we have lifted this word-language edit distance to a quasimetric
|
|
111
|
+
that computes a directed Hausdorff distance to the `EditDistanceAutomaton` from some
|
|
112
|
+
other automaton.
|
|
113
|
+
|
|
114
|
+
- `unsigned_levenshtein_distance` computes the worst-case number of edits needed to
|
|
115
|
+
repair a source word into the target language.
|
|
116
|
+
It returns zero when the source language is contained in the target.
|
|
117
|
+
`signed_levenshtein_distance` reports a containment margin
|
|
118
|
+
when the source language is contained in the target,
|
|
119
|
+
and the same repair cost otherwise.
|
|
120
|
+
|
|
121
|
+
- `language_separation_distance` computes the minimum edit distance between any pair of
|
|
122
|
+
words from two languages.
|
|
123
|
+
It returns infinity if either is empty.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- Persistent automata now retain the original predicate objects.
|
|
128
|
+
`morphata.storage.configure_converter` lets you use your own cattrs converter
|
|
129
|
+
and predicate serialization hooks, with consistent ordering across backends.
|
|
130
|
+
The JSON helpers remain for string predicates.
|
|
131
|
+
|
|
132
|
+
- Custom alphabet domain callbacks now need to accept `care_vars`.
|
|
133
|
+
`BooleanAlphabet.intersect_with_domain` uses this to constrain guards using only the
|
|
134
|
+
predicates those guards actually mention.
|
|
135
|
+
|
|
136
|
+
### Fixed
|
|
137
|
+
|
|
138
|
+
- DFA minimization now compares guards on the full alphabet domain,
|
|
139
|
+
so guards that differ only on impossible predicate valuations do not split equivalent
|
|
140
|
+
states.
|
|
141
|
+
|
|
142
|
+
- Symbolic transformations reuse alphabet domains within each construction stage.
|
|
143
|
+
Dealternation, determinization,
|
|
144
|
+
and RFSA subset exploration cache projected domains by the combined relation's
|
|
145
|
+
predicate support and apply them before partitioning.
|
|
146
|
+
|
|
147
|
+
- Canonical finite-alphabet traversal now restricts transitions before partitioning,
|
|
148
|
+
so impossible predicate valuations do not affect BFS state numbering.
|
|
149
|
+
|
|
150
|
+
- `compose_automata` now removes pruned states from the finite accepting set too.
|
|
151
|
+
Previously, accepting states could survive in the bookkeeping
|
|
152
|
+
after their transition rows had been removed.
|
|
153
|
+
|
|
154
|
+
- `has_conjunctive_state_terms` previously did not correctly handle successor states
|
|
155
|
+
that were just Boolean constants, i.e., unmaterialized accepting/rejecting sinks.
|
|
156
|
+
|
|
3
157
|
## 2.2.3 — 2026-09-22
|
|
4
158
|
|
|
5
159
|
This is a hefty release, but all really cool things that I am super proud of
|
|
@@ -57,8 +211,8 @@ so I will just be making this a patch release
|
|
|
57
211
|
which keeps finite-alphabet guards compact without changing their meaning.
|
|
58
212
|
|
|
59
213
|
- Symbolic automaton transformations accept an optional initial state formula,
|
|
60
|
-
allowing a transformation to start from a formula other than the automaton's
|
|
61
|
-
|
|
214
|
+
allowing a transformation to start from a formula other than the automaton's stored
|
|
215
|
+
initial condition without modifying the source automaton.
|
|
62
216
|
|
|
63
217
|
- `prune_unreachable`, which removes the states unreachable from an automaton's initial
|
|
64
218
|
states and, with `remove_sink_states=True`, the materialized sink states too (an
|
|
@@ -83,9 +237,9 @@ so I will just be making this a patch release
|
|
|
83
237
|
since the manager's variable levels are not stable under reordering.
|
|
84
238
|
The partition is recomputed on each call.
|
|
85
239
|
|
|
86
|
-
- A `make_sink_states` keyword on `remove_alternation`, `determinize`,
|
|
87
|
-
`minimize_dfa`, controlling whether constant `True`
|
|
88
|
-
materialized as indexed sink states.
|
|
240
|
+
- A `make_sink_states` keyword on `remove_alternation`, `determinize`,
|
|
241
|
+
and `minimize_dfa`, controlling whether constant `True`
|
|
242
|
+
and `False` successors are materialized as indexed sink states.
|
|
89
243
|
|
|
90
244
|
- A `reverse_language` utility that produces an automaton
|
|
91
245
|
that accepts the reversed language.
|
|
@@ -111,12 +265,12 @@ so I will just be making this a patch release
|
|
|
111
265
|
- Add a signed version of the Levenshtein distance between two nondeterministic finite
|
|
112
266
|
automata.
|
|
113
267
|
|
|
114
|
-
- `SemiringAlphabet` now has two optional fields
|
|
115
|
-
|
|
116
|
-
the alphabet.
|
|
268
|
+
- `SemiringAlphabet` now has two optional fields
|
|
269
|
+
that allows one to enumerate all symbols in the alphabet
|
|
270
|
+
(not just predicates), and test if some symbol is contained in the alphabet.
|
|
117
271
|
|
|
118
|
-
- In addition, `BooleanAlphabet` now have a mandatory `domain` keyword argument
|
|
119
|
-
constrains the universe of allowed predicate valuations as a BDD.
|
|
272
|
+
- In addition, `BooleanAlphabet` now have a mandatory `domain` keyword argument
|
|
273
|
+
which constrains the universe of allowed predicate valuations as a BDD.
|
|
120
274
|
|
|
121
275
|
- `morphata.storage` has means to store canonical representations (morphata-specific) of
|
|
122
276
|
`SymbolicAutomaton` to disk.
|
|
@@ -139,9 +293,11 @@ so I will just be making this a patch release
|
|
|
139
293
|
|
|
140
294
|
### Developer Experience
|
|
141
295
|
|
|
142
|
-
- The Pixi environments now describe CPU, CUDA 12,
|
|
143
|
-
|
|
144
|
-
|
|
296
|
+
- The Pixi environments now describe CPU, CUDA 12,
|
|
297
|
+
and CUDA 13 targets with virtual packages,
|
|
298
|
+
so dependency resolution does not have to guess
|
|
299
|
+
which machine it is eventually going to meet.
|
|
300
|
+
`sphinx-autobuild` also joins the development toolbox
|
|
145
301
|
for faster documentation tinkering.
|
|
146
302
|
|
|
147
303
|
### Fixed
|
|
@@ -211,9 +367,9 @@ and increase the surface area of properly typed code.
|
|
|
211
367
|
The variadic `compose_automata`, `is_language_equivalent`,
|
|
212
368
|
and `forward_bisim_reduction` helpers cover composition, equivalence checking,
|
|
213
369
|
and language-preserving quotienting without leaving the symbolic representation.
|
|
214
|
-
- Add a typed `BDDManager`/`Function` API and symbolic utilities
|
|
215
|
-
manager, reindexing or quotienting states, materializing sinks,
|
|
216
|
-
states, and constructing universal acceptors and rejectors.
|
|
370
|
+
- Add a typed `BDDManager`/`Function` API and symbolic utilities
|
|
371
|
+
for replacing a manager, reindexing or quotienting states, materializing sinks,
|
|
372
|
+
traversing reachable states, and constructing universal acceptors and rejectors.
|
|
217
373
|
- Support arbitrary HOA v1 acceptance expressions through `GenericCondition`,
|
|
218
374
|
in addition to the concrete finite, Büchi, co-Büchi, generalized Büchi/co-Büchi,
|
|
219
375
|
Rabin, and Streett conditions.
|
|
@@ -237,8 +393,9 @@ and increase the surface area of properly typed code.
|
|
|
237
393
|
use a Boolean state expression for an alternating conjunction.
|
|
238
394
|
The old `variant`/`DeltaKind` construction API is gone.
|
|
239
395
|
- Alphabets now separate symbol labeling from guard weighting.
|
|
240
|
-
`BooleanAlphabet.labeling` returns an `AP -> bool` mapping,
|
|
241
|
-
functions receive guards in sum-of-products form.
|
|
396
|
+
`BooleanAlphabet.labeling` returns an `AP -> bool` mapping,
|
|
397
|
+
while operator weight functions receive guards in sum-of-products form.
|
|
398
|
+
`Alphabet`, `WeightedAlphabet`,
|
|
242
399
|
and `weighted_alphabet` are replaced by `BooleanAlphabet`, `SemiringAlphabet`,
|
|
243
400
|
`powerset_alphabet`, and `finite_alphabet`.
|
|
244
401
|
- `MatrixOperator` and `PolynomialOperator` are constructed with
|
|
@@ -254,12 +411,13 @@ and increase the surface area of properly typed code.
|
|
|
254
411
|
### Fixed
|
|
255
412
|
|
|
256
413
|
- Correct symbolic derivatives for negated variables and SERE nodes.
|
|
257
|
-
- Fix breadth-first traversal ordering, symbolic language equivalence,
|
|
258
|
-
partitioning when multiple guards have the same residual.
|
|
259
|
-
- Correct `step()` labeling and the structural checks for deterministic
|
|
260
|
-
forward-progressing automata.
|
|
261
|
-
- Make builders, HOA conversion,
|
|
262
|
-
consistently by using dense
|
|
414
|
+
- Fix breadth-first traversal ordering, symbolic language equivalence,
|
|
415
|
+
and transition partitioning when multiple guards have the same residual.
|
|
416
|
+
- Correct `step()` labeling and the structural checks for deterministic
|
|
417
|
+
and forward-progressing automata.
|
|
418
|
+
- Make builders, HOA conversion,
|
|
419
|
+
and both operators handle sparse external state IDs consistently by using dense
|
|
420
|
+
indices only internally.
|
|
263
421
|
|
|
264
422
|
### Removed
|
|
265
423
|
|
|
@@ -268,9 +426,9 @@ and increase the surface area of properly typed code.
|
|
|
268
426
|
`symbolic.equivalence`, and `symbolic.compose` modules.
|
|
269
427
|
Their surviving operations now live on `SymbolicAutomaton` or in `morphata.symbolic`;
|
|
270
428
|
there is no replacement for STREL or BDD-JSON persistence in this release.
|
|
271
|
-
- Remove the specialized composition-map/transition-enumeration APIs
|
|
272
|
-
`prune`; use general symbolic composition and `forward_bisim_reduction`
|
|
273
|
-
semantics fit.
|
|
429
|
+
- Remove the specialized composition-map/transition-enumeration APIs
|
|
430
|
+
and structural `prune`; use general symbolic composition and `forward_bisim_reduction`
|
|
431
|
+
where those semantics fit.
|
|
274
432
|
|
|
275
433
|
## 2.1.0 — 2026-06-11
|
|
276
434
|
|
|
@@ -322,9 +480,9 @@ and increase the surface area of properly typed code.
|
|
|
322
480
|
|
|
323
481
|
### Fixed
|
|
324
482
|
|
|
325
|
-
- Using `SymbolicAutomaton.to_bdd_json`
|
|
326
|
-
preserve the positive normal form of the
|
|
327
|
-
cofactor expansion.
|
|
483
|
+
- Using `SymbolicAutomaton.to_bdd_json`
|
|
484
|
+
and `SymbolicAutomaton.from_bdd_json` did not preserve the positive normal form of the
|
|
485
|
+
BDDs because we were using incorrect Shannon cofactor expansion.
|
|
328
486
|
|
|
329
487
|
### Performance
|
|
330
488
|
|
|
@@ -366,10 +524,9 @@ and increase the surface area of properly typed code.
|
|
|
366
524
|
but minimization can merge classes such
|
|
367
525
|
that a representative's per-factor successor lands on a non-representative tuple,
|
|
368
526
|
so the full surjection has to be there.
|
|
369
|
-
- `iter_composed_transitions` enumerates `(state, symbol, successor)`
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
`(state, symbol)`.
|
|
527
|
+
- `iter_composed_transitions` enumerates `(state, symbol, successor)` of a composed DFA
|
|
528
|
+
without building the product BDD, walking factor deltas directly and hitting
|
|
529
|
+
`tuple_to_class` once per `(state, symbol)`.
|
|
373
530
|
|
|
374
531
|
### Performance
|
|
375
532
|
|
|
@@ -382,23 +539,22 @@ and increase the surface area of properly typed code.
|
|
|
382
539
|
and per-class point dicts across same-support rows.
|
|
383
540
|
Conjunction-fold DFAs get 1.3-1.6x; `F a & F b & F c & F d` q1 went ~343us -> ~175us.
|
|
384
541
|
- `isomorphic` routes through a compact support-reduced fingerprint
|
|
385
|
-
and skips the broadcast expansion.
|
|
386
|
-
~333ms -> ~83ms.
|
|
542
|
+
and skips the broadcast expansion.
|
|
543
|
+
`|AP|=19` sparse case: ~333ms -> ~83ms.
|
|
387
544
|
|
|
388
545
|
### Changed
|
|
389
546
|
|
|
390
|
-
- `SymbolicAutomaton` carries a derived `ap_inverse: Mapping[str, AP]`
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
recorded rather than gated on a hard-coded threshold.
|
|
547
|
+
- `SymbolicAutomaton` carries a derived `ap_inverse: Mapping[str, AP]` populated in
|
|
548
|
+
`__post_init__`; `to_automaton` and `compose._merge_managers` route through it.
|
|
549
|
+
- New symbolic benches are pytest-benchmark cases,
|
|
550
|
+
so timings get recorded rather than gated on a hard-coded threshold.
|
|
395
551
|
|
|
396
552
|
## 2.0.7 — 2026-06-02
|
|
397
553
|
|
|
398
554
|
### Fixed
|
|
399
555
|
|
|
400
|
-
- The BDD JSON exporter in `dd.cudd` needed to be worked around because of a bug
|
|
401
|
-
`mgr.true` and `mrg.false` do not survive a round trip serialization.
|
|
556
|
+
- The BDD JSON exporter in `dd.cudd` needed to be worked around because of a bug
|
|
557
|
+
where `mgr.true` and `mrg.false` do not survive a round trip serialization.
|
|
402
558
|
|
|
403
559
|
## 2.0.6 — 2026-06-02
|
|
404
560
|
|
|
@@ -410,8 +566,9 @@ and increase the surface area of properly typed code.
|
|
|
410
566
|
|
|
411
567
|
### Added
|
|
412
568
|
|
|
413
|
-
- Added a free-floating function
|
|
414
|
-
|
|
569
|
+
- Added a free-floating function
|
|
570
|
+
that helps enumerate the successor BDDs from a symbolic automaton state,
|
|
571
|
+
given a specific alphabet and set of symbols.
|
|
415
572
|
|
|
416
573
|
## 2.0.5 — 2026-06-01
|
|
417
574
|
|
|
@@ -465,8 +622,8 @@ smaller minimal DFAs, having a better composition operation benefits us.
|
|
|
465
622
|
and bounded `FusionRepeat` desugar through `logic_asts.spec.Expr.expand`.
|
|
466
623
|
Unbounded `FusionRepeat[:*i..]` deliberately raises `NotImplementedError` —
|
|
467
624
|
I don't have a clean expansion for it yet.
|
|
468
|
-
- Benchmarking script for SERE NLM intersection,
|
|
469
|
-
break the perf curve.
|
|
625
|
+
- Benchmarking script for SERE NLM intersection,
|
|
626
|
+
so I can see when I break the perf curve.
|
|
470
627
|
|
|
471
628
|
### Changed
|
|
472
629
|
|
|
@@ -477,8 +634,7 @@ smaller minimal DFAs, having a better composition operation benefits us.
|
|
|
477
634
|
|
|
478
635
|
### Miscellaneous
|
|
479
636
|
|
|
480
|
-
- The README is linked from `pyproject.toml`, so it actually shows up
|
|
481
|
-
on PyPI.
|
|
637
|
+
- The README is linked from `pyproject.toml`, so it actually shows up on PyPI.
|
|
482
638
|
|
|
483
639
|
## 2.0.1 — 2026-05-24
|
|
484
640
|
|
|
@@ -512,8 +668,9 @@ interest.
|
|
|
512
668
|
Two LTL helpers (`_aut_symbolic_expansion`, `_empty_trace_value`) were renamed to
|
|
513
669
|
`ltl_symbolic_expansion` / `ltl_empty_trace_value` so PSL can delegate to them for
|
|
514
670
|
pure-LTL subformulas.
|
|
515
|
-
- Moved off `uv` and onto Pixi.
|
|
516
|
-
the way it churns the lockfile weren't working
|
|
671
|
+
- Moved off `uv` and onto Pixi.
|
|
672
|
+
`uv`'s handling of CUDA packages and the way it churns the lockfile weren't working
|
|
673
|
+
for me; Pixi does.
|
|
517
674
|
|
|
518
675
|
### Fixed
|
|
519
676
|
|
|
@@ -559,9 +716,8 @@ short-lived manager for these things.
|
|
|
559
716
|
- `psl_to_automaton` does not yet decompose LTL temporal operators
|
|
560
717
|
that wrap PSL closures at the top level (e.g. `Always(StrongClosure(r))`).
|
|
561
718
|
Lift the PSL fragment out of the surrounding LTL temporal operator before calling.
|
|
562
|
-
- The continuation of a `SuffixImpliesExist` / `SuffixImpliesUniv`
|
|
563
|
-
|
|
564
|
-
continuation raise `NotImplementedError`.
|
|
719
|
+
- The continuation of a `SuffixImpliesExist` / `SuffixImpliesUniv` must be a pure-LTL
|
|
720
|
+
formula; nested PSL closures inside a continuation raise `NotImplementedError`.
|
|
565
721
|
|
|
566
722
|
## 2.0.0 — 2026-05-23
|
|
567
723
|
|
|
@@ -624,9 +780,10 @@ which will be summarized below.
|
|
|
624
780
|
and `WeightedAlphabet.from_predicates(...)` folds per-AP predicates through the
|
|
625
781
|
semiring.
|
|
626
782
|
The reverse direction is deliberately omitted —
|
|
627
|
-
recovering Boolean semantics from arbitrary `V` needs an ordering and a cut
|
|
628
|
-
STL), and pretending otherwise would silently produce garbage.
|
|
629
|
-
- **Ergonomic construction.**
|
|
783
|
+
recovering Boolean semantics from arbitrary `V` needs an ordering and a cut
|
|
784
|
+
(cf. STL), and pretending otherwise would silently produce garbage.
|
|
785
|
+
- **Ergonomic construction.**
|
|
786
|
+
`AutomatonBuilder` replaces the old NFA builder.
|
|
630
787
|
Add states, add transitions with a guard and a successor
|
|
631
788
|
(single state, set of states, or a raw `BoolExpr` for full alternation),
|
|
632
789
|
and `build()` cleans up by merging rows that share a successor.
|
|
@@ -654,9 +811,11 @@ which will be summarized below.
|
|
|
654
811
|
The BDD cofactor path works for any `BooleanAlphabet`,
|
|
655
812
|
so you can feed a `SymbolicAutomaton` over integers, graph nodes, whatever —
|
|
656
813
|
as long as you can write a labeling.
|
|
657
|
-
- **The AFA-to-min-DFA pipeline actually exists now.**
|
|
658
|
-
`
|
|
659
|
-
|
|
814
|
+
- **The AFA-to-min-DFA pipeline actually exists now.**
|
|
815
|
+
`nfa_from_afa` (dealternation), `determinize`
|
|
816
|
+
(subset construction with a sink),
|
|
817
|
+
`minimize` (Hopcroft) — all share one BDD manager
|
|
818
|
+
and successively tighten the invariants on successor BDDs.
|
|
660
819
|
`SymbolicAutomaton.to_min_dfa` chains the three.
|
|
661
820
|
Finite-word only for now; omega-regular determinisation is a different beast.
|
|
662
821
|
- **DFA equivalence checks.**
|
|
@@ -667,17 +826,19 @@ which will be summarized below.
|
|
|
667
826
|
|
|
668
827
|
### Operators
|
|
669
828
|
|
|
670
|
-
- **One per-step shape.**
|
|
829
|
+
- **One per-step shape.**
|
|
830
|
+
`SymbolicAutomaton`, `MatrixOperator`,
|
|
671
831
|
and `PolynomialOperator` all expose the same `step(current, symbol)` / `run(word)` /
|
|
672
832
|
`accepts(word)` shape.
|
|
673
833
|
Each binds its alphabet at construction
|
|
674
834
|
(matching how the semiring / algebra were already bound),
|
|
675
835
|
so the per-call API is monomorphic and `V` is pinned end-to-end.
|
|
676
836
|
Wanted symmetry between the layers; got it.
|
|
677
|
-
- **`PolynomialOperator` evaluates lazily.**
|
|
678
|
-
`alphabet.weight` on the fly,
|
|
679
|
-
|
|
680
|
-
|
|
837
|
+
- **`PolynomialOperator` evaluates lazily.**
|
|
838
|
+
`step` evaluates guards against `alphabet.weight` on the fly,
|
|
839
|
+
with no per-symbol precomputation —
|
|
840
|
+
important because the natural LTL alphabet is `Σ = 2^AP`,
|
|
841
|
+
and you really don't want to materialise `2^|AP|` polynomials up front.
|
|
681
842
|
The AFA's row structure stays static
|
|
682
843
|
(good for JAX tracing), and the alphabet decides whether to memoise.
|
|
683
844
|
- **Polynomial performance.**
|
|
@@ -687,8 +848,9 @@ which will be summarized below.
|
|
|
687
848
|
|
|
688
849
|
### Tooling and Tests
|
|
689
850
|
|
|
690
|
-
- **Hand-written changelogs.**
|
|
691
|
-
that needed enough editing that I might
|
|
851
|
+
- **Hand-written changelogs.**
|
|
852
|
+
`git cliff` was producing entries that needed enough editing that I might
|
|
853
|
+
as well write them by hand.
|
|
692
854
|
`ci/make-release` no longer touches `CHANGELOG.md` or tag messages.
|
|
693
855
|
Run `git cliff` separately if you want a draft to crib from.
|
|
694
856
|
- **Tests.**
|
|
@@ -701,23 +863,23 @@ which will be summarized below.
|
|
|
701
863
|
|
|
702
864
|
Documentation and tooling cleanup.
|
|
703
865
|
|
|
704
|
-
- Replaced stray non-ASCII characters in docs
|
|
705
|
-
copy-paste rather than authored content).
|
|
866
|
+
- Replaced stray non-ASCII characters in docs
|
|
867
|
+
(those that survived from copy-paste rather than authored content).
|
|
706
868
|
- Started publishing CHANGELOGs and wired them into the Sphinx docs.
|
|
707
869
|
- Added a `pytest-timeout` dev dependency so hanging tests fail loudly.
|
|
708
|
-
- Added a mypy override for the `dd` BDD library so type-checking is
|
|
709
|
-
|
|
870
|
+
- Added a mypy override for the `dd` BDD library so type-checking is clean
|
|
871
|
+
for symbolic code.
|
|
710
872
|
|
|
711
873
|
## 1.0.2 — 2026-04-17
|
|
712
874
|
|
|
713
|
-
- Added `dd` as a dependency along with a small in-tree wrapper,
|
|
714
|
-
preparation for the BDD-backed symbolic layer.
|
|
715
|
-
- Fixed a queue ordering bug in `ltl_to_automaton`
|
|
716
|
-
incorrect successor expansions for some operator combinations.
|
|
717
|
-
- First pass at user-facing documentation
|
|
718
|
-
URLs) and at RST linting for the docs.
|
|
719
|
-
- Trimmed CI to a single type checker (`mypy`)
|
|
720
|
-
hiding missing-import errors.
|
|
875
|
+
- Added `dd` as a dependency along with a small in-tree wrapper,
|
|
876
|
+
in preparation for the BDD-backed symbolic layer.
|
|
877
|
+
- Fixed a queue ordering bug in `ltl_to_automaton`
|
|
878
|
+
that produced incorrect successor expansions for some operator combinations.
|
|
879
|
+
- First pass at user-facing documentation
|
|
880
|
+
(README, LICENSE, package URLs) and at RST linting for the docs.
|
|
881
|
+
- Trimmed CI to a single type checker (`mypy`)
|
|
882
|
+
and stopped silently hiding missing-import errors.
|
|
721
883
|
- Ported all operators to the current `algebraic` API.
|
|
722
884
|
This is source-incompatible with the previous internal `automatix` algebra module.
|
|
723
885
|
|
|
@@ -726,15 +888,15 @@ Documentation and tooling cleanup.
|
|
|
726
888
|
Initial wave of feature work that established the current shape of the library.
|
|
727
889
|
|
|
728
890
|
- Boolean polynomials implemented on top of BDDs.
|
|
729
|
-
- STREL: Lark-based parser for STREL expressions
|
|
730
|
-
alternating finite automata,
|
|
731
|
-
operators.
|
|
891
|
+
- STREL: Lark-based parser for STREL expressions
|
|
892
|
+
and a translation to alternating finite automata,
|
|
893
|
+
including the spatial Reach/Escape operators.
|
|
732
894
|
- LTL/LTLf to alternating Büchi / finite automata.
|
|
733
895
|
- Algebraic structures moved to the separate `algebraic` package.
|
|
734
|
-
- HOA parsing moved out into a dedicated `hoaparser` package
|
|
735
|
-
re-integrated as `morphata.hoa`).
|
|
736
|
-
- JAX and PyTorch made optional dependencies;
|
|
737
|
-
up automatically by `algebraic` when installed.
|
|
896
|
+
- HOA parsing moved out into a dedicated `hoaparser` package
|
|
897
|
+
(later re-integrated as `morphata.hoa`).
|
|
898
|
+
- JAX and PyTorch made optional dependencies;
|
|
899
|
+
both backends are picked up automatically by `algebraic` when installed.
|
|
738
900
|
- Test suite rebuilt against the new APIs.
|
|
739
901
|
|
|
740
902
|
## Pre-1.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: morphata
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.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
|
|
@@ -11,7 +11,7 @@ License-File: LICENSE
|
|
|
11
11
|
Classifier: Intended Audience :: Science/Research
|
|
12
12
|
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
13
13
|
Requires-Python: >=3.12
|
|
14
|
-
Requires-Dist: algebraic-arrays>=1.3.
|
|
14
|
+
Requires-Dist: algebraic-arrays>=1.3.10
|
|
15
15
|
Requires-Dist: attrs>=25.4.0
|
|
16
16
|
Requires-Dist: bitarray>=3.10.0
|
|
17
17
|
Requires-Dist: cattrs>=26.1.0
|
|
@@ -24,7 +24,8 @@ Requires-Dist: typing-extensions>=4.14
|
|
|
24
24
|
Provides-Extra: dot
|
|
25
25
|
Requires-Dist: pydot>=4.0.1; extra == 'dot'
|
|
26
26
|
Provides-Extra: jax
|
|
27
|
-
Requires-Dist:
|
|
27
|
+
Requires-Dist: flax; extra == 'jax'
|
|
28
|
+
Requires-Dist: jax<0.11.2,>=0.8; extra == 'jax'
|
|
28
29
|
Provides-Extra: torch
|
|
29
30
|
Requires-Dist: torch>=2.0; extra == 'torch'
|
|
30
31
|
Description-Content-Type: text/x-rst
|
|
@@ -20,6 +20,12 @@ To get pytest-benchmark's tabular wall-time output:
|
|
|
20
20
|
JAX-only scale cases are opt-in via
|
|
21
21
|
`MORPHATA_RUN_SCALE_BENCHMARKS=1`; run each scale case in a fresh process under
|
|
22
22
|
a hard memory limit.
|
|
23
|
+
- `test_transforms_perf.py` -- alternation removal and determinization over
|
|
24
|
+
single-root conjoined-eventuality and until-chain AFA families, plus composed
|
|
25
|
+
eventuality AFAs whose initial formulas have multiple state variables. The
|
|
26
|
+
composed cases compare the monolithic and opt-in factored-initial
|
|
27
|
+
constructions. Results are grouped by transform, construction, and formula
|
|
28
|
+
size. Regular cases stop at size 10.
|
|
23
29
|
- `test_sere_nlm_perf.py` -- NLM-intersection state-space blowup.
|
|
24
30
|
Cases: `NLMInter(a0..a_{n-1})` for n in 2..6, `NLMInter(a_i;b_i)`
|
|
25
31
|
for n in 2..4, plus length-matching `Inter` baselines.
|