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 all commits
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
8 changes: 2 additions & 6 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@

name: Python package

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
on: [push, pull_request]

jobs:
build:
Expand Down Expand Up @@ -51,7 +47,7 @@ jobs:
junitxml-path: ./pytest.xml
default-branch: master
- name: Create coverage Badge
if: ${{ matrix.python-version == '3.8'}}
if: ${{ github.ref_name == 'master' && matrix.python-version == '3.8'}}
uses: schneegans/[email protected]
with:
auth: ${{ secrets.GIST_SECRET }}
Expand Down
30 changes: 13 additions & 17 deletions pyformlang/cfg/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

# pylint: disable=cyclic-import
from pyformlang import pda
from pyformlang.finite_automaton import FiniteAutomaton
from pyformlang.finite_automaton import DeterministicFiniteAutomaton
# pylint: disable=cyclic-import
from pyformlang.pda import cfg_variable_converter as cvc
from pyformlang import regular_expression
from .cfg_object import CFGObject
# pylint: disable=cyclic-import
from .cyk_table import CYKTable, DerivationDoesNotExist
Expand Down Expand Up @@ -788,7 +787,7 @@ def to_pda(self) -> "pda.PDA":
state, [])
return new_pda

def intersection(self, other: Any) -> "CFG":
def intersection(self, other: DeterministicFiniteAutomaton) -> "CFG":
""" Gives the intersection of the current CFG with an other object

Equivalent to:
Expand All @@ -810,13 +809,6 @@ def intersection(self, other: Any) -> "CFG":
When trying to intersect with something else than a regex or a
finite automaton
"""
if isinstance(other, regular_expression.Regex):
other = other.to_epsilon_nfa().to_deterministic()
elif isinstance(other, FiniteAutomaton):
if not other.is_deterministic():
other = other.to_deterministic()
else:
raise NotImplementedError
if other.is_empty():
return CFG()
generate_empty = self.contains([]) and other.accepts([])
Expand Down Expand Up @@ -845,10 +837,12 @@ def intersection(self, other: Any) -> "CFG":
return res_cfg

@staticmethod
def _intersection_starting_rules(cfg, other, cv_converter):
def _intersection_starting_rules(cfg: "CFG",
other: DeterministicFiniteAutomaton,
cv_converter):
start = Variable("Start")
productions_temp = []
start_other = list(other.start_states)[0] # it is deterministic
start_other = other.start_state
for final_state in other.final_states:
new_body = [
cv_converter.to_cfg_combined_variable(
Expand All @@ -860,15 +854,17 @@ def _intersection_starting_rules(cfg, other, cv_converter):
return productions_temp

@staticmethod
def _intersection_when_terminal(other_fst, production,
def _intersection_when_terminal(other: DeterministicFiniteAutomaton,
production,
cv_converter, states):
productions_temp = []
for state_p in states:
next_states = other_fst(state_p, production.body[0].value)
if next_states:
next_state = other.get_next_state(
state_p, production.body[0].value)
if next_state:
new_head = \
cv_converter.to_cfg_combined_variable(
state_p, production.head, next_states[0])
state_p, production.head, next_state)
productions_temp.append(
Production(new_head,
[production.body[0]],
Expand Down Expand Up @@ -904,7 +900,7 @@ def _get_all_bodies(production, state_p, state_r, states, cv_converter):
state_r)]
for state_q in states]

def __and__(self, other):
def __and__(self, other: DeterministicFiniteAutomaton) -> "CFG":
""" Gives the intersection of the current CFG with an other object

Parameters
Expand Down
7 changes: 4 additions & 3 deletions pyformlang/cfg/tests/test_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,8 @@ def test_finite(self):
def test_intersection(self):
""" Tests the intersection with a regex """
regex = Regex("a*b*")
dfa = regex.to_epsilon_nfa()
enfa = regex.to_epsilon_nfa()
dfa = DeterministicFiniteAutomaton.from_epsilon_nfa(enfa)
symb_a = Symbol("a")
symb_b = Symbol("b")
assert dfa.accepts([symb_a, symb_a, symb_b, symb_b])
Expand All @@ -530,7 +531,7 @@ def test_intersection(self):
cfg = CFG(productions=productions, start_symbol=var_s)
assert cfg.contains([ter_a, ter_a, ter_b, ter_b])
assert not cfg.contains([ter_a, ter_a, ter_b])
cfg_i = cfg.intersection(regex)
cfg_i = cfg.intersection(regex.to_minimal_dfa())
assert cfg_i.contains([ter_a, ter_a, ter_b, ter_b])
assert not cfg_i.contains([ter_a, ter_a, ter_b])
assert cfg_i.contains([])
Expand All @@ -548,7 +549,7 @@ def test_intersection_empty(self):
Production(var_s, [ter_b, var_s, ter_a]),
Production(var_s, [])}
cfg = CFG(productions=productions, start_symbol=var_s)
cfg_i = cfg & regex
cfg_i = cfg & regex.to_minimal_dfa()
assert not cfg_i

def test_intersection_dfa(self):
Expand Down
2 changes: 1 addition & 1 deletion pyformlang/cfg/tests/test_llone_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def test_sentence_cfg(self):
N -> gorilla | sky | carrots
""")
regex = Regex("georges touches (a|an) (sky|gorilla) !")
cfg_inter = cfg.intersection(regex)
cfg_inter = cfg.intersection(regex.to_minimal_dfa())
assert not cfg_inter.is_empty()
assert cfg_inter.is_finite()
assert not cfg_inter.contains(["georges", "sees", "a", "gorilla", "."])
Expand Down
9 changes: 5 additions & 4 deletions pyformlang/finite_automaton/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@
from .state import State
from .symbol import Symbol
from .epsilon import Epsilon
from .transition_function import (TransitionFunction,
DuplicateTransitionError,
InvalidEpsilonTransition)
from .deterministic_transition_function import \
(DeterministicTransitionFunction,
DuplicateTransitionError,
InvalidEpsilonTransition)
from .nondeterministic_transition_function import \
NondeterministicTransitionFunction

Expand All @@ -54,7 +55,7 @@
"State",
"Symbol",
"Epsilon",
"TransitionFunction",
"DeterministicTransitionFunction",
"NondeterministicTransitionFunction",
"DuplicateTransitionError",
"InvalidEpsilonTransition"]
Loading