morphata 2.0.2__tar.gz → 2.0.3__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.2 → morphata-2.0.3}/.claude/settings.local.json +4 -1
- {morphata-2.0.2 → morphata-2.0.3}/AGENTS.md +160 -126
- {morphata-2.0.2 → morphata-2.0.3}/CHANGELOG.md +16 -0
- morphata-2.0.3/PKG-INFO +137 -0
- {morphata-2.0.2 → morphata-2.0.3}/pyproject.toml +2 -1
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/symbolic/__init__.py +3 -0
- morphata-2.0.3/src/morphata/symbolic/compose.py +363 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/symbolic/transforms.py +4 -4
- {morphata-2.0.2 → morphata-2.0.3}/tests/conftest.py +7 -0
- morphata-2.0.3/tests/symbolic/test_compose.py +335 -0
- {morphata-2.0.2 → morphata-2.0.3}/uv.lock +82 -20
- morphata-2.0.2/PKG-INFO +0 -29
- {morphata-2.0.2 → morphata-2.0.3}/.basedpyright/baseline.json +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.dockerignore +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.editorconfig +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.envrc +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.envrc.recommended +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.fdignore +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.gitattributes +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.gitignore +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.mailmap +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.python-version +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/.rstcheck.cfg +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/CLAUDE.md +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/CONTRIBUTING.md +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/LICENSE +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/README.md +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/bench/README.md +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/bench/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/bench/conftest.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/bench/test_sere_nlm_perf.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/ci/make-release +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/cliff.toml +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/_static/navigation.html +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/modules.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.acceptance.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.alphabet.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.automaton.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.builder.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.hoa.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.logic.ltl.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.logic.psl.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.logic.sere.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.logic.strel.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.operators.matrix.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.operators.polynomial.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.operators.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/api/morphata.symbolic.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/acceptance.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/hoa.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/index.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/operators.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/spec.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/concepts/weights.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/conf.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/index.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/quick-start.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/docs/symbolic-transforms.rst +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/justfile +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/mypy.ini +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/pixi.lock +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/pixi.toml +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/project.utf-8.add +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/project.utf-8.add.spl +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/pyrefly.toml +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/pyrightconfig.json +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/pytest.toml +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/ruff.toml +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/acceptance.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/alphabet.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/automaton.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/builder.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/__main__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/acc_expr.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/exporter.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/hoa.lark +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/hoa/parser.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/_common.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/ltl.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/psl.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/sere.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/logic/strel.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/operators/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/operators/_backend.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/operators/matrix.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/operators/polynomial.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/py.typed +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/symbolic/automaton.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/symbolic/bdd.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/src/morphata/symbolic/equivalence.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut1.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut11.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut2.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut3.2.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut3.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut4.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut5.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut6.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut7.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/aut8.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/finite_aut.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/gen_buchi_3.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/gen_cobuchi_2.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/rabin_2pair.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/streett_2pair.hoa +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/test_exporter_basic.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/test_exporter_roundtrip.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/hoa/test_parser.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/__init__.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/test_ltl.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/test_psl.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/test_sere.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/test_sere_properties.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/logic/test_strel.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/operators/test_matrix_from_ir.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/operators/test_matrix_from_ltl.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/operators/test_polynomial_from_ir.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_bdd_helpers.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_from_hoaf.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_ltlf2dfa_equivalence.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_step.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_symbolic_automaton.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_symbolic_from_ir.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_transforms.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_transforms_ir.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/symbolic/test_transforms_properties.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/test_alphabet.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/test_automaton.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/test_builder.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/tests/test_from_parsed.py +0 -0
- {morphata-2.0.2 → morphata-2.0.3}/ty.toml +0 -0
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
"Skill(superpowers:requesting-code-review)",
|
|
24
24
|
"Bash(timeout 15 python -c ' *)",
|
|
25
25
|
"Read(//tmp/**)",
|
|
26
|
-
"Bash(echo \"exit: $?\")"
|
|
26
|
+
"Bash(echo \"exit: $?\")",
|
|
27
|
+
"Skill(superpowers:executing-plans)",
|
|
28
|
+
"Bash(ruff check *)",
|
|
29
|
+
"Bash(ruff format *)"
|
|
27
30
|
]
|
|
28
31
|
}
|
|
29
32
|
}
|
|
@@ -9,73 +9,81 @@ It packages structural automaton representations together with semiring-valued
|
|
|
9
9
|
The development shell already has the project virtual environment activated,
|
|
10
10
|
so `pytest`, `mypy`, `ruff`, `sphinx-build`, etc. are on `PATH` directly.
|
|
11
11
|
**Do not** prefix commands with `uv run`, `pixi run`, `poetry run`, or similar.
|
|
12
|
-
Just invoke the tool.
|
|
13
|
-
|
|
12
|
+
Just invoke the tool.
|
|
13
|
+
If a tool is missing, stop and tell the user rather than trying to bootstrap
|
|
14
|
+
or reinstall the environment.
|
|
14
15
|
|
|
15
16
|
## Core Architecture
|
|
16
17
|
|
|
17
|
-
### IR
|
|
18
|
+
### IR Layer (`morphata.automaton`, `morphata.alphabet`, `morphata.acceptance`)
|
|
18
19
|
|
|
19
20
|
**`morphata.automaton`** : the canonical automaton IR.
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
|
|
22
|
+
- `Automaton[State, Symbol, AP]` : the single automaton dataclass.
|
|
23
|
+
Fields: `states`, `predicates`, `initial: BoolExpr[State]`, `delta: Delta`,
|
|
22
24
|
`acceptance: AcceptanceCondition[State]`, plus a derived ``variant``.
|
|
23
|
-
- `Outgoing[State, AP]` : canonical predicate-row delta.
|
|
25
|
+
- `Outgoing[State, AP]` : canonical predicate-row delta. ``fn(state)``
|
|
24
26
|
yields ``(guard: BoolExpr[AP], successor: BoolExpr[State])`` pairs.
|
|
25
|
-
- `Step[State, Symbol]` : escape-hatch delta for input-dependent state
|
|
26
|
-
|
|
27
|
+
- `Step[State, Symbol]` : escape-hatch delta for input-dependent state spaces.
|
|
28
|
+
``fn(state, symbol) -> BoolExpr[State]``.
|
|
29
|
+
Used by STREL.
|
|
27
30
|
Not symbolically liftable.
|
|
28
31
|
- `Delta` : union of ``Outgoing`` and ``Step``.
|
|
29
32
|
- `DeltaKind` : ``DETERMINISTIC``, ``NONDETERMINISTIC``, ``UNIVERSAL``,
|
|
30
33
|
``ALTERNATING``.
|
|
31
34
|
- `classify_delta(delta, states)` : classifies a delta into a
|
|
32
|
-
``DeltaKind``.
|
|
35
|
+
``DeltaKind``. ``Step`` always classifies as ``ALTERNATING``.
|
|
33
36
|
- `BoolExpr[Var]` : alias for ``logic_asts.base.BaseExpr[Var]``.
|
|
34
37
|
|
|
35
|
-
**`morphata.alphabet`** : input alphabet abstractions.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- `
|
|
41
|
-
``
|
|
42
|
-
|
|
43
|
-
``
|
|
44
|
-
|
|
45
|
-
``
|
|
46
|
-
|
|
38
|
+
**`morphata.alphabet`** : input alphabet abstractions.
|
|
39
|
+
Guards in the IR stay symbolic;
|
|
40
|
+
the alphabet bundles the symbol-side metadata with the function
|
|
41
|
+
that interprets a guard against a symbol.
|
|
42
|
+
|
|
43
|
+
- `Alphabet[Symbol, AP, V]` (``Protocol``) : the operator-facing contract.
|
|
44
|
+
Exposes ``predicates`` and ``weight(symbol, guard) -> V``.
|
|
45
|
+
- `BooleanAlphabet[Symbol, AP]` : carries a labeling ``L: Symbol -> AbstractSet[AP]``.
|
|
46
|
+
``weight`` evaluates the guard in Boolean semantics against the AP-truth set
|
|
47
|
+
``L(symbol)``.
|
|
48
|
+
Satisfies ``Alphabet[Symbol, AP, bool]``.
|
|
49
|
+
- `WeightedAlphabet[Symbol, AP, V]` : carries an arbitrary ``weight_fn:
|
|
50
|
+
(Symbol, BoolExpr[AP]) -> V``.
|
|
51
|
+
Satisfies ``Alphabet[Symbol, AP, V]``.
|
|
47
52
|
- Factories: ``powerset_alphabet(aps)`` (Sigma = 2^AP, identity
|
|
48
53
|
labeling), ``finite_alphabet(aps)`` (Sigma = AP, one-hot labeling),
|
|
49
54
|
``weighted_alphabet(weight_fn, *, predicates)``.
|
|
50
55
|
- ``WeightedAlphabet.from_boolean(boolean, semiring)`` lifts a Boolean
|
|
51
56
|
alphabet into ``V`` via evaluate-then-lift (the guard is evaluated in
|
|
52
57
|
``bool`` and the result is mapped to ``semiring.zero`` / ``one``).
|
|
53
|
-
- ``WeightedAlphabet.from_predicates
|
|
54
|
-
weight function from per-AP predicates over ``V``.
|
|
55
|
-
former ``morphata.weights`` module.
|
|
58
|
+
- ``WeightedAlphabet.from_predicates
|
|
59
|
+
(predicates, semiring)`` builds a weight function from per-AP predicates over ``V``.
|
|
60
|
+
Replaces the former ``morphata.weights`` module.
|
|
56
61
|
|
|
57
|
-
The reverse direction (``WeightedAlphabet -> BooleanAlphabet``) requires
|
|
58
|
-
|
|
59
|
-
and is deliberately not provided.
|
|
62
|
+
The reverse direction (``WeightedAlphabet -> BooleanAlphabet``) requires extra ordering
|
|
63
|
+
/ threshold structure (cf.
|
|
64
|
+
STL quantitative semantics) and is deliberately not provided.
|
|
60
65
|
|
|
61
|
-
**`morphata.acceptance`** :
|
|
62
|
-
used by the HOA parser
|
|
63
|
-
``Buchi``, ``CoBuchi``, ``GeneralizedBuchi``,
|
|
64
|
-
``Rabin``, ``Streett``,
|
|
65
|
-
|
|
66
|
+
**`morphata.acceptance`** :
|
|
67
|
+
expression-based acceptance conditions used by the HOA parser
|
|
68
|
+
and the rest of the stack - ``Finite``, ``Buchi``, ``CoBuchi``, ``GeneralizedBuchi``,
|
|
69
|
+
``GeneralizedCoBuchi``, ``Rabin``, ``Streett``,
|
|
70
|
+
plus a ``GenericCondition`` fallback for acceptance formulas
|
|
71
|
+
that do not match a named condition.
|
|
66
72
|
|
|
67
73
|
**`morphata.hoa`** : Hanoi Omega-Automata v1 parser.
|
|
74
|
+
|
|
68
75
|
- ``parser.py`` : LALR-based parser; supports the ``Final(n)``
|
|
69
76
|
extension for finite-word acceptance.
|
|
70
77
|
- ``acc_expr.py`` : acceptance-formula AST shared with the parser.
|
|
71
78
|
- ``exporter.py`` : HOA v1 serializer; round-trips parser input via
|
|
72
79
|
``automaton_to_hoa``.
|
|
73
80
|
|
|
74
|
-
### Construction
|
|
81
|
+
### Construction Layer
|
|
82
|
+
|
|
83
|
+
**`morphata.builder.AutomatonBuilder[State, AP]`** :
|
|
84
|
+
the mutable builder that produces an ``Automaton`` IR on ``build()``.
|
|
85
|
+
Replaces the deleted ``morphata.constructions.nfa.NFA``.
|
|
75
86
|
|
|
76
|
-
**`morphata.builder.AutomatonBuilder[State, AP]`** : the mutable builder
|
|
77
|
-
that produces an ``Automaton`` IR on ``build()``. Replaces the deleted
|
|
78
|
-
``morphata.constructions.nfa.NFA``.
|
|
79
87
|
- ``add_state(state, *, initial=False, accepting=False)``.
|
|
80
88
|
- ``add_transition(src, guard, succ)`` where ``succ`` may be a single
|
|
81
89
|
state, a set of states (lifted to ``Or`` / ``And`` per variant), or a
|
|
@@ -88,35 +96,40 @@ LTL/LTLf -> alternating ``Automaton`` with an ``Outgoing`` delta.
|
|
|
88
96
|
``finite=True`` -> ``Finite`` acceptance; ``finite=False`` -> ``Buchi``.
|
|
89
97
|
|
|
90
98
|
**`morphata.logic.strel.strel_to_automata(expr, dist_attr, label_fn, ...)`** :
|
|
91
|
-
STREL over labelled graphs.
|
|
92
|
-
delta - the transition consumes the labelled
|
|
93
|
-
automata are not symbolically liftable.
|
|
94
|
-
Somewhere, Everywhere.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
``
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
99
|
+
STREL over labelled graphs.
|
|
100
|
+
Returns an ``Automaton`` with a ``Step`` delta - the transition consumes the labelled
|
|
101
|
+
graph eagerly, so STREL automata are not symbolically liftable.
|
|
102
|
+
Operators: Reach, Escape, Somewhere, Everywhere.
|
|
103
|
+
Boolean-only.
|
|
104
|
+
|
|
105
|
+
**`morphata.logic.sere.sere_to_automaton(expr)`** :
|
|
106
|
+
SERE -> alternating finite automaton.
|
|
107
|
+
Supports ``Concat``, ``Fusion``, ``Repeat``
|
|
108
|
+
(bounded and unbounded), ``Inter``, ``Alt``, and Boolean leaves over AP.
|
|
109
|
+
Acceptance is always ``Finite``;
|
|
110
|
+
the accepting-state set is exactly the *nullable* states
|
|
111
|
+
(those that match the empty word).
|
|
112
|
+
|
|
113
|
+
**`morphata.logic.psl.psl_to_automaton(phi, *, finite=False)`** :
|
|
114
|
+
PSL -> alternating automaton.
|
|
115
|
+
Wraps pure-LTL subformulas in an internal ``_LTL`` tag
|
|
116
|
+
and dispatches to the LTL expansion rule; closure operators (``{r}!
|
|
117
|
+
``, ``{r}``, ``!{r}``, ``{r}<>-> f``, ``{r}[]-> f``) become their own tagged states with
|
|
118
|
+
SERE-step expansion.
|
|
119
|
+
Suffix implications follow Spot's overlapping semantics:
|
|
120
|
+
the last symbol of ``r`` and the first position of ``f`` coincide.
|
|
121
|
+
``finite=True`` -> ``Finite`` acceptance (PSLf); ``finite=False`` -> ``Buchi``.
|
|
122
|
+
|
|
123
|
+
Hand-written automata are built with ``AutomatonBuilder``;
|
|
124
|
+
the package has no separate ``constructions`` namespace.
|
|
125
|
+
|
|
126
|
+
### Operator Layer (`morphata.operators`)
|
|
127
|
+
|
|
128
|
+
Algebraic morphisms that turn an ``Automaton`` plus an ``Alphabet`` into a computable
|
|
129
|
+
interpretation over an algebraic domain.
|
|
118
130
|
|
|
119
131
|
**`morphata.operators.matrix.MatrixOperator`** :
|
|
132
|
+
|
|
120
133
|
- Weighted finite-word NFA semantics as semiring matrix multiplication.
|
|
121
134
|
- Fields: ``initial_weights``, ``final_weights``, ``semiring``, an
|
|
122
135
|
``alphabet`` bound at construction, and a frozen ``(src, dst, guard)``
|
|
@@ -129,6 +142,7 @@ a computable interpretation over an algebraic domain.
|
|
|
129
142
|
- ``cost_transitions(x)`` returns an ``algebraic.AlgebraicArray``.
|
|
130
143
|
|
|
131
144
|
**`morphata.operators.polynomial.PolynomialOperator`** :
|
|
145
|
+
|
|
132
146
|
- Alternating finite automata as multilinear polynomials over a
|
|
133
147
|
bounded distributive lattice (typically Boolean).
|
|
134
148
|
- The alphabet is bound at construction. ``step(current, symbol)``
|
|
@@ -139,51 +153,64 @@ a computable interpretation over an algebraic domain.
|
|
|
139
153
|
``PolynomialOperator.from_ltl(formula, algebra, *, alphabet, finite=True, ...)``.
|
|
140
154
|
- Backed by ``algebraic.polynomials.RankDecomposition``.
|
|
141
155
|
|
|
142
|
-
**`morphata.operators._backend`** :
|
|
143
|
-
``_StaticAux`` JAX-pytree helper.
|
|
144
|
-
``AlgebraicArray`` or specified explicitly via ``backend=``.
|
|
156
|
+
**`morphata.operators._backend`** :
|
|
157
|
+
``resolve_backend(...)`` and the ``_StaticAux`` JAX-pytree helper.
|
|
158
|
+
Inferred from any provided ``AlgebraicArray`` or specified explicitly via ``backend=``.
|
|
145
159
|
|
|
146
|
-
### Symbolic
|
|
160
|
+
### Symbolic Layer (`morphata.symbolic`)
|
|
147
161
|
|
|
148
|
-
BDD-backed representation of an ``Automaton``.
|
|
149
|
-
layer: no target algebra, no semiring.
|
|
162
|
+
BDD-backed representation of an ``Automaton``.
|
|
163
|
+
Structural / runtime layer: no target algebra, no semiring.
|
|
150
164
|
|
|
151
|
-
**`morphata.symbolic.bdd`** :
|
|
152
|
-
``dd`` BDD package.
|
|
153
|
-
``
|
|
154
|
-
``boolexpr_to_bdd
|
|
155
|
-
``bdd_to_boolexpr(node) -> BoolExpr[int]``.
|
|
156
|
-
``morphata`` imports ``dd`` directly.
|
|
165
|
+
**`morphata.symbolic.bdd`** :
|
|
166
|
+
thin bridge between ``BoolExpr`` and the ``dd`` BDD package.
|
|
167
|
+
Exports ``make_manager(reordering=True)``, ``declare_state_vars``, ``state_var_name``,
|
|
168
|
+
``STATE_VAR_FORMAT``, ``boolexpr_to_bdd
|
|
169
|
+
(expr, mgr, num_vars) -> dd.Function``, ``bdd_to_boolexpr(node) -> BoolExpr[int]``.
|
|
170
|
+
Nothing else in ``morphata`` imports ``dd`` directly.
|
|
157
171
|
|
|
158
172
|
**`morphata.symbolic.automaton.SymbolicAutomaton`** :
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
|
|
174
|
+
- Wraps an ``Automaton`` so the initial-state set
|
|
175
|
+
and every cached transition are live ``dd.Function`` nodes in a single ``dd.BDD``
|
|
176
|
+
manager.
|
|
177
|
+
Acceptance is stored as given; only ``accepts(word)`` requires ``Finite`` acceptance.
|
|
163
178
|
- Requires ``aut.delta`` to be ``Outgoing``; ``Step`` deltas (STREL)
|
|
164
179
|
raise ``TypeError``.
|
|
165
|
-
- Constructor: ``SymbolicAutomaton.from_automaton
|
|
166
|
-
manager=None, reordering=True, cache_transitions=True,
|
|
180
|
+
- Constructor: ``SymbolicAutomaton.from_automaton
|
|
181
|
+
(aut, *, alphabet, manager=None, reordering=True, cache_transitions=True,
|
|
182
|
+
name_fn=None)``.
|
|
167
183
|
Convenience ``from_ltl`` / ``from_hoaf`` constructors compose with
|
|
168
|
-
``ltl_to_automaton`` and the HOA parser, and likewise require
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
``BooleanAlphabet``; the BDD cofactor path generalises to any
|
|
173
|
-
user-supplied labeling.
|
|
184
|
+
``ltl_to_automaton`` and the HOA parser, and likewise require ``alphabet=``.
|
|
185
|
+
- Per-step primitives: ``step(current, symbol)``, ``run(word)``, ``accepts(word)``.
|
|
186
|
+
The alphabet is bound at construction and must be a ``BooleanAlphabet``;
|
|
187
|
+
the BDD cofactor path generalises to any user-supplied labeling.
|
|
174
188
|
- State variables in the manager are always named ``q0..q{n-1}``;
|
|
175
189
|
callers who want their own variable names should apply ``mgr.let``
|
|
176
190
|
with an alias map.
|
|
177
191
|
|
|
178
|
-
**`morphata.symbolic.transforms`** :
|
|
179
|
-
over ``SymbolicAutomaton`` -- ``nfa_from_afa``
|
|
180
|
-
``determinize`` (subset construction with an explicit sink), and
|
|
181
|
-
``minimize`` (Hopcroft partition refinement).
|
|
182
|
-
``SymbolicAutomaton.to_min_dfa``.
|
|
183
|
-
|
|
184
|
-
**`morphata.symbolic.
|
|
185
|
-
|
|
186
|
-
``
|
|
192
|
+
**`morphata.symbolic.transforms`** :
|
|
193
|
+
BDD-level structural transforms over ``SymbolicAutomaton`` -- ``nfa_from_afa``
|
|
194
|
+
(dealternation), ``determinize`` (subset construction with an explicit sink), and
|
|
195
|
+
``minimize`` (Hopcroft partition refinement).
|
|
196
|
+
The three compose to ``SymbolicAutomaton.to_min_dfa``.
|
|
197
|
+
|
|
198
|
+
**`morphata.symbolic.compose`** :
|
|
199
|
+
compositional min-DFA construction on top of ``minimize``.
|
|
200
|
+
``compose_min_dfa(left, right, op)`` takes the product of two DFA-shaped
|
|
201
|
+
``SymbolicAutomaton`` instances over a shared manager and minimizes the result; ``op``
|
|
202
|
+
is ``"and"`` or ``"or"``.
|
|
203
|
+
``min_dfa_of_conjunction(formulas, *, alphabet)`` builds each conjunct's min-DFA over a
|
|
204
|
+
shared manager with a canonical AP ``name_fn`` derived from the alphabet's predicate
|
|
205
|
+
set, then folds them under ``compose_min_dfa(..., op="and")``.
|
|
206
|
+
For top-level LTLf conjunctions where each conjunct has a small min-DFA
|
|
207
|
+
but the monolithic AFA explodes under ``determinize``,
|
|
208
|
+
the layered path can be orders of magnitude faster.
|
|
209
|
+
|
|
210
|
+
**`morphata.symbolic.equivalence`** :
|
|
211
|
+
language-equivalence and isomorphism checks
|
|
212
|
+
for DFA-shaped symbolic automata -- ``language_equivalent``, ``canonical_form``,
|
|
213
|
+
``isomorphic``.
|
|
187
214
|
|
|
188
215
|
## Dependencies
|
|
189
216
|
|
|
@@ -194,18 +221,18 @@ isomorphism checks for DFA-shaped symbolic automata --
|
|
|
194
221
|
- Optional: `jax` (for the JAX backend), `torch` (for the PyTorch
|
|
195
222
|
backend), `pydot` (for `.dot` exports).
|
|
196
223
|
|
|
197
|
-
`morphata` operators that use `equinox` are JAX-flavoured;
|
|
198
|
-
is backend-agnostic via `backend=`.
|
|
224
|
+
`morphata` operators that use `equinox` are JAX-flavoured;
|
|
225
|
+
`algebraic` is backend-agnostic via `backend=`.
|
|
199
226
|
|
|
200
227
|
## Design Principles
|
|
201
228
|
|
|
202
|
-
1. **Single IR shape** : everything is a
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
2. **Alphabet-Carried Characteristic Function** : guards stay symbolic
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
for symbolic evaluation, semiring elements for weighted evaluation).
|
|
229
|
+
1. **Single IR shape** : everything is a ``morphata.automaton.Automaton``.
|
|
230
|
+
Variants (det / nondet / univ / alt) are derived from the rows,
|
|
231
|
+
not encoded in separate classes.
|
|
232
|
+
2. **Alphabet-Carried Characteristic Function** : guards stay symbolic in the IR.
|
|
233
|
+
``Alphabet.weight(symbol, guard)`` lifts a symbol against a guard.
|
|
234
|
+
Match the alphabet's ``V`` type to your consumer
|
|
235
|
+
(``bool`` for symbolic evaluation, semiring elements for weighted evaluation).
|
|
209
236
|
3. **Semiring-Agnostic Operators** : operator factories accept the
|
|
210
237
|
target algebra and the alphabet separately; the alphabet does not
|
|
211
238
|
know about the algebra.
|
|
@@ -221,31 +248,36 @@ is backend-agnostic via `backend=`.
|
|
|
221
248
|
|
|
222
249
|
## Usage Notes and Limitations
|
|
223
250
|
|
|
224
|
-
- STREL automata use a ``Step`` delta
|
|
225
|
-
|
|
226
|
-
|
|
251
|
+
- STREL automata use a ``Step`` delta
|
|
252
|
+
(the transition consumes the input graph eagerly),
|
|
253
|
+
so they cannot be lifted to ``SymbolicAutomaton``
|
|
254
|
+
and are not consumable by ``MatrixOperator`` / ``PolynomialOperator``.
|
|
227
255
|
STREL itself is Boolean-only.
|
|
228
|
-
- ``MatrixOperator`` targets finite-word acceptance;
|
|
229
|
-
acceptance is not implemented for it.
|
|
230
|
-
single ``Variable(dst)`` per row
|
|
256
|
+
- ``MatrixOperator`` targets finite-word acceptance;
|
|
257
|
+
omega-regular acceptance is not implemented for it.
|
|
258
|
+
Successor expressions must be single ``Variable(dst)`` per row
|
|
259
|
+
(no alternation / universal lifting).
|
|
231
260
|
- ``PolynomialOperator`` is tested with Boolean algebra; other semirings
|
|
232
261
|
may require additional validation.
|
|
233
|
-
- **State-based acceptance only.**
|
|
234
|
-
sets
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
262
|
+
- **State-based acceptance only.**
|
|
263
|
+
Acceptance sets are sets of states, not sets of transitions.
|
|
264
|
+
The HOA parser ingests ``{n}`` markers from ``State:`` declarations;
|
|
265
|
+
per-edge ``{n}`` markers are ignored.
|
|
266
|
+
Convert transition-based HOA files to state-based form before loading them.
|
|
267
|
+
- ``psl_to_automaton`` requires the continuation of any ``SuffixImpliesExist`` /
|
|
268
|
+
``SuffixImpliesUniv`` to be a pure-LTL formula in v1.
|
|
269
|
+
Nested PSL closures inside a suffix-implication continuation raise
|
|
270
|
+
``NotImplementedError``.
|
|
271
|
+
Likewise, LTL temporal operators wrapping a PSL closure at the top level
|
|
272
|
+
(e.g. ``Always(StrongClosure(r))``)
|
|
273
|
+
are not yet decomposed; lift the PSL fragment out of the LTL temporal operator
|
|
274
|
+
before calling.
|
|
244
275
|
- The PSL Buchi acceptance classification is the natural per-tag rule
|
|
245
|
-
(strong-closure non-accepting, weak-closure accepting, etc.).
|
|
246
|
-
not been cross-checked against a published reference
|
|
247
|
-
combination of operators;
|
|
248
|
-
|
|
276
|
+
(strong-closure non-accepting, weak-closure accepting, etc.).
|
|
277
|
+
It has not been cross-checked against a published reference
|
|
278
|
+
for every combination of operators;
|
|
279
|
+
consult ``docs/superpowers/specs/``
|
|
280
|
+
before relying on omega-language semantics in production.
|
|
249
281
|
|
|
250
282
|
## Testing
|
|
251
283
|
|
|
@@ -379,6 +411,8 @@ matrix_product = algebraic.matmul(arr1, arr2)
|
|
|
379
411
|
- `src/morphata/operators/polynomial.py` : ``PolynomialOperator``.
|
|
380
412
|
- `src/morphata/symbolic/automaton.py` : ``SymbolicAutomaton``.
|
|
381
413
|
- `src/morphata/symbolic/bdd.py` : ``BoolExpr`` / ``dd`` bridge.
|
|
414
|
+
- `src/morphata/symbolic/compose.py` : ``compose_min_dfa`` and
|
|
415
|
+
``min_dfa_of_conjunction``.
|
|
382
416
|
- `src/morphata/symbolic/transforms.py` : ``nfa_from_afa`` /
|
|
383
417
|
``determinize`` / ``minimize``.
|
|
384
418
|
- `src/morphata/symbolic/equivalence.py` : language equivalence and
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.3 — 2026-05-28
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
Added a new `morphata.symbolic.compose` API
|
|
8
|
+
that provides some helper functions to construct `SymbolicAutomaton` from composing two
|
|
9
|
+
minimal DFAs or to construct minimal DFAs from LTLf formula with a lot of overlapping
|
|
10
|
+
conjunctive clauses (essentially uses `compose_min_dfa`).
|
|
11
|
+
|
|
12
|
+
This helps fix some downstream issues where the AFA can have maybe 20 states
|
|
13
|
+
(like in Craftax tech trees),
|
|
14
|
+
but always using the `SymbolicAutomaton.to_min_dfa()` pipeline causes us to hit the
|
|
15
|
+
worst-case exponential blow up.
|
|
16
|
+
But, since these specifications have the structure of being conjunctive clauses of much
|
|
17
|
+
smaller minimal DFAs, having a better composition operation benefits us.
|
|
18
|
+
|
|
3
19
|
## 2.0.2 — 2026-05-27
|
|
4
20
|
|
|
5
21
|
### Added
|
morphata-2.0.3/PKG-INFO
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: morphata
|
|
3
|
+
Version: 2.0.3
|
|
4
|
+
Summary: Representation theory for automata, made practical.
|
|
5
|
+
Project-URL: Documentation, https://docs.anandb.dev/morphata
|
|
6
|
+
Project-URL: Repository, https://git.anandb.dev/morphata.git
|
|
7
|
+
Project-URL: Changelog, https://docs.anandb.dev/morphata/changelog.html
|
|
8
|
+
Author-email: Anand Balakrishnan <anandbala1597@gmail.com>
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
13
|
+
Requires-Python: >=3.12
|
|
14
|
+
Requires-Dist: algebraic-arrays>=1.3.0
|
|
15
|
+
Requires-Dist: attrs>=25.4.0
|
|
16
|
+
Requires-Dist: dd>=0.6.0
|
|
17
|
+
Requires-Dist: jaxtyping>=0.3
|
|
18
|
+
Requires-Dist: lark>=1.3.1
|
|
19
|
+
Requires-Dist: logic-asts>=1.6.2
|
|
20
|
+
Requires-Dist: networkx
|
|
21
|
+
Requires-Dist: numpy
|
|
22
|
+
Requires-Dist: types-networkx
|
|
23
|
+
Requires-Dist: typing-extensions
|
|
24
|
+
Provides-Extra: dot
|
|
25
|
+
Requires-Dist: pydot>=4.0.1; extra == 'dot'
|
|
26
|
+
Provides-Extra: jax
|
|
27
|
+
Requires-Dist: jax>=0.8; extra == 'jax'
|
|
28
|
+
Provides-Extra: torch
|
|
29
|
+
Requires-Dist: torch>=2.0; extra == 'torch'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# morphata
|
|
33
|
+
|
|
34
|
+
**morphata** does representation theory for automata, and makes it practical.
|
|
35
|
+
|
|
36
|
+
An automaton -- its states, transitions, and acceptance condition -- is a
|
|
37
|
+
*structural* object. *Operators* turn that structure into a quantitative
|
|
38
|
+
interpretation: a matrix-valued morphism over a semiring, a multilinear
|
|
39
|
+
polynomial over a bounded distributive lattice, or a BDD-canonicalised
|
|
40
|
+
symbolic representation. ``morphata`` packages both halves -- the structures
|
|
41
|
+
and the morphisms that interpret them -- in one library.
|
|
42
|
+
|
|
43
|
+
It builds on [`algebraic`](https://docs.anandb.dev/algebraic) for
|
|
44
|
+
backend-agnostic semiring algebra (NumPy, JAX, PyTorch).
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
47
|
+
|
|
48
|
+
### Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pip install morphata
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Basic Usage
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
import algebraic
|
|
58
|
+
import jax.numpy as jnp
|
|
59
|
+
from morphata.builder import AutomatonBuilder
|
|
60
|
+
from morphata.alphabet import weighted_alphabet
|
|
61
|
+
from morphata.operators.matrix import MatrixOperator
|
|
62
|
+
import logic_asts as logic
|
|
63
|
+
|
|
64
|
+
builder: AutomatonBuilder[int, str] = AutomatonBuilder()
|
|
65
|
+
builder.add_state(0, initial=True)
|
|
66
|
+
builder.add_state(1, accepting=True)
|
|
67
|
+
builder.add_transition(0, guard=logic.Variable("a"), succ=1)
|
|
68
|
+
aut = builder.build()
|
|
69
|
+
|
|
70
|
+
def xi(x, guard):
|
|
71
|
+
return float(x[0])
|
|
72
|
+
|
|
73
|
+
alphabet = weighted_alphabet(xi=xi)
|
|
74
|
+
maxplus = algebraic.semirings.tropical_semiring(minplus=False)
|
|
75
|
+
op = MatrixOperator.from_nfa(aut, semiring=maxplus, alphabet=alphabet)
|
|
76
|
+
|
|
77
|
+
x = jnp.array([2.0])
|
|
78
|
+
transitions = op.cost_transitions(x)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For more, see the [documentation](https://docs.anandb.dev/morphata).
|
|
82
|
+
|
|
83
|
+
## Citation
|
|
84
|
+
|
|
85
|
+
If you use the matrix operator or this package, please cite one of:
|
|
86
|
+
|
|
87
|
+
- For differentiable weighted automata in general:
|
|
88
|
+
|
|
89
|
+
```bibtex
|
|
90
|
+
@inproceedings{balakrishnan2024differentiable,
|
|
91
|
+
title = {Differentiable {{Weighted Automata}}},
|
|
92
|
+
booktitle = {{{ICML}} 2024 {{Workshop}} on {{Differentiable Almost Everything}}: {{Differentiable Relaxations}}, {{Algorithms}}, {{Operators}}, and {{Simulators}}},
|
|
93
|
+
author = {Balakrishnan, Anand and Deshmukh, Jyotirmoy V.},
|
|
94
|
+
year = 2024,
|
|
95
|
+
month = jun,
|
|
96
|
+
url = {https://openreview.net/forum?id=k2hIQYqHTh},
|
|
97
|
+
copyright = {All rights reserved},
|
|
98
|
+
langid = {english}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
- For weighted automata in motion planning:
|
|
103
|
+
|
|
104
|
+
```bibtex
|
|
105
|
+
@inproceedings{balakrishnan2024motion,
|
|
106
|
+
title = {Motion {{Planning}} for {{Automata-based Objectives}} Using {{Efficient Gradient-based Methods}}},
|
|
107
|
+
booktitle = {2024 {{IEEE}}/{{RSJ International Conference}} on {{Intelligent Robots}} and {{Systems}} ({{IROS}})},
|
|
108
|
+
author = {Balakrishnan, Anand and Atasever, Merve and Deshmukh, Jyotirmoy V.},
|
|
109
|
+
year = 2024,
|
|
110
|
+
month = oct,
|
|
111
|
+
pages = {13734--13740},
|
|
112
|
+
issn = {2153-0866},
|
|
113
|
+
doi = {10.1109/IROS58592.2024.10802177}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- For alternating weighted automata in multi-agent systems:
|
|
118
|
+
|
|
119
|
+
```bibtex
|
|
120
|
+
@inproceedings{balakrishnan2025monitoring,
|
|
121
|
+
title = {Monitoring {{Spatially Distributed Cyber-Physical Systems}} with {{Alternating Finite Automata}}},
|
|
122
|
+
booktitle = {Proceedings of the 28th {{ACM International Conference}} on {{Hybrid Systems}}: {{Computation}} and {{Control}}},
|
|
123
|
+
author = {Balakrishnan, Anand and Paul, Sheryl and Silvetti, Simone and Nenzi, Laura and Deshmukh, Jyotirmoy V.},
|
|
124
|
+
year = 2025,
|
|
125
|
+
month = may,
|
|
126
|
+
pages = {1--11},
|
|
127
|
+
publisher = {ACM},
|
|
128
|
+
address = {Irvine CA USA},
|
|
129
|
+
doi = {10.1145/3716863.3718033},
|
|
130
|
+
isbn = {979-8-4007-1504-4},
|
|
131
|
+
langid = {english}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## License
|
|
136
|
+
|
|
137
|
+
See LICENSE file for details.
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
name = "morphata"
|
|
3
3
|
authors = [{ name = "Anand Balakrishnan", email = "anandbala1597@gmail.com" }]
|
|
4
4
|
description = "Representation theory for automata, made practical."
|
|
5
|
-
version = "2.0.
|
|
5
|
+
version = "2.0.3"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
classifiers = [
|
|
8
8
|
"Intended Audience :: Science/Research",
|
|
9
9
|
"Topic :: Scientific/Engineering :: Mathematics",
|
|
10
10
|
]
|
|
11
11
|
license = "BSD-3-Clause"
|
|
12
|
+
readme = "README.md"
|
|
12
13
|
|
|
13
14
|
dependencies = [
|
|
14
15
|
"attrs>=25.4.0",
|
|
@@ -34,9 +34,12 @@ from morphata.symbolic.bdd import guard_to_bdd as guard_to_bdd
|
|
|
34
34
|
from morphata.symbolic.bdd import make_ap_registry as make_ap_registry
|
|
35
35
|
from morphata.symbolic.bdd import make_manager as make_manager
|
|
36
36
|
from morphata.symbolic.bdd import state_var_name as state_var_name
|
|
37
|
+
from morphata.symbolic.compose import compose_min_dfa as compose_min_dfa
|
|
38
|
+
from morphata.symbolic.compose import min_dfa_of_conjunction as min_dfa_of_conjunction
|
|
37
39
|
from morphata.symbolic.equivalence import canonical_form as canonical_form
|
|
38
40
|
from morphata.symbolic.equivalence import isomorphic as isomorphic
|
|
39
41
|
from morphata.symbolic.equivalence import language_equivalent as language_equivalent
|
|
40
42
|
from morphata.symbolic.transforms import determinize as determinize
|
|
43
|
+
from morphata.symbolic.transforms import extract_dfa_target as extract_dfa_target
|
|
41
44
|
from morphata.symbolic.transforms import minimize as minimize
|
|
42
45
|
from morphata.symbolic.transforms import nfa_from_afa as nfa_from_afa
|