Science Score: 54.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
✓CITATION.cff file
Found CITATION.cff file -
✓codemeta.json file
Found codemeta.json file -
✓.zenodo.json file
Found .zenodo.json file -
○DOI references
-
○Academic publication links
-
✓Committers with academic emails
1 of 3 committers (33.3%) from academic institutions -
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (13.5%) to scientific vocabulary
Keywords
Repository
A simple python implementation of a DFA.
Basic Info
Statistics
- Stars: 22
- Watchers: 2
- Forks: 3
- Open Issues: 2
- Releases: 0
Topics
Metadata Files
README.md
DFA
A simple python implementation of a DFA.
Table of Contents
Features:
- State can be any Hashable object.
- Alphabet can be any finite sequence of Hashable objects.
- Designed to be immutable and hashable (assuming components are immutable and hashable).
- Design choice to allow transition map and accepting set to be
given as functions rather than an explicit
dictorset.
Installation
If you just need to use dfa, you can just run:
$ pip install dfa
For developers, note that this project uses the poetry python package/dependency management tool. Please familarize yourself with it and then run:
$ poetry install
Usage
The dfa api is centered around the DFA object.
By default, the DFA object models a Deterministic Finite Acceptor,
e.g., a recognizer of a Regular Language.
Example Usage: ```python from dfa import DFA
dfa1 = DFA( start=0, inputs={0, 1}, label=lambda s: (s % 4) == 3, transition=lambda s, c: (s + c) % 4, )
dfa2 = DFA( start="left", inputs={"move right", "move left"}, label=lambda s: s == "left", transition=lambda s, c: "left" if c == "move left" else "right", ) ```
Membership Queries
```python assert dfa1.label([1, 1, 1, 1]) assert not dfa1.label([1, 0])
assert dfa2.label(["move right"]*100 + ["move left"]) assert not dfa2.label(["move left", "move right"]) ```
Transitions and Traces
python
assert dfa1.transition([1, 1, 1]) == 3
assert list(dfa1.trace([1, 1, 1])) == [0, 1, 2, 3]
Non-boolean output alphabets
Sometimes, it is useful to model an automata which can label a word
using a non-Boolean alphabet. For example, {True, False, UNSURE}.
The DFA object supports this by specifying the output alphabet.
```python UNSURE = None
def my_labeler(s): if s % 4 == 2: return None return (s % 4) == 3
dfa3 = DFA( start=0, inputs={0, 1}, label=my_labeler, transition=lambda s, c: (s + c) % 4, outputs={True, False, UNSURE}, ) ```
Note: If outputs is set to None, then no checks are done that
the outputs are within the output alphabet.
python
dfa3 = DFA(
start=0,
inputs={0, 1},
label=my_labeler,
transition=lambda s, c: (s + c) % 4,
outputs=None,
)
Moore Machines
Finally, by reinterpreting the structure of the DFA object, one can
model a Moore Machine. For example, in 3 state counter, dfa1, the
Moore Machine can output the current count.
python
assert dfa1.transduce(()) == ()
assert dfa1.transduce((1,)) == (False,)
assert dfa1.transduce((1, 1, 1, 1)) == (False, False, False, True)
Language Queries
Utility functions are available for testing if a language:
- Is empty:
utils.find_word - Is equivilent to another language:
utils.find_equiv_counterexample - Is a subset of a another language:
utils.find_subset_counterexample
These operate by returning None if the property holds, i.e.,
lang(dfa1) = ∅, lang(dfa1) ≡ lang(dfa2), lang(dfa1) ⊆ lang(dfa2), and
returning a counterexample Word otherwise.
DFA <-> Dictionary
Note that dfa provides helper functions for going from a dictionary
based representation of a deterministic transition system to a DFA
object and back.
```python from dfa import dfa2dict, dict2dfa
DFA encoded a nested dictionaries with the following
signature.
: (
dfa_dict = { 0: (False, {0: 0, 1: 1}), 1: (False, {0: 1, 1: 2}), 2: (False, {0: 2, 1: 3}), 3: (True, {0: 3, 1: 0}) }
Dictionary -> DFA
dfa = dict2dfa(dfa_dict, start=0)
DFA -> Dictionary
dfa_dict2, start = dfa2dict(dfa)
assert (dfadict, 0) == (dfadict2, start) ```
Computing Reachable States
```python
Perform a depth first traversal to collect all reachable states.
assert dfa1.states() == {0, 1, 2, 3} ```
Finding Words and Access strings
To generate accepting strings (words) in a DFA (breadth first using string length) one can use the dfa.utils.words function:
```python from dfa.utils.import dfa2dict, words, find_words
dfadict = { 0: (False, {0: 0, 1: 1}), 1: (False, {0: 1, 1: 2}), 2: (False, {0: 2, 1: 3}), 3: (True, {0: 3, 1: 0}) } lang = dict2dfa(dfadict, start=0)
xs = set(fn.take(5, words(lang))) assert len(xs) == 5 assert all(lang.label(x) for x in xs) ```
To get a single word, a helper function is provided in dfa.utils.find_word which returns None if the language of the DFA is empty:
```python
... Same as above ...
x = find_word(lang) assert x is not None assert lang.label(x) ```
Often times, it is useful to sample a path between two states, say a
and b. dfa supports this using dfa.utils.paths. This function
returns a generator of words, w, such that dfa.transition(w,
start=b) == a. For example:
```python from dfa.utils import paths
accessstrings = paths(
dfa1,
start=0,
end=1, # Optional. If not specified returns all paths
# starting at start.
maxlength=7, # Defaults to float('inf')
randomize=True, # Randomize the order. Shorter paths still found first.
)
for word in access_strings: assert dfa1.transition(word, start=0) == 1 ```
DFA minimization
DFAs can be minimized using the minimize method.
python
my_dfa = my_dfa.minimize()
DFA advancement (progression)
One can create the DFA starting at the state indexed by a given word by using
the advance method.
python
my_dfa = my_dfa.advance(word)
Running interactively (Co-Routine API)
dfa supports interactively stepping through a DFA object via
co-routines. This is particularly useful when using DFA in a control
loop. For example, the following code counts how many 1's it takes
to advance dfa1's state back to the start state.
```python
machine = dfa1.run()
next(machine) state = None
count = 0 while state != dfa1.start: count += 1 state = machine.send(1) ```
Visualizing DFAs
dfa optionally supports visualizing DFAs using graphviz. To use this
functionality be sure to install dfa using with the draw option:
python
pip install dfa[draw]
or
python
poetry install -E draw
Then one can simply use dfa.draw.write_dot to write a .dot file
representing the DFA. This .dot file can be rendered using any
graphviz supporting tool.
```python from dfa.draw import write_dot
write_dot(dfa1, "path/to/dfa1.dot") ```
Using the dot command in linux results in the following rendering of dfa1.
$ dot -Tsvg path/to/dfa1.dot > dfa1.svg
Owner
- Name: Marcell Vazquez-Chanlatte
- Login: mvcisback
- Kind: user
- Website: mjvc.me
- Repositories: 78
- Profile: https://github.com/mvcisback
Citation (CITATION.cff)
cff-version: 1.2.0 message: "If you use this software, please cite it as below." authors: - family-names: "Vazquez-Chanlatte" given-names: "Marcell" orcid: "https://orcid.org/0000-0002-1248-0000" - family-names: "Shah" given-names: "Ameesh" title: "dfa" version: 1 date-released: 2022-05-16 url: "https://github.com/mvcisback/dfa"
GitHub Events
Total
- Issues event: 1
- Watch event: 1
Last Year
- Issues event: 1
- Watch event: 1
Committers
Last synced: almost 3 years ago
All Time
- Total Commits: 126
- Total Committers: 3
- Avg Commits per committer: 42.0
- Development Distribution Score (DDS): 0.048
Top Committers
| Name | Commits | |
|---|---|---|
| Marcell Vazquez-Chanlatte | m****c@l****m | 120 |
| ameesh | a****7@r****u | 5 |
| Sebastian Junges | s****s@r****l | 1 |
Issues and Pull Requests
Last synced: 6 months ago
All Time
- Total issues: 5
- Total pull requests: 3
- Average time to close issues: about 1 month
- Average time to close pull requests: 4 days
- Total issue authors: 5
- Total pull request authors: 2
- Average comments per issue: 1.8
- Average comments per pull request: 1.0
- Merged pull requests: 3
- Bot issues: 0
- Bot pull requests: 0
Past Year
- Issues: 1
- Pull requests: 0
- Average time to close issues: N/A
- Average time to close pull requests: N/A
- Issue authors: 1
- Pull request authors: 0
- Average comments per issue: 0.0
- Average comments per pull request: 0
- Merged pull requests: 0
- Bot issues: 0
- Bot pull requests: 0
Top Authors
Issue Authors
- niklaslauffer (1)
- tomyaacov (1)
- ameesh-shah (1)
- sjunges (1)
- beyazit-y (1)
Pull Request Authors
- ameesh-shah (2)
- sjunges (1)
Top Labels
Issue Labels
Pull Request Labels
Packages
- Total packages: 1
-
Total downloads:
- pypi 2,333 last-month
- Total docker downloads: 52
- Total dependent packages: 6
- Total dependent repositories: 11
- Total versions: 51
- Total maintainers: 1
pypi.org: dfa
Python library for modeling DFAs, Moore Machines, and Transition Systems.
- Homepage: https://github.com/mvcisback/dfa
- Documentation: https://dfa.readthedocs.io/
- License: MIT
-
Latest release: 4.7.1
published almost 2 years ago
Rankings
Maintainers (1)
Dependencies
- attrs 23.2.0
- bidict 0.23.1
- bitarray 2.9.2
- colorama 0.4.6
- dill 0.3.8
- exceptiongroup 1.2.1
- funcy 2.0
- hypothesis 6.100.2
- iniconfig 2.0.0
- packaging 24.0
- pluggy 1.5.0
- pydot 1.4.2
- pyparsing 3.1.2
- pytest 7.4.4
- sortedcontainers 2.4.0
- tomli 2.0.1
- dill ^0.3.5 develop
- hypothesis ^6.56.4 develop
- pydot ^1.4 develop
- pytest ^7.2 develop
- attrs >=22
- bidict >=0.22
- bitarray ^2.4.0
- funcy >=1,<3
- pydot >=1.4
- python ^3.9