Skip to content
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

Rework the architecture #27

Draft
wants to merge 48 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
2e141f8
add finite automaton word generation
bygu4 Sep 28, 2024
5a7119e
add final path existance checks
bygu4 Sep 28, 2024
2ddf4ad
set up CI for all branches, minor style changes
bygu4 Sep 29, 2024
001d7a9
add tests for word generation, debug
bygu4 Sep 29, 2024
a97e69f
refactor
bygu4 Sep 29, 2024
660b8e9
make path check methods private, refactor, add type signatures
bygu4 Sep 30, 2024
7ca0408
import Tuple to debug
bygu4 Sep 30, 2024
d4e7a2f
add tests for transitions iteration
bygu4 Oct 2, 2024
76d5b75
update CI
bygu4 Oct 4, 2024
176a609
Merge pull request #3 from FormalLanguageConstrainedPathQuerying/fa_s…
bygu4 Oct 11, 2024
d72eff8
add max word length specification, refactor, add cyclic enfa test
bygu4 Oct 16, 2024
f49ce75
rewrite the generator without networkx
bygu4 Oct 16, 2024
5406e6f
use deque collection
bygu4 Oct 19, 2024
ed3e418
generalize _get_reachable_states, correct max length specification
bygu4 Oct 21, 2024
0fe3d88
avoid epsilon cycles, add tests with epsilon cycles, add tests with m…
bygu4 Oct 21, 2024
2ae69a3
minor style changes
bygu4 Oct 21, 2024
82202da
correct cycle checks, use BFS in _get_reachable_states
bygu4 Oct 22, 2024
7a0d27f
Merge from origin, update tests
bygu4 Oct 22, 2024
deed143
update tests for word generator
bygu4 Oct 22, 2024
bd3daba
add checks for any duplicates, add test for duplicate generation
bygu4 Oct 24, 2024
bffade7
Merge pull request #11 from FormalLanguageConstrainedPathQuerying/fa_…
bygu4 Oct 26, 2024
ebf7101
add type annotations for finite_automaton module, refactor
bygu4 Oct 13, 2024
9c0512b
rename _start_state, correct start_state property
bygu4 Oct 14, 2024
95a93fd
rework transition function
bygu4 Nov 11, 2024
7e54208
change input types to Hashable, add utils.py
bygu4 Nov 11, 2024
85a06d1
remove to_deterministic, refactor
bygu4 Nov 11, 2024
5ee276d
add type annotations for regex
bygu4 Oct 14, 2024
5fdb201
add annotations for python_regex
bygu4 Oct 15, 2024
422e4b5
refactor regex
bygu4 Nov 11, 2024
61acee7
refactor to_regex, remove regexable
bygu4 Nov 11, 2024
c1d8f46
make finite_automaton.copy generic, move regex to minimal dfa to Rege…
bygu4 Nov 12, 2024
f0b0030
reimplement regexable methods for epsilon_nfa
bygu4 Nov 12, 2024
fab3a37
refactor tests for fa to regex transitions
bygu4 Nov 12, 2024
f17cf85
correct union of enfas, refactor
bygu4 Nov 13, 2024
2a7aaac
correct partition, debug regex
bygu4 Nov 13, 2024
cf3ec20
debug, refactor tests
bygu4 Nov 13, 2024
fafd489
try to fix typing issue in python_regex
bygu4 Nov 13, 2024
e4bf660
correct pda intersection, add more tests for union, concatenation and…
bygu4 Nov 13, 2024
33d0895
add from_networkx abstract method to fa, use update instead of union …
bygu4 Nov 14, 2024
38880e7
add recursive automaton annotations
bygu4 Oct 22, 2024
30d00d9
minor style changes in automata
bygu4 Nov 15, 2024
72cd938
refactor PreviousTransitions
bygu4 Nov 16, 2024
ac97aec
handle cycles in get_states_leading_to_final, add more tests
bygu4 Nov 25, 2024
0c9930d
Merge pull request #13 from FormalLanguageConstrainedPathQuerying/fa_…
bygu4 Nov 28, 2024
b83c71a
Merge branch 'master' of github.com:FormalLanguageConstrainedPathQuer…
bygu4 Nov 28, 2024
7fcec6c
Merge pull request #12 from FormalLanguageConstrainedPathQuerying/rew…
bygu4 Nov 28, 2024
b5a0735
remove fastcore import, update pyright config
bygu4 Dec 9, 2024
94af59a
correct generic type naming, simplify _to_epsilon_nfa_internal method
bygu4 Dec 29, 2024
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
Prev Previous commit
correct generic type naming, simplify _to_epsilon_nfa_internal method
  • Loading branch information
bygu4 committed Dec 29, 2024
commit 94af59ab2602e9618d83e33179175ac7bd61a37b
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
A deterministic transition function
"""

# pylint: disable=function-redefined

from typing import Optional

from .state import State
Expand Down
18 changes: 11 additions & 7 deletions pyformlang/finite_automaton/finite_automaton.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
""" A general finite automaton representation """

# pylint: disable=function-redefined

from typing import Dict, List, Set, Tuple, \
Iterable, Iterator, Optional, Hashable, Any, TypeVar
from abc import abstractmethod
Expand All @@ -17,7 +15,7 @@
from .transition_function import TransitionFunction
from .utils import to_state, to_symbol

fa_type = TypeVar("fa_type", bound="FiniteAutomaton")
AutomatonT = TypeVar("AutomatonT", bound="FiniteAutomaton")


class FiniteAutomaton(Iterable[Tuple[State, Symbol, State]]):
Expand All @@ -41,6 +39,7 @@ class FiniteAutomaton(Iterable[Tuple[State, Symbol, State]]):
A set of final or accepting states. It is a subset of states.
"""

@abstractmethod
def __init__(self) -> None:
self._states: Set[State]
self._input_symbols: Set[Symbol]
Expand Down Expand Up @@ -553,13 +552,18 @@ def write_as_dot(self, filename: str) -> None:
"""
write_dot(self.to_networkx(), filename)

@abstractmethod
def accepts(self, word: Iterable[Hashable]) -> bool:
""" Checks whether the finite automaton accepts a given word """
raise NotImplementedError

def get_accepted_words(self, max_length: Optional[int] = None) \
-> Iterable[List[Symbol]]:
"""
Gets words accepted by the finite automaton.
"""
if max_length is not None and max_length < 0:
return []
return
states_to_visit = deque((start_state, [])
for start_state in self.start_states)
states_leading_to_final = self._get_states_leading_to_final()
Expand Down Expand Up @@ -657,14 +661,14 @@ def to_dict(self) -> Dict[State, Dict[Symbol, Set[State]]]:
return self._transition_function.to_dict()

@abstractmethod
def copy(self: fa_type) -> fa_type:
def copy(self: AutomatonT) -> AutomatonT:
""" Copies the current Finite Automaton instance """
raise NotImplementedError

def __copy__(self: fa_type) -> fa_type:
def __copy__(self: AutomatonT) -> AutomatonT:
return self.copy()

def _copy_to(self, fa_to_copy_to: fa_type) -> fa_type:
def _copy_to(self, fa_to_copy_to: AutomatonT) -> AutomatonT:
""" Copies current automaton properties to the given one """
for start in self._start_states:
fa_to_copy_to.add_start_state(start)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
A nondeterministic transition function
"""

# pylint: disable=function-redefined

from typing import Dict, Set, Iterable, Tuple
from copy import deepcopy

Expand Down
2 changes: 0 additions & 2 deletions pyformlang/finite_automaton/transition_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
General transition function representation
"""

# pylint: disable=function-redefined

from typing import Dict, Set, Tuple, Iterable, Iterator
from abc import abstractmethod

Expand Down
18 changes: 7 additions & 11 deletions pyformlang/regular_expression/regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ class Regex(RegexReader):
"""

def __init__(self, regex: str) -> None:
self.sons: List[Regex] = [] # type: ignore
super().__init__(regex)
self.sons: List[Regex] # type: ignore
self._counter = 0
self._enfa: Optional[EpsilonNFA] = None

Expand Down Expand Up @@ -138,7 +138,7 @@ def get_number_operators(self) -> int:

def to_minimal_dfa(self) -> DeterministicFiniteAutomaton:
""" Builds minimal dfa from current regex """
enfa = self.to_epsilon_nfa()
enfa = self._to_epsilon_nfa_internal()
dfa = DeterministicFiniteAutomaton.from_epsilon_nfa(enfa)
return dfa.minimize()

Expand All @@ -157,19 +157,16 @@ def to_epsilon_nfa(self) -> EpsilonNFA:
>>> regex.to_epsilon_nfa()

"""
return self._to_epsilon_nfa_internal(True)
return self._to_epsilon_nfa_internal().copy()

def _to_epsilon_nfa_internal(self, copy: bool) -> EpsilonNFA:
"""
Transforms the regular expression into an epsilon NFA.
Copy enfa in case of external usage.
"""
def _to_epsilon_nfa_internal(self) -> EpsilonNFA:
""" Transforms the regular expression into an epsilon NFA """
if self._enfa is None:
self._enfa = EpsilonNFA()
s_initial = self._set_and_get_initial_state_in_enfa(self._enfa)
s_final = self._set_and_get_final_state_in_enfa(self._enfa)
self._process_to_enfa(self._enfa, s_initial, s_final)
return self._enfa.copy() if copy else self._enfa
return self._enfa

def _set_and_get_final_state_in_enfa(self, enfa: EpsilonNFA) -> State:
s_final = self._get_next_state_enfa()
Expand Down Expand Up @@ -567,8 +564,7 @@ def accepts(self, word: Iterable[str]) -> bool:
True

"""
self._enfa = self._to_epsilon_nfa_internal(False)
return self._enfa.accepts(word)
return self._to_epsilon_nfa_internal().accepts(word)

@classmethod
def from_finite_automaton(cls, automaton: FiniteAutomaton) -> "Regex":
Expand Down