morphata 2.3.0__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.3.1/.rstcheck.cfg +43 -0
- {morphata-2.3.0 → morphata-2.3.1}/AGENTS.md +7 -0
- {morphata-2.3.0 → morphata-2.3.1}/CHANGELOG.md +168 -93
- {morphata-2.3.0 → morphata-2.3.1}/PKG-INFO +1 -1
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/modules.rst +1 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.storage.rst +19 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.symbolic.rst +2 -0
- morphata-2.3.1/docs/api/morphata.utils.rst +61 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/acceptance.rst +2 -2
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/hoa.rst +3 -3
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/operators.rst +1 -1
- {morphata-2.3.0 → morphata-2.3.1}/docs/index.rst +3 -2
- {morphata-2.3.0 → morphata-2.3.1}/docs/quick-start.rst +2 -2
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/_version.py +2 -2
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/acceptance.py +1 -1
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/_common.py +5 -2
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/operators/_backend.py +1 -1
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/operators/matrix.py +1 -1
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/storage/__init__.py +7 -1
- morphata-2.3.1/src/morphata/storage/run.py +204 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/storage/signature.py +99 -26
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/symbolic/automaton.py +81 -9
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/symbolic/bdd.py +133 -67
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/symbolic/distance.py +85 -8
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/symbolic/transforms.py +117 -82
- 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/witness.py +139 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/test_exporter.py +100 -52
- morphata-2.3.1/tests/hoa/test_parser.py +118 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/logic/test_ltl.py +22 -20
- {morphata-2.3.0 → morphata-2.3.1}/tests/logic/test_sere.py +0 -30
- {morphata-2.3.0 → morphata-2.3.1}/tests/operators/test_matrix.py +31 -5
- {morphata-2.3.0 → morphata-2.3.1}/tests/operators/test_polynomial.py +9 -10
- {morphata-2.3.0 → morphata-2.3.1}/tests/storage/test_serialize.py +9 -4
- {morphata-2.3.0 → morphata-2.3.1}/tests/storage/test_signature.py +56 -2
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_bdd_helpers.py +4 -19
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_distance.py +140 -72
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_language_equivalence.py +146 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_ltlf2dfa_equivalence.py +19 -30
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_symbolic_automaton.py +1 -9
- {morphata-2.3.0 → morphata-2.3.1}/tests/test_alphabet.py +0 -25
- morphata-2.3.1/tests/utils/test_edit_distance.py +499 -0
- morphata-2.3.0/.agents/plans/2026-10-16-canonical-rfsa.md +0 -456
- morphata-2.3.0/.rstcheck.cfg +0 -13
- morphata-2.3.0/src/morphata/utils/__init__.py +0 -9
- morphata-2.3.0/tests/hoa/test_parser.py +0 -62
- {morphata-2.3.0 → morphata-2.3.1}/.basedpyright/baseline.json +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.dockerignore +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.editorconfig +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.envrc +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.envrc.recommended +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.fdignore +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.gitattributes +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.gitignore +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.mailmap +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/.python-version +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/CLAUDE.md +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/CONTRIBUTING.md +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/LICENSE +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/README.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/README.md +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/conftest.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_distance_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_equivalence_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_hoa_exporter_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_hoa_parser_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_matrix_operator_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_sere_nlm_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/bench/test_transforms_perf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/ci/make-release +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/Makefile +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/_static/navigation.html +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.acc_expr.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.acceptance.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.alphabet.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.builder.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.hoa.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.logic.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/api/morphata.operators.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/bibliography.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/changelog.md +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/index.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/symbolic.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/concepts/weights.rst +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/conf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/docs/refs.bib +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/justfile +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/mypy.ini +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/pixi.lock +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/project.utf-8.add +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/project.utf-8.add.spl +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/pyproject.toml +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/pyrightconfig.json +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/pytest.toml +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/rules/no-derivative-multiarg.yml +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/rules/no-typing-as-ty.yml +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/sgconfig.yml +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/acc_expr.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/alphabet.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/builder.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/hoa/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/hoa/__main__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/hoa/hoa.lark +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/hoa/parser.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/__init__.pyi +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/ltl.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/psl.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/logic/sere.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/operators/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/operators/jax.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/operators/polynomial.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/py.typed +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/storage/serialize.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/symbolic/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/utils/expressions.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/utils/memory.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/src/morphata/utils/sampling.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/conftest.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut1.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut11.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut2.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut3.2.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut3.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut4.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut5.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut6.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut7.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/aut8.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/finite_aut.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/gen_buchi_3.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/gen_cobuchi_2.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/rabin_2pair.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/hoa/streett_2pair.hoa +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/logic/__init__.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/logic/test_psl.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/operators/test_jax.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/operators/test_reductions.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_compose.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_from_hoaf.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_rfsa.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_to_hoa.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/symbolic/test_transforms.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/test_acceptance_validation.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/tests/test_builder.py +0 -0
- {morphata-2.3.0 → morphata-2.3.1}/uv.lock +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
|
|
@@ -46,6 +46,13 @@ Just invoke the tool.
|
|
|
46
46
|
If a tool is missing, stop and tell the user rather than trying to bootstrap
|
|
47
47
|
or reinstall the environment.
|
|
48
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
|
+
|
|
49
56
|
## Documentation
|
|
50
57
|
|
|
51
58
|
Use NumPy/numpydoc-style sections for Python docstrings. Use RST math markup
|
|
@@ -1,5 +1,71 @@
|
|
|
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
|
+
|
|
3
69
|
## 2.3.0 — 2026-10-21
|
|
4
70
|
|
|
5
71
|
This is *another* hefty release,
|
|
@@ -16,9 +82,9 @@ which has allowed me to harden `morphata` and also add a bunch of relevant featu
|
|
|
16
82
|
exploration and language reversal, without building the full DFA.
|
|
17
83
|
Follows the same API as the other transformers.
|
|
18
84
|
|
|
19
|
-
- `SymbolicAutomaton` now has helpers for determining if its language is empty,
|
|
20
|
-
it contains the language of another automaton,
|
|
21
|
-
(for nondeterministic automata only).
|
|
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).
|
|
22
88
|
|
|
23
89
|
- `JaxBatchedMatrixOperator` runs batches of integer-encoded words over dense matrix
|
|
24
90
|
operators using JAX's `lax.scan`.
|
|
@@ -64,13 +130,14 @@ which has allowed me to harden `morphata` and also add a bunch of relevant featu
|
|
|
64
130
|
The JSON helpers remain for string predicates.
|
|
65
131
|
|
|
66
132
|
- Custom alphabet domain callbacks now need to accept `care_vars`.
|
|
67
|
-
`BooleanAlphabet.intersect_with_domain` uses this to constrain guards using only
|
|
68
|
-
|
|
133
|
+
`BooleanAlphabet.intersect_with_domain` uses this to constrain guards using only the
|
|
134
|
+
predicates those guards actually mention.
|
|
69
135
|
|
|
70
136
|
### Fixed
|
|
71
137
|
|
|
72
|
-
- DFA minimization now compares guards on the full alphabet domain,
|
|
73
|
-
that differ only on impossible predicate valuations do not split equivalent
|
|
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.
|
|
74
141
|
|
|
75
142
|
- Symbolic transformations reuse alphabet domains within each construction stage.
|
|
76
143
|
Dealternation, determinization,
|
|
@@ -144,8 +211,8 @@ so I will just be making this a patch release
|
|
|
144
211
|
which keeps finite-alphabet guards compact without changing their meaning.
|
|
145
212
|
|
|
146
213
|
- Symbolic automaton transformations accept an optional initial state formula,
|
|
147
|
-
allowing a transformation to start from a formula other than the automaton's
|
|
148
|
-
|
|
214
|
+
allowing a transformation to start from a formula other than the automaton's stored
|
|
215
|
+
initial condition without modifying the source automaton.
|
|
149
216
|
|
|
150
217
|
- `prune_unreachable`, which removes the states unreachable from an automaton's initial
|
|
151
218
|
states and, with `remove_sink_states=True`, the materialized sink states too (an
|
|
@@ -170,9 +237,9 @@ so I will just be making this a patch release
|
|
|
170
237
|
since the manager's variable levels are not stable under reordering.
|
|
171
238
|
The partition is recomputed on each call.
|
|
172
239
|
|
|
173
|
-
- A `make_sink_states` keyword on `remove_alternation`, `determinize`,
|
|
174
|
-
`minimize_dfa`, controlling whether constant `True`
|
|
175
|
-
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.
|
|
176
243
|
|
|
177
244
|
- A `reverse_language` utility that produces an automaton
|
|
178
245
|
that accepts the reversed language.
|
|
@@ -198,12 +265,12 @@ so I will just be making this a patch release
|
|
|
198
265
|
- Add a signed version of the Levenshtein distance between two nondeterministic finite
|
|
199
266
|
automata.
|
|
200
267
|
|
|
201
|
-
- `SemiringAlphabet` now has two optional fields
|
|
202
|
-
|
|
203
|
-
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.
|
|
204
271
|
|
|
205
|
-
- In addition, `BooleanAlphabet` now have a mandatory `domain` keyword argument
|
|
206
|
-
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.
|
|
207
274
|
|
|
208
275
|
- `morphata.storage` has means to store canonical representations (morphata-specific) of
|
|
209
276
|
`SymbolicAutomaton` to disk.
|
|
@@ -226,9 +293,11 @@ so I will just be making this a patch release
|
|
|
226
293
|
|
|
227
294
|
### Developer Experience
|
|
228
295
|
|
|
229
|
-
- The Pixi environments now describe CPU, CUDA 12,
|
|
230
|
-
|
|
231
|
-
|
|
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
|
|
232
301
|
for faster documentation tinkering.
|
|
233
302
|
|
|
234
303
|
### Fixed
|
|
@@ -298,9 +367,9 @@ and increase the surface area of properly typed code.
|
|
|
298
367
|
The variadic `compose_automata`, `is_language_equivalent`,
|
|
299
368
|
and `forward_bisim_reduction` helpers cover composition, equivalence checking,
|
|
300
369
|
and language-preserving quotienting without leaving the symbolic representation.
|
|
301
|
-
- Add a typed `BDDManager`/`Function` API and symbolic utilities
|
|
302
|
-
manager, reindexing or quotienting states, materializing sinks,
|
|
303
|
-
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.
|
|
304
373
|
- Support arbitrary HOA v1 acceptance expressions through `GenericCondition`,
|
|
305
374
|
in addition to the concrete finite, Büchi, co-Büchi, generalized Büchi/co-Büchi,
|
|
306
375
|
Rabin, and Streett conditions.
|
|
@@ -324,8 +393,9 @@ and increase the surface area of properly typed code.
|
|
|
324
393
|
use a Boolean state expression for an alternating conjunction.
|
|
325
394
|
The old `variant`/`DeltaKind` construction API is gone.
|
|
326
395
|
- Alphabets now separate symbol labeling from guard weighting.
|
|
327
|
-
`BooleanAlphabet.labeling` returns an `AP -> bool` mapping,
|
|
328
|
-
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`,
|
|
329
399
|
and `weighted_alphabet` are replaced by `BooleanAlphabet`, `SemiringAlphabet`,
|
|
330
400
|
`powerset_alphabet`, and `finite_alphabet`.
|
|
331
401
|
- `MatrixOperator` and `PolynomialOperator` are constructed with
|
|
@@ -341,12 +411,13 @@ and increase the surface area of properly typed code.
|
|
|
341
411
|
### Fixed
|
|
342
412
|
|
|
343
413
|
- Correct symbolic derivatives for negated variables and SERE nodes.
|
|
344
|
-
- Fix breadth-first traversal ordering, symbolic language equivalence,
|
|
345
|
-
partitioning when multiple guards have the same residual.
|
|
346
|
-
- Correct `step()` labeling and the structural checks for deterministic
|
|
347
|
-
forward-progressing automata.
|
|
348
|
-
- Make builders, HOA conversion,
|
|
349
|
-
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.
|
|
350
421
|
|
|
351
422
|
### Removed
|
|
352
423
|
|
|
@@ -355,9 +426,9 @@ and increase the surface area of properly typed code.
|
|
|
355
426
|
`symbolic.equivalence`, and `symbolic.compose` modules.
|
|
356
427
|
Their surviving operations now live on `SymbolicAutomaton` or in `morphata.symbolic`;
|
|
357
428
|
there is no replacement for STREL or BDD-JSON persistence in this release.
|
|
358
|
-
- Remove the specialized composition-map/transition-enumeration APIs
|
|
359
|
-
`prune`; use general symbolic composition and `forward_bisim_reduction`
|
|
360
|
-
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.
|
|
361
432
|
|
|
362
433
|
## 2.1.0 — 2026-06-11
|
|
363
434
|
|
|
@@ -409,9 +480,9 @@ and increase the surface area of properly typed code.
|
|
|
409
480
|
|
|
410
481
|
### Fixed
|
|
411
482
|
|
|
412
|
-
- Using `SymbolicAutomaton.to_bdd_json`
|
|
413
|
-
preserve the positive normal form of the
|
|
414
|
-
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.
|
|
415
486
|
|
|
416
487
|
### Performance
|
|
417
488
|
|
|
@@ -453,10 +524,9 @@ and increase the surface area of properly typed code.
|
|
|
453
524
|
but minimization can merge classes such
|
|
454
525
|
that a representative's per-factor successor lands on a non-representative tuple,
|
|
455
526
|
so the full surjection has to be there.
|
|
456
|
-
- `iter_composed_transitions` enumerates `(state, symbol, successor)`
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
`(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)`.
|
|
460
530
|
|
|
461
531
|
### Performance
|
|
462
532
|
|
|
@@ -469,23 +539,22 @@ and increase the surface area of properly typed code.
|
|
|
469
539
|
and per-class point dicts across same-support rows.
|
|
470
540
|
Conjunction-fold DFAs get 1.3-1.6x; `F a & F b & F c & F d` q1 went ~343us -> ~175us.
|
|
471
541
|
- `isomorphic` routes through a compact support-reduced fingerprint
|
|
472
|
-
and skips the broadcast expansion.
|
|
473
|
-
~333ms -> ~83ms.
|
|
542
|
+
and skips the broadcast expansion.
|
|
543
|
+
`|AP|=19` sparse case: ~333ms -> ~83ms.
|
|
474
544
|
|
|
475
545
|
### Changed
|
|
476
546
|
|
|
477
|
-
- `SymbolicAutomaton` carries a derived `ap_inverse: Mapping[str, AP]`
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
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.
|
|
482
551
|
|
|
483
552
|
## 2.0.7 — 2026-06-02
|
|
484
553
|
|
|
485
554
|
### Fixed
|
|
486
555
|
|
|
487
|
-
- The BDD JSON exporter in `dd.cudd` needed to be worked around because of a bug
|
|
488
|
-
`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.
|
|
489
558
|
|
|
490
559
|
## 2.0.6 — 2026-06-02
|
|
491
560
|
|
|
@@ -497,8 +566,9 @@ and increase the surface area of properly typed code.
|
|
|
497
566
|
|
|
498
567
|
### Added
|
|
499
568
|
|
|
500
|
-
- Added a free-floating function
|
|
501
|
-
|
|
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.
|
|
502
572
|
|
|
503
573
|
## 2.0.5 — 2026-06-01
|
|
504
574
|
|
|
@@ -552,8 +622,8 @@ smaller minimal DFAs, having a better composition operation benefits us.
|
|
|
552
622
|
and bounded `FusionRepeat` desugar through `logic_asts.spec.Expr.expand`.
|
|
553
623
|
Unbounded `FusionRepeat[:*i..]` deliberately raises `NotImplementedError` —
|
|
554
624
|
I don't have a clean expansion for it yet.
|
|
555
|
-
- Benchmarking script for SERE NLM intersection,
|
|
556
|
-
break the perf curve.
|
|
625
|
+
- Benchmarking script for SERE NLM intersection,
|
|
626
|
+
so I can see when I break the perf curve.
|
|
557
627
|
|
|
558
628
|
### Changed
|
|
559
629
|
|
|
@@ -564,8 +634,7 @@ smaller minimal DFAs, having a better composition operation benefits us.
|
|
|
564
634
|
|
|
565
635
|
### Miscellaneous
|
|
566
636
|
|
|
567
|
-
- The README is linked from `pyproject.toml`, so it actually shows up
|
|
568
|
-
on PyPI.
|
|
637
|
+
- The README is linked from `pyproject.toml`, so it actually shows up on PyPI.
|
|
569
638
|
|
|
570
639
|
## 2.0.1 — 2026-05-24
|
|
571
640
|
|
|
@@ -599,8 +668,9 @@ interest.
|
|
|
599
668
|
Two LTL helpers (`_aut_symbolic_expansion`, `_empty_trace_value`) were renamed to
|
|
600
669
|
`ltl_symbolic_expansion` / `ltl_empty_trace_value` so PSL can delegate to them for
|
|
601
670
|
pure-LTL subformulas.
|
|
602
|
-
- Moved off `uv` and onto Pixi.
|
|
603
|
-
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.
|
|
604
674
|
|
|
605
675
|
### Fixed
|
|
606
676
|
|
|
@@ -646,9 +716,8 @@ short-lived manager for these things.
|
|
|
646
716
|
- `psl_to_automaton` does not yet decompose LTL temporal operators
|
|
647
717
|
that wrap PSL closures at the top level (e.g. `Always(StrongClosure(r))`).
|
|
648
718
|
Lift the PSL fragment out of the surrounding LTL temporal operator before calling.
|
|
649
|
-
- The continuation of a `SuffixImpliesExist` / `SuffixImpliesUniv`
|
|
650
|
-
|
|
651
|
-
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`.
|
|
652
721
|
|
|
653
722
|
## 2.0.0 — 2026-05-23
|
|
654
723
|
|
|
@@ -711,9 +780,10 @@ which will be summarized below.
|
|
|
711
780
|
and `WeightedAlphabet.from_predicates(...)` folds per-AP predicates through the
|
|
712
781
|
semiring.
|
|
713
782
|
The reverse direction is deliberately omitted —
|
|
714
|
-
recovering Boolean semantics from arbitrary `V` needs an ordering and a cut
|
|
715
|
-
STL), and pretending otherwise would silently produce garbage.
|
|
716
|
-
- **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.
|
|
717
787
|
Add states, add transitions with a guard and a successor
|
|
718
788
|
(single state, set of states, or a raw `BoolExpr` for full alternation),
|
|
719
789
|
and `build()` cleans up by merging rows that share a successor.
|
|
@@ -741,9 +811,11 @@ which will be summarized below.
|
|
|
741
811
|
The BDD cofactor path works for any `BooleanAlphabet`,
|
|
742
812
|
so you can feed a `SymbolicAutomaton` over integers, graph nodes, whatever —
|
|
743
813
|
as long as you can write a labeling.
|
|
744
|
-
- **The AFA-to-min-DFA pipeline actually exists now.**
|
|
745
|
-
`
|
|
746
|
-
|
|
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.
|
|
747
819
|
`SymbolicAutomaton.to_min_dfa` chains the three.
|
|
748
820
|
Finite-word only for now; omega-regular determinisation is a different beast.
|
|
749
821
|
- **DFA equivalence checks.**
|
|
@@ -754,17 +826,19 @@ which will be summarized below.
|
|
|
754
826
|
|
|
755
827
|
### Operators
|
|
756
828
|
|
|
757
|
-
- **One per-step shape.**
|
|
829
|
+
- **One per-step shape.**
|
|
830
|
+
`SymbolicAutomaton`, `MatrixOperator`,
|
|
758
831
|
and `PolynomialOperator` all expose the same `step(current, symbol)` / `run(word)` /
|
|
759
832
|
`accepts(word)` shape.
|
|
760
833
|
Each binds its alphabet at construction
|
|
761
834
|
(matching how the semiring / algebra were already bound),
|
|
762
835
|
so the per-call API is monomorphic and `V` is pinned end-to-end.
|
|
763
836
|
Wanted symmetry between the layers; got it.
|
|
764
|
-
- **`PolynomialOperator` evaluates lazily.**
|
|
765
|
-
`alphabet.weight` on the fly,
|
|
766
|
-
|
|
767
|
-
|
|
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.
|
|
768
842
|
The AFA's row structure stays static
|
|
769
843
|
(good for JAX tracing), and the alphabet decides whether to memoise.
|
|
770
844
|
- **Polynomial performance.**
|
|
@@ -774,8 +848,9 @@ which will be summarized below.
|
|
|
774
848
|
|
|
775
849
|
### Tooling and Tests
|
|
776
850
|
|
|
777
|
-
- **Hand-written changelogs.**
|
|
778
|
-
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.
|
|
779
854
|
`ci/make-release` no longer touches `CHANGELOG.md` or tag messages.
|
|
780
855
|
Run `git cliff` separately if you want a draft to crib from.
|
|
781
856
|
- **Tests.**
|
|
@@ -788,23 +863,23 @@ which will be summarized below.
|
|
|
788
863
|
|
|
789
864
|
Documentation and tooling cleanup.
|
|
790
865
|
|
|
791
|
-
- Replaced stray non-ASCII characters in docs
|
|
792
|
-
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).
|
|
793
868
|
- Started publishing CHANGELOGs and wired them into the Sphinx docs.
|
|
794
869
|
- Added a `pytest-timeout` dev dependency so hanging tests fail loudly.
|
|
795
|
-
- Added a mypy override for the `dd` BDD library so type-checking is
|
|
796
|
-
|
|
870
|
+
- Added a mypy override for the `dd` BDD library so type-checking is clean
|
|
871
|
+
for symbolic code.
|
|
797
872
|
|
|
798
873
|
## 1.0.2 — 2026-04-17
|
|
799
874
|
|
|
800
|
-
- Added `dd` as a dependency along with a small in-tree wrapper,
|
|
801
|
-
preparation for the BDD-backed symbolic layer.
|
|
802
|
-
- Fixed a queue ordering bug in `ltl_to_automaton`
|
|
803
|
-
incorrect successor expansions for some operator combinations.
|
|
804
|
-
- First pass at user-facing documentation
|
|
805
|
-
URLs) and at RST linting for the docs.
|
|
806
|
-
- Trimmed CI to a single type checker (`mypy`)
|
|
807
|
-
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.
|
|
808
883
|
- Ported all operators to the current `algebraic` API.
|
|
809
884
|
This is source-incompatible with the previous internal `automatix` algebra module.
|
|
810
885
|
|
|
@@ -813,15 +888,15 @@ Documentation and tooling cleanup.
|
|
|
813
888
|
Initial wave of feature work that established the current shape of the library.
|
|
814
889
|
|
|
815
890
|
- Boolean polynomials implemented on top of BDDs.
|
|
816
|
-
- STREL: Lark-based parser for STREL expressions
|
|
817
|
-
alternating finite automata,
|
|
818
|
-
operators.
|
|
891
|
+
- STREL: Lark-based parser for STREL expressions
|
|
892
|
+
and a translation to alternating finite automata,
|
|
893
|
+
including the spatial Reach/Escape operators.
|
|
819
894
|
- LTL/LTLf to alternating Büchi / finite automata.
|
|
820
895
|
- Algebraic structures moved to the separate `algebraic` package.
|
|
821
|
-
- HOA parsing moved out into a dedicated `hoaparser` package
|
|
822
|
-
re-integrated as `morphata.hoa`).
|
|
823
|
-
- JAX and PyTorch made optional dependencies;
|
|
824
|
-
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.
|
|
825
900
|
- Test suite rebuilt against the new APIs.
|
|
826
901
|
|
|
827
902
|
## Pre-1.0
|
|
@@ -34,3 +34,22 @@ Persistent automata
|
|
|
34
34
|
.. autofunction:: morphata.storage.automaton_to_json
|
|
35
35
|
|
|
36
36
|
.. autofunction:: morphata.storage.automaton_from_json
|
|
37
|
+
|
|
38
|
+
Running persistent automata
|
|
39
|
+
---------------------------
|
|
40
|
+
|
|
41
|
+
These functions run a :class:`~morphata.storage.PersistentAutomaton` without a BDD
|
|
42
|
+
manager. A run configuration is a positive state formula in minimal form.
|
|
43
|
+
|
|
44
|
+
.. automodule:: morphata.storage.run
|
|
45
|
+
:no-members:
|
|
46
|
+
|
|
47
|
+
.. autofunction:: morphata.storage.minimal_state_sop
|
|
48
|
+
|
|
49
|
+
.. autofunction:: morphata.storage.step
|
|
50
|
+
|
|
51
|
+
.. autofunction:: morphata.storage.is_accepting
|
|
52
|
+
|
|
53
|
+
.. autofunction:: morphata.storage.run_semantics
|
|
54
|
+
|
|
55
|
+
.. autofunction:: morphata.storage.distinguishing_words
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
|
|
23
23
|
.. autofunction:: morphata.symbolic.language_separation_distance
|
|
24
24
|
|
|
25
|
+
.. autofunction:: morphata.symbolic.distance.dfa_from_symbolic_automaton
|
|
26
|
+
|
|
25
27
|
.. autoclass:: morphata.symbolic.MacroStateLimitError
|
|
26
28
|
|
|
27
29
|
.. autofunction:: morphata.symbolic.minimize_dfa
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
``morphata.utils``
|
|
2
|
+
==================
|
|
3
|
+
|
|
4
|
+
.. automodule:: morphata.utils
|
|
5
|
+
:no-members:
|
|
6
|
+
|
|
7
|
+
Distinguishing words
|
|
8
|
+
--------------------
|
|
9
|
+
|
|
10
|
+
.. automodule:: morphata.utils.witness
|
|
11
|
+
:no-members:
|
|
12
|
+
|
|
13
|
+
.. autoclass:: morphata.utils.RunSemantics
|
|
14
|
+
:members: initial, step, is_accepting
|
|
15
|
+
|
|
16
|
+
.. autofunction:: morphata.utils.distinguishing_words
|
|
17
|
+
|
|
18
|
+
Edit distances between DFAs
|
|
19
|
+
---------------------------
|
|
20
|
+
|
|
21
|
+
.. automodule:: morphata.utils.edit_distance
|
|
22
|
+
:no-members:
|
|
23
|
+
|
|
24
|
+
.. autoclass:: morphata.utils.DFATable
|
|
25
|
+
:members: initial, transitions, accepting
|
|
26
|
+
|
|
27
|
+
.. autofunction:: morphata.utils.dfa_unsigned_levenshtein_distance
|
|
28
|
+
|
|
29
|
+
.. autofunction:: morphata.utils.dfa_signed_levenshtein_distance
|
|
30
|
+
|
|
31
|
+
.. autofunction:: morphata.utils.dfa_language_separation_distance
|
|
32
|
+
|
|
33
|
+
.. autofunction:: morphata.utils.dfa_from_persistent
|
|
34
|
+
|
|
35
|
+
Sampling automata
|
|
36
|
+
-----------------
|
|
37
|
+
|
|
38
|
+
.. automodule:: morphata.utils.sampling
|
|
39
|
+
:no-members:
|
|
40
|
+
|
|
41
|
+
.. autofunction:: morphata.utils.sampling.random_dfa
|
|
42
|
+
|
|
43
|
+
.. autofunction:: morphata.utils.sampling.fresh_random_afa
|
|
44
|
+
|
|
45
|
+
.. autofunction:: morphata.utils.sampling.reverse_random_dfa
|
|
46
|
+
|
|
47
|
+
.. autofunction:: morphata.utils.sampling.kth_from_end
|
|
48
|
+
|
|
49
|
+
.. autofunction:: morphata.utils.sampling.modular_counters
|
|
50
|
+
|
|
51
|
+
.. autofunction:: morphata.utils.sampling.eventually_conjunction
|
|
52
|
+
|
|
53
|
+
.. autofunction:: morphata.utils.sampling.safety_conjunction
|
|
54
|
+
|
|
55
|
+
.. autofunction:: morphata.utils.sampling.locally_testable
|
|
56
|
+
|
|
57
|
+
.. autofunction:: morphata.utils.sampling.finite_trace_pattern
|
|
58
|
+
|
|
59
|
+
.. autofunction:: morphata.utils.sampling.mutate
|
|
60
|
+
|
|
61
|
+
.. autofunction:: morphata.utils.sampling.vary
|
|
@@ -2,11 +2,11 @@ Acceptance Conditions
|
|
|
2
2
|
=====================
|
|
3
3
|
|
|
4
4
|
An :class:`~morphata.acceptance.AcceptanceCondition` decides when a run
|
|
5
|
-
of an automaton is considered accepting. morphata supports both
|
|
5
|
+
of an automaton is considered accepting. ``morphata`` supports both
|
|
6
6
|
**finite-word** and **omega-regular** acceptance.
|
|
7
7
|
|
|
8
8
|
Omega-regular support is structural: conditions can be represented, imported,
|
|
9
|
-
exported, and complemented. morphata does not evaluate infinite runs.
|
|
9
|
+
exported, and complemented. ``morphata`` does not evaluate infinite runs.
|
|
10
10
|
:meth:`~morphata.symbolic.SymbolicAutomaton.accepts`, operators, language
|
|
11
11
|
equivalence, and current transforms implement finite-word semantics only.
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@ HOA Format
|
|
|
2
2
|
==========
|
|
3
3
|
|
|
4
4
|
The `Hanoi Omega-Automata (HOA) <https://adl.github.io/hoaf/>`_ format
|
|
5
|
-
is a standard text representation for omega-automata. morphata provides
|
|
5
|
+
is a standard text representation for omega-automata. ``morphata`` provides
|
|
6
6
|
a parser for HOA v1, extended with a ``Final(n)`` operator for
|
|
7
7
|
finite-word acceptance.
|
|
8
8
|
|
|
@@ -76,7 +76,7 @@ The ``Final(n)`` Extension
|
|
|
76
76
|
|
|
77
77
|
Standard HOA defines ``Inf(n)`` (visit set *n* infinitely often) and
|
|
78
78
|
``Fin(n)`` (visit set *n* finitely often) for omega-regular acceptance.
|
|
79
|
-
morphata adds ``Final(n)`` for finite-word automata:
|
|
79
|
+
``morphata`` adds ``Final(n)`` for finite-word automata:
|
|
80
80
|
|
|
81
81
|
- ``Final(n)``: accept if the run **ends in** a state marked with
|
|
82
82
|
acceptance set *n*.
|
|
@@ -122,7 +122,7 @@ This automaton accepts exactly the finite words that contain ``a``.
|
|
|
122
122
|
State-based acceptance only
|
|
123
123
|
---------------------------
|
|
124
124
|
|
|
125
|
-
morphata reads only state-based acceptance markers (``{n}`` attached
|
|
125
|
+
``morphata`` reads only state-based acceptance markers (``{n}`` attached
|
|
126
126
|
to ``State:`` declarations). Per-edge ``{n}`` markers in transition
|
|
127
127
|
lines are ignored. Convert transition-based HOA files to state-based
|
|
128
128
|
form before loading them.
|