Skip to content

Added jupyter notebook integration and new visualization #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 99 commits into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
e1c2317
Added `get_state_name`
khoda81 Mar 17, 2023
7d657fc
Fixed reordering list and tuple
khoda81 Mar 17, 2023
128d38a
Added abstract methods for visualization
khoda81 Mar 17, 2023
ae0d996
Implemented graph visualization
khoda81 Mar 17, 2023
4ca7067
Fixed svg display bug
khoda81 Mar 17, 2023
ae19ccb
Removed IpythonGraph class
khoda81 Mar 17, 2023
86a8d8c
Fixed repr error for frozenset states
khoda81 Mar 17, 2023
f9e2295
Fixed `null_node` edge tooltip
khoda81 Mar 17, 2023
6deff5d
Removed unused imports
khoda81 Mar 21, 2023
3eed0e4
Added basic visualizations from Visual Automata
khoda81 Mar 26, 2023
b73ef8d
Replaced " with '
khoda81 Mar 31, 2023
6b91b7c
Sort dependencies in requirements.txt
caleb531 Apr 1, 2023
720b71b
Update remaining files to comply with flake8/black
caleb531 Apr 1, 2023
5dd6474
Using null set symbol for empty sets
khoda81 Apr 7, 2023
1f5bcd9
Added step visualization for DFA
khoda81 Apr 7, 2023
0a2a9f5
Fixed dfa step visualization label bug
khoda81 Apr 9, 2023
c7f283e
Improved coloring for step visualization
khoda81 Apr 10, 2023
9526482
Implemented step visualization for `NFA`
khoda81 Apr 12, 2023
df9f3e4
Final touches for rebasing
khoda81 Apr 12, 2023
a48ffef
Added `get_state_name`
khoda81 Mar 17, 2023
3ee49fb
Fixed reordering list and tuple
khoda81 Mar 17, 2023
fc6b09e
Added abstract methods for visualization
khoda81 Mar 17, 2023
5e55b99
Implemented graph visualization
khoda81 Mar 17, 2023
ad144a8
Removed IpythonGraph class
khoda81 Mar 17, 2023
878de2a
Fixed `null_node` edge tooltip
khoda81 Mar 17, 2023
051808f
Removed unused imports
khoda81 Mar 21, 2023
9b883fc
Added basic visualizations from Visual Automata
khoda81 Mar 26, 2023
a4ae8d8
Added step visualization for DFA
khoda81 Apr 7, 2023
fffa1fa
Implemented step visualization for `NFA`
khoda81 Apr 12, 2023
c3fc3b4
Added back frozendict as a dependency
khoda81 Apr 14, 2023
fd8e27e
Cleaned up api added for visualization
khoda81 Apr 15, 2023
c3e58be
Changed back to `AbstractSet`
khoda81 Apr 26, 2023
ec7a977
Merge branch 'develop' into jupyter-integration
eliotwrobson Apr 29, 2023
e41dbe5
Update automaton.py
eliotwrobson Apr 29, 2023
583424e
Merge branch 'jupyter-integration' of https://github.com/khoda81/auto…
eliotwrobson Apr 29, 2023
7cc87cb
Update automaton.py
eliotwrobson Apr 29, 2023
aab3eb5
More tests passing
eliotwrobson Apr 29, 2023
36083f2
Update fa.py
eliotwrobson Apr 29, 2023
957c2d9
Update gnfa.py
eliotwrobson Apr 29, 2023
7958451
Change some types
eliotwrobson Apr 29, 2023
e36d2c6
Type fixes
eliotwrobson Apr 29, 2023
55f8120
Update nfa.py
eliotwrobson Apr 29, 2023
8513a89
Simplify get edge name function
eliotwrobson Apr 29, 2023
fc7bee3
List functions
eliotwrobson Apr 29, 2023
55bd711
Put import behind check
eliotwrobson Apr 29, 2023
165d25b
Fixed some conflicting variable names
eliotwrobson Apr 29, 2023
b00470e
Update fa.py
eliotwrobson Apr 29, 2023
e52e2bd
Started switch to pygraphviz
eliotwrobson Apr 29, 2023
01a897e
Update requirements
eliotwrobson Apr 29, 2023
479bbd2
Update requirements.txt
eliotwrobson Apr 29, 2023
7b9def2
Update tests.yml
eliotwrobson Apr 29, 2023
b212b05
Modify tests
eliotwrobson Apr 29, 2023
9f1f8af
Typing fixes
eliotwrobson Apr 29, 2023
91b0af2
Update fa.py
eliotwrobson Apr 29, 2023
d0c6452
Cleaned up display logic
eliotwrobson May 12, 2023
a48387e
Type fix
eliotwrobson May 12, 2023
b7ffb65
Type fix
eliotwrobson May 12, 2023
d8dbcae
Update nfa.py
eliotwrobson May 12, 2023
37c5e6a
Removed caching because of mypy issues
eliotwrobson May 12, 2023
119e942
Fixed GNFA freezing
eliotwrobson May 12, 2023
abb13e3
import fix
eliotwrobson May 12, 2023
5c44c0e
Update gnfa.py
eliotwrobson May 12, 2023
854b753
Updated DFA display test
eliotwrobson May 12, 2023
c8f60c4
Updated DFA display tests
eliotwrobson May 12, 2023
820136f
mypy fix
eliotwrobson May 12, 2023
1987dbe
Update test_nfa.py
eliotwrobson May 12, 2023
954b57e
Commented out GNFA test to get coverage report
eliotwrobson May 12, 2023
2322f24
lint
eliotwrobson May 12, 2023
89656e2
Updated GNFA test cases
eliotwrobson May 13, 2023
a1cd413
Fix orientation
eliotwrobson May 13, 2023
15fad78
Update gnfa.py
eliotwrobson May 13, 2023
e0bbea0
Layout typing
eliotwrobson May 13, 2023
f8ed207
Rename variable
eliotwrobson May 13, 2023
103420d
Repr fixes and better state addition
eliotwrobson May 18, 2023
e3c0563
Fixed failing test
eliotwrobson May 18, 2023
45cc69a
Reverted repr friendly value change
eliotwrobson May 18, 2023
2cd52c2
Restore missing type annotation to _get_repr_friendly_value()
caleb531 May 19, 2023
0fdf3d0
Restore type annotation to __repr__
caleb531 May 19, 2023
b0ce2ad
changed config
eliotwrobson May 19, 2023
22317ac
Update pyproject.toml
eliotwrobson May 20, 2023
7cb48f5
Added test for edge coloring
eliotwrobson May 20, 2023
6f1ec9f
nfa diagram tests
eliotwrobson May 21, 2023
a8d8433
Replace @functools.cache with @functools.lru_cache
caleb531 May 21, 2023
10706a6
Rewrote broken algorithm and added test cases
eliotwrobson Jun 6, 2023
13aaf95
lint
eliotwrobson Jun 6, 2023
e7de250
Added epsilon loop test case
eliotwrobson Jun 6, 2023
9085f24
Made test case more interesting
eliotwrobson Jun 6, 2023
5db4922
Added some test cases
eliotwrobson Jun 6, 2023
e51692b
Lint and some silly tests
eliotwrobson Jun 6, 2023
95ede78
Update test_fa.py
eliotwrobson Jun 6, 2023
668e071
More test cases
eliotwrobson Jun 6, 2023
6c01021
Add orientation test
eliotwrobson Jun 6, 2023
a6fd789
Added more complex test cases
eliotwrobson Jun 6, 2023
201f5c6
Added optimality test
eliotwrobson Jun 6, 2023
7da1013
Added figure size tests
eliotwrobson Jun 6, 2023
fddf5e8
lint
eliotwrobson Jun 6, 2023
73cd3dc
Add missing PDA test
eliotwrobson Jun 6, 2023
993536b
Remove todos
eliotwrobson Jun 14, 2023
1bf1d74
Correct typo in NFA._get_input_path() docstring
caleb531 Jun 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions .coveragerc

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ jobs:
with:
python-version: "3.11"

- name: Install graphviz
run: sudo apt-get install graphviz
- name: Setup Graphviz
uses: ts-graphviz/setup-graphviz@v1

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
with:
python-version: ${{ matrix.python-version }}

- name: Install graphviz
run: sudo apt-get install graphviz
- name: Setup Graphviz
uses: ts-graphviz/setup-graphviz@v1

- name: Install dependencies
run: |
Expand Down
73 changes: 33 additions & 40 deletions automata/fa/dfa.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,15 @@
Iterable,
Iterator,
List,
Literal,
Mapping,
Optional,
Set,
Tuple,
Type,
TypeVar,
cast,
)

import networkx as nx
from pydot import Dot, Edge, Node
from typing_extensions import Self

import automata.base.exceptions as exceptions
Expand All @@ -50,7 +47,6 @@
class DFA(fa.FA):
"""A deterministic finite automaton."""

# TODO allow
__slots__ = (
"states",
"input_symbols",
Expand Down Expand Up @@ -332,7 +328,7 @@ def minify(self, retain_names: bool = False) -> Self:
Create a minimal DFA which accepts the same inputs as this DFA.

First, non-reachable states are removed.
Then, similiar states are merged using Hopcroft's Algorithm.
Then, similar states are merged using Hopcroft's Algorithm.
retain_names: If True, merged states retain names.
If False, new states will be named 0, ..., n-1.
"""
Expand Down Expand Up @@ -807,7 +803,7 @@ def predecessors(
*,
strict: bool = True,
key: Optional[Callable[[Any], Any]] = None,
) -> Iterable[str]:
) -> Generator[str, None, None]:
"""
Generates all strings that come before the input string
in lexicographical order.
Expand Down Expand Up @@ -845,7 +841,7 @@ def successors(
strict: bool = True,
key: Optional[Callable[[Any], Any]] = None,
reverse: bool = False,
) -> Iterable[str]:
) -> Generator[str, None, None]:
"""
Generates all strings that come after the input string in
lexicographical order. Passing in None will generate all words. If
Expand Down Expand Up @@ -906,7 +902,7 @@ def successors(
)
# Traverse to child if candidate is viable
if candidate_state in coaccessible_nodes:
state_stack.append(cast(str, candidate_state))
state_stack.append(candidate_state)
char_stack.append(cast(str, candidate))
candidate = first_symbol
else:
Expand Down Expand Up @@ -1553,38 +1549,35 @@ def get_name_original(states: FrozenSet[DFAStateT]) -> DFAStateT:
final_states=dfa_final_states,
)

def show_diagram(self, path=None):
def iter_transitions(
self,
) -> Generator[Tuple[DFAStateT, DFAStateT, str], None, None]:
return (
(from_, to_, symbol)
for from_, lookup in self.transitions.items()
for symbol, to_ in lookup.items()
)

def _get_input_path(
self, input_str
) -> Tuple[List[Tuple[DFAStateT, DFAStateT, DFASymbolT]], bool]:
"""
Creates the graph associated with this DFA
Calculate the path taken by input.

Args:
input_str (str): The input string to run on the DFA.

Returns:
tuple[list[tuple[DFAStateT, DFAStateT, DFASymbolT], bool]]: A list
of all transitions taken in each step and a boolean indicating
whether the DFA accepted the input.

"""
# Nodes are set of states

graph = Dot(graph_type="digraph", rankdir="LR")
nodes = {}
for state in self.states:
if state == self.initial_state:
# color start state with green
if state in self.final_states:
initial_state_node = Node(
state, style="filled", peripheries=2, fillcolor="#66cc33"
)
else:
initial_state_node = Node(
state, style="filled", fillcolor="#66cc33"
)
nodes[state] = initial_state_node
graph.add_node(initial_state_node)
else:
if state in self.final_states:
state_node = Node(state, peripheries=2)
else:
state_node = Node(state)
nodes[state] = state_node
graph.add_node(state_node)
# adding edges
for from_state, lookup in self.transitions.items():
for to_label, to_state in lookup.items():
graph.add_edge(Edge(nodes[from_state], nodes[to_state], label=to_label))
if path:
graph.write_png(path)
return graph
state_history = list(self.read_input_stepwise(input_str, ignore_rejection=True))
path = list(zip(state_history, state_history[1:], input_str))

last_state = state_history[-1] if state_history else self.initial_state
accepted = last_state in self.final_states

return path, accepted
Loading