From b5c340df082204edf2242dedc7c6c89f5377a04f Mon Sep 17 00:00:00 2001 From: heli0dus Date: Wed, 27 Mar 2024 23:13:58 +0300 Subject: [PATCH 1/9] task 6? (i guess) (probably not) (or is it?) (pls help) --- project/task6.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 project/task6.py diff --git a/project/task6.py b/project/task6.py new file mode 100644 index 000000000..25572263c --- /dev/null +++ b/project/task6.py @@ -0,0 +1,13 @@ +from pyformlang.cfg import CFG + + +def to_wnf(gramm: CFG) -> CFG: + gramm1 = gramm.eliminate_unit_productions().remove_useless_symbols() + long_rules = gramm1._get_productions_with_only_single_terminals() + new_rules = set(gramm1._decompose_productions(long_rules)) + return CFG(start_symbol=gramm1.start_symbol, production=new_rules) + + +def gramm_from_file(filepath: str) -> CFG: + with open(filepath) as f: + return CFG.from_text("".join(l for l in f)) \ No newline at end of file From ffcdab73aba1e1912a1daf7275f7d10d5421e608 Mon Sep 17 00:00:00 2001 From: heli0dus Date: Wed, 27 Mar 2024 23:15:41 +0300 Subject: [PATCH 2/9] style fixes --- project/task6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/task6.py b/project/task6.py index 25572263c..05c21202d 100644 --- a/project/task6.py +++ b/project/task6.py @@ -10,4 +10,4 @@ def to_wnf(gramm: CFG) -> CFG: def gramm_from_file(filepath: str) -> CFG: with open(filepath) as f: - return CFG.from_text("".join(l for l in f)) \ No newline at end of file + return CFG.from_text("".join(l for l in f)) From 902dfab0b8b6d201abfe8cb43c90e1bcadc5206b Mon Sep 17 00:00:00 2001 From: heli0dus Date: Wed, 17 Apr 2024 18:55:04 +0300 Subject: [PATCH 3/9] task6 stump --- project/task6.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/project/task6.py b/project/task6.py index 05c21202d..37398f786 100644 --- a/project/task6.py +++ b/project/task6.py @@ -1,8 +1,10 @@ from pyformlang.cfg import CFG +import pyformlang +import networkx as nx +from typing import Tuple - -def to_wnf(gramm: CFG) -> CFG: - gramm1 = gramm.eliminate_unit_productions().remove_useless_symbols() +def cfg_to_weak_normal_form(cfg: pyformlang.cfg.CFG) -> pyformlang.cfg.CFG: + gramm1 = cfg.eliminate_unit_productions().remove_useless_symbols() long_rules = gramm1._get_productions_with_only_single_terminals() new_rules = set(gramm1._decompose_productions(long_rules)) return CFG(start_symbol=gramm1.start_symbol, production=new_rules) @@ -11,3 +13,20 @@ def to_wnf(gramm: CFG) -> CFG: def gramm_from_file(filepath: str) -> CFG: with open(filepath) as f: return CFG.from_text("".join(l for l in f)) + +def cfpq_with_hellings( + cfg: pyformlang.cfg.CFG, + graph: nx.DiGraph, + start_nodes: set[int] = None, + final_nodes: set[int] = None, +) -> set[Tuple[int, int]]: + + if start_nodes is None: + start_nodes = graph.nodes + if final_nodes is None: + final_nodes = graph.nodes + + gramm = cfg_to_weak_normal_form(cfg) + p1 = {} + p2 = set() + p3 = {} \ No newline at end of file From 14806f9cf6bb030fc2c7588cee86ca52b48ae48f Mon Sep 17 00:00:00 2001 From: heli0dus Date: Thu, 25 Apr 2024 14:01:15 +0300 Subject: [PATCH 4/9] initial implementation (time for bug backtracking) --- project/task6.py | 78 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/project/task6.py b/project/task6.py index 37398f786..f62ddbcbc 100644 --- a/project/task6.py +++ b/project/task6.py @@ -1,32 +1,82 @@ -from pyformlang.cfg import CFG +from pyformlang.cfg import CFG, Variable, Terminal, Epsilon import pyformlang import networkx as nx from typing import Tuple + def cfg_to_weak_normal_form(cfg: pyformlang.cfg.CFG) -> pyformlang.cfg.CFG: gramm1 = cfg.eliminate_unit_productions().remove_useless_symbols() long_rules = gramm1._get_productions_with_only_single_terminals() new_rules = set(gramm1._decompose_productions(long_rules)) - return CFG(start_symbol=gramm1.start_symbol, production=new_rules) + return CFG(start_symbol=Variable("S"), productions=new_rules) def gramm_from_file(filepath: str) -> CFG: with open(filepath) as f: return CFG.from_text("".join(l for l in f)) + def cfpq_with_hellings( - cfg: pyformlang.cfg.CFG, - graph: nx.DiGraph, - start_nodes: set[int] = None, - final_nodes: set[int] = None, + cfg: pyformlang.cfg.CFG, + graph: nx.DiGraph, + start_nodes: set[int] = None, + final_nodes: set[int] = None, ) -> set[Tuple[int, int]]: - - if start_nodes is None: + + if start_nodes is None: start_nodes = graph.nodes - if final_nodes is None: - final_nodes = graph.nodes + if final_nodes is None: + final_nodes = graph.nodes + + gramm = cfg_to_weak_normal_form(cfg) + p1 = {} + p2 = set() + p3 = {} + + for p in gramm.productions: + p_len = p.body + if p_len == 1 and isinstance(p.body[0], Terminal): + p1.setdefault(p.head, set()).add(p.body[0]) + elif p_len == 1 and isinstance(p.body[0], Epsilon): + p2.add(p.body[0]) + elif p_len == 2: + p3.setdefault(p.head, set).add((p.body[0], p.body[1])) + + result = {(n, v, v) for n in p2 for v in graph.nodes} + increment = {} + i = 0 + for v, u, tag in graph.edges.data("label"): + for n in p1: + if tag in p1[n]: + increment[i] = (n, v, u) + i += 1 + result.union(increment) + + queue_to_process = result.copy() + + while len(queue_to_process) > 0: + n_i, vi, ui = queue_to_process.pop() + + step_increment = set() + + for n_j, vj, uj in result: + if vi == ui: + for n_k in p3: + if (n_j, n_i) in p3[n_k] and (n_k, vj, vi) not in result: + queue_to_process.add((n_k, vj, ui)) + step_increment.add((n_k, vj, ui)) + + for n_j, vj, uj in result: + if ui == vi: + for n_k in p3: + if (n_i, n_j) in p3[n_k] and (n_k, vi, ui) not in result: + queue_to_process.add((n_k, vi, uj)) + step_increment.add((n_k, vi, uj)) + + result.union(step_increment) - gramm = cfg_to_weak_normal_form(cfg) - p1 = {} - p2 = set() - p3 = {} \ No newline at end of file + return { + (u, v) + for (n_i, u, v) in result + if u in start_nodes and v in final_nodes and Variable(n_i) == cfg.start_symbol + } From 81477f7147af2c7eb1316ef8fd935e3835ce3e11 Mon Sep 17 00:00:00 2001 From: heli0dus Date: Fri, 10 May 2024 21:10:58 +0300 Subject: [PATCH 5/9] new local test --- tests/test_task6.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/test_task6.py diff --git a/tests/test_task6.py b/tests/test_task6.py new file mode 100644 index 000000000..5777f0786 --- /dev/null +++ b/tests/test_task6.py @@ -0,0 +1,28 @@ +import project.task4 as task4 +import project.task2 as task2 +import project.task3 as task3 +import project.task6 as task6 +from pyformlang import cfg +import networkx as nx + +def test_cfpq(): + gramm = cfg.CFG.from_text("S -> $ | a S") + regex_str = "a*" + + gr = nx.MultiDiGraph() + gr.add_edge(0, 1, label='a') + gr.add_edge(1, 2, label='b') + gr.add_edge(2, 0, label='a') + start_nodes = {0, 1, 2} + final_nodes = {0, 1} + + print(gramm) + print(task6.cfg_to_weak_normal_form(gramm)) + print() + print(task4.reachability_with_constraints( + task3.FiniteAutomaton(task2.graph_to_nfa(gr, start_nodes, final_nodes)), + task3.FiniteAutomaton(task2.regex_to_dfa(regex_str)), + )) + print(task6.cfpq_with_hellings(gramm, gr, start_nodes, final_nodes)) + + assert True \ No newline at end of file From 0e1a13045c16efcd2ac135c340caacafbc2b988d Mon Sep 17 00:00:00 2001 From: heli0dus Date: Fri, 10 May 2024 22:59:45 +0300 Subject: [PATCH 6/9] call of despair --- project/task2.py | 12 +++-- project/task3.py | 47 ++++++++++-------- project/task4.py | 16 ++++-- project/task6.py | 51 +++++++++++--------- tests/{test_task6.py => test_task6_local.py} | 7 ++- 5 files changed, 79 insertions(+), 54 deletions(-) rename tests/{test_task6.py => test_task6_local.py} (81%) diff --git a/project/task2.py b/project/task2.py index 8ae640210..1ce39679a 100644 --- a/project/task2.py +++ b/project/task2.py @@ -4,6 +4,8 @@ from pyformlang.finite_automaton import DeterministicFiniteAutomaton from pyformlang.finite_automaton import NondeterministicFiniteAutomaton +from pyformlang.finite_automaton import NondeterministicFiniteAutomaton +from pyformlang.finite_automaton import State def regex_to_dfa(regex: str) -> DeterministicFiniteAutomaton: @@ -15,20 +17,20 @@ def graph_to_nfa( ) -> NondeterministicFiniteAutomaton: nfa = NondeterministicFiniteAutomaton() - if len(start_states) == 0: - for node in graph.nodes(): + if start_states is None or len(start_states) == 0: + for node in graph.nodes: nfa.add_start_state(node) for node in start_states: nfa.add_start_state(node) - if len(final_states) == 0: - for node in graph.nodes(): + if final_states is None or len(final_states) == 0: + for node in graph.nodes: nfa.add_final_state(node) for node in final_states: nfa.add_final_state(node) for u, v, label in graph.edges(data="label"): - nfa.add_transition(u, label, v) + nfa.add_transition(State(u), label, State(v)) return nfa pass diff --git a/project/task3.py b/project/task3.py index 8d9053b09..39a7c2571 100644 --- a/project/task3.py +++ b/project/task3.py @@ -29,7 +29,7 @@ def __init__( self.final_states = aut.final_states states = aut.to_dict() len_states = len(aut.states) - self.state_to_idx = {v: i for i, v in enumerate(aut.states)} + self.state_mat_mapping = {v: i for i, v in enumerate(aut.states)} self.matrix = dict() for label in aut.symbols: @@ -38,31 +38,33 @@ def __init__( if label in edges: for v in as_set(edges[label]): self.matrix[label][ - self.state_to_idx[u], self.state_to_idx[v] + self.state_mat_mapping[u], self.state_mat_mapping[v] ] = True def accepts(self, word: Iterable[Symbol]) -> bool: return self.to_automaton().accepts("".join(word)) - pass def is_empty(self) -> bool: - return len(self.matrix) == 0 or len(list(self.matrix.values())[0]) == 0 + return len(self.matrix.values()) == 0 def size(self) -> int: - return len(self.state_to_idx) + return len(self.state_mat_mapping) - def transitive_closure(self): - if len(self.matrix.values()) == 0: + def transitive_closure(self) -> sparse.dok_matrix: + if self.is_empty(): return sparse.dok_matrix((0, 0), dtype=bool) - adj = sum(self.matrix.values()) + + adj = sum(self.matrix.values()) + sparse.eye(self.size(), self.size(), dtype=bool) + for _ in range(adj.shape[0]): adj += adj @ adj + return adj def to_automaton(self) -> NondeterministicFiniteAutomaton: ans = NondeterministicFiniteAutomaton() - idx_to_state = {v: k for k, v in self.state_to_idx.items()} + idx_to_state = {v: k for k, v in self.state_mat_mapping.items()} for label in self.matrix.keys(): matrix_size = self.matrix[label].shape[0] @@ -70,16 +72,16 @@ def to_automaton(self) -> NondeterministicFiniteAutomaton: for y in range(matrix_size): if self.matrix[label][x, y]: ans.add_transition( - self.state_to_idx[State(x)], + self.state_mat_mapping[State(x)], label, - self.state_to_idx[State(y)], + self.state_mat_mapping[State(y)], ) for s in self.start_states: - ans.add_start_state(self.state_to_idx[State(s)]) + ans.add_start_state(self.state_mat_mapping[State(s)]) for s in self.final_states: - ans.add_final_state(self.state_to_idx[State(s)]) + ans.add_final_state(self.state_mat_mapping[State(s)]) return ans @@ -88,8 +90,13 @@ def intersect_automata( automaton1: FiniteAutomaton, automaton2: FiniteAutomaton ) -> FiniteAutomaton: a = deepcopy(automaton1) - num_states = len(automaton2.state_to_idx) - symbols = set(automaton1.matrix.keys()).intersection(automaton2.matrix.keys()) + num_states = len(automaton2.state_mat_mapping) + symbols = automaton1.matrix.keys() & automaton2.matrix.keys() + # symbols = None + # if take_from_mapping: + # symbols = automaton1.state_mat_mapping.keys() & automaton2.state_mat_mapping.keys() + # else: + # symbols = automaton1.matrix.keys() & automaton2.matrix.keys() matrices = { label: sparse.kron(automaton1.matrix[label], automaton2.matrix[label], "csr") for label in symbols @@ -98,10 +105,10 @@ def intersect_automata( final = set() mapping = dict() - for u, i in automaton1.state_to_idx.items(): - for v, j in automaton2.state_to_idx.items(): + for u, i in automaton1.state_mat_mapping.items(): + for v, j in automaton2.state_mat_mapping.items(): - k = len(automaton2.state_to_idx) * i + j + k = len(automaton2.state_mat_mapping) * i + j mapping[State(k)] = k assert isinstance(u, State) @@ -112,7 +119,7 @@ def intersect_automata( final.add(State(k)) a.matrix = matrices - a.state_to_idx = mapping + a.state_mat_mapping = mapping a.start_states = start a.final_states = final return a @@ -131,7 +138,7 @@ def paths_ends( for u, v in zip(*closure.nonzero()): if u in intersection.start_states and v in intersection.final_states: result.append( - (aut_graph.state_to_idx[u // size], aut_graph.state_to_idx[v // size]) + (aut_graph.state_mat_mapping[u // size], aut_graph.state_mat_mapping[v // size]) ) return result diff --git a/project/task4.py b/project/task4.py index 01ad7c7a6..2ce53c18b 100644 --- a/project/task4.py +++ b/project/task4.py @@ -23,7 +23,7 @@ def reachability_with_constraints( n = fa.size() constr_start_inds = [ - constraints_fa.state_to_idx[State(i)] for i in constraints_fa.start_states + constraints_fa.state_mat_mapping[State(i)] for i in constraints_fa.start_states ] symbols = fa.matrix.keys() & constraints_fa.matrix.keys() @@ -33,12 +33,20 @@ def reachability_with_constraints( for label in symbols } - for v in [fa.state_to_idx[State(k)] for k in fa.start_states]: + for v in [fa.state_mat_mapping[State(k)] for k in fa.start_states]: front = sparse.dok_matrix((m, m + n), dtype=bool) for i in constr_start_inds: front[i, i] = True for i in range(m): front[i, v + m] = True + + for i in [ + constraints_fa.state_mat_mapping[State(k)] + for k in constraints_fa.final_states + ]: + for j in [fa.state_mat_mapping[State(k)] for k in fa.final_states]: + if front[i, j + m]: + result[v].add(j) for _ in range(m * n): new_front = sparse.dok_matrix((m, m + n), dtype=bool) @@ -47,10 +55,10 @@ def reachability_with_constraints( front = new_front for i in [ - constraints_fa.state_to_idx[State(k)] + constraints_fa.state_mat_mapping[State(k)] for k in constraints_fa.final_states ]: - for j in [fa.state_to_idx[State(k)] for k in fa.final_states]: + for j in [fa.state_mat_mapping[State(k)] for k in fa.final_states]: if front[i, j + m]: result[v].add(j) return result diff --git a/project/task6.py b/project/task6.py index f62ddbcbc..6b26852a5 100644 --- a/project/task6.py +++ b/project/task6.py @@ -2,6 +2,7 @@ import pyformlang import networkx as nx from typing import Tuple +from copy import deepcopy def cfg_to_weak_normal_form(cfg: pyformlang.cfg.CFG) -> pyformlang.cfg.CFG: @@ -34,25 +35,29 @@ def cfpq_with_hellings( p3 = {} for p in gramm.productions: - p_len = p.body + p_len = len(p.body) if p_len == 1 and isinstance(p.body[0], Terminal): p1.setdefault(p.head, set()).add(p.body[0]) - elif p_len == 1 and isinstance(p.body[0], Epsilon): - p2.add(p.body[0]) + elif p_len == 0 or p_len == 1 and isinstance(p.body[0], Epsilon): + p2.add(p.head) elif p_len == 2: - p3.setdefault(p.head, set).add((p.body[0], p.body[1])) - + p3.setdefault(p.head, set()).add((p.body[0], p.body[1])) + #петли result = {(n, v, v) for n in p2 for v in graph.nodes} - increment = {} - i = 0 - for v, u, tag in graph.edges.data("label"): - for n in p1: - if tag in p1[n]: - increment[i] = (n, v, u) - i += 1 - result.union(increment) - - queue_to_process = result.copy() + #переходы по терминалам + increment = {(n, v, u) + for (v, u, tag) in graph.edges.data("label") + for n in p1 + if Terminal(tag) in p1[n]} + # i = 0 + # for v, u, tag in graph.edges.data("label"): + # for n in p1: + # if tag in p1[n]: + # increment[i] = (n, v, u) + # i += 1 + result |= increment + + queue_to_process = deepcopy(result) while len(queue_to_process) > 0: n_i, vi, ui = queue_to_process.pop() @@ -60,23 +65,23 @@ def cfpq_with_hellings( step_increment = set() for n_j, vj, uj in result: - if vi == ui: + if vi == uj: for n_k in p3: - if (n_j, n_i) in p3[n_k] and (n_k, vj, vi) not in result: + if (n_j, n_i) in p3[n_k] and (n_k, vj, ui) not in result: queue_to_process.add((n_k, vj, ui)) step_increment.add((n_k, vj, ui)) for n_j, vj, uj in result: - if ui == vi: + if ui == vj: for n_k in p3: - if (n_i, n_j) in p3[n_k] and (n_k, vi, ui) not in result: + if (n_i, n_j) in p3[n_k] and (n_k, vi, uj) not in result: queue_to_process.add((n_k, vi, uj)) step_increment.add((n_k, vi, uj)) - result.union(step_increment) + result |= step_increment return { - (u, v) - for (n_i, u, v) in result - if u in start_nodes and v in final_nodes and Variable(n_i) == cfg.start_symbol + (v, u) + for (n_i, v, u) in result + if v in start_nodes and u in final_nodes and Variable(n_i) == cfg.start_symbol } diff --git a/tests/test_task6.py b/tests/test_task6_local.py similarity index 81% rename from tests/test_task6.py rename to tests/test_task6_local.py index 5777f0786..aaf89061a 100644 --- a/tests/test_task6.py +++ b/tests/test_task6_local.py @@ -16,13 +16,16 @@ def test_cfpq(): start_nodes = {0, 1, 2} final_nodes = {0, 1} - print(gramm) - print(task6.cfg_to_weak_normal_form(gramm)) + print() + + print(gramm.to_text()) + print(task6.cfg_to_weak_normal_form(gramm).to_text()) print() print(task4.reachability_with_constraints( task3.FiniteAutomaton(task2.graph_to_nfa(gr, start_nodes, final_nodes)), task3.FiniteAutomaton(task2.regex_to_dfa(regex_str)), )) print(task6.cfpq_with_hellings(gramm, gr, start_nodes, final_nodes)) + print(task3.paths_ends(gr, start_nodes, final_nodes, regex_str)) assert True \ No newline at end of file From 6b498df862665e404c2ac10eb42fafa42fc213b6 Mon Sep 17 00:00:00 2001 From: heli0dus Date: Fri, 10 May 2024 23:18:38 +0300 Subject: [PATCH 7/9] despair is all I'm left with --- project/task4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/task4.py b/project/task4.py index 2ce53c18b..526d26e66 100644 --- a/project/task4.py +++ b/project/task4.py @@ -42,9 +42,9 @@ def reachability_with_constraints( for i in [ constraints_fa.state_mat_mapping[State(k)] - for k in constraints_fa.final_states + for k in (constraints_fa.final_states & constraints_fa.start_states) ]: - for j in [fa.state_mat_mapping[State(k)] for k in fa.final_states]: + for j in [fa.state_mat_mapping[State(k)] for k in (fa.final_states & fa.start_states)]: if front[i, j + m]: result[v].add(j) From 25e43fd7fab9b43a362451de2c64c16d20b6a74d Mon Sep 17 00:00:00 2001 From: heli0dus Date: Sat, 11 May 2024 13:49:05 +0300 Subject: [PATCH 8/9] bug fixes --- project/task3.py | 22 +++++++++++++++------- project/task4.py | 9 ++++++--- project/task6.py | 14 ++++++++------ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/project/task3.py b/project/task3.py index 39a7c2571..4e6ec4958 100644 --- a/project/task3.py +++ b/project/task3.py @@ -53,12 +53,14 @@ def size(self) -> int: def transitive_closure(self) -> sparse.dok_matrix: if self.is_empty(): return sparse.dok_matrix((0, 0), dtype=bool) - - adj = sum(self.matrix.values()) + sparse.eye(self.size(), self.size(), dtype=bool) + + adj = sum(self.matrix.values()) + sparse.eye( + self.size(), self.size(), dtype=bool + ) for _ in range(adj.shape[0]): adj += adj @ adj - + return adj def to_automaton(self) -> NondeterministicFiniteAutomaton: @@ -134,11 +136,17 @@ def paths_ends( closure = intersection.transitive_closure() size = query.size() - result = [] + result = set() for u, v in zip(*closure.nonzero()): if u in intersection.start_states and v in intersection.final_states: - result.append( - (aut_graph.state_mat_mapping[u // size], aut_graph.state_mat_mapping[v // size]) + result.add( + ( + aut_graph.state_mat_mapping[u // size], + aut_graph.state_mat_mapping[v // size], + ) ) - return result + if len(query.start_states & query.final_states) > 0: + result |= {(i, i) for i in start_nodes & final_nodes} + + return list(result) diff --git a/project/task4.py b/project/task4.py index 526d26e66..a78d11500 100644 --- a/project/task4.py +++ b/project/task4.py @@ -39,13 +39,16 @@ def reachability_with_constraints( front[i, i] = True for i in range(m): front[i, v + m] = True - + for i in [ constraints_fa.state_mat_mapping[State(k)] for k in (constraints_fa.final_states & constraints_fa.start_states) ]: - for j in [fa.state_mat_mapping[State(k)] for k in (fa.final_states & fa.start_states)]: - if front[i, j + m]: + for j in [ + fa.state_mat_mapping[State(k)] + for k in (fa.final_states & fa.start_states) + ]: + if front[i, i] and front[i, j + m]: result[v].add(j) for _ in range(m * n): diff --git a/project/task6.py b/project/task6.py index 6b26852a5..ba101f30e 100644 --- a/project/task6.py +++ b/project/task6.py @@ -42,13 +42,15 @@ def cfpq_with_hellings( p2.add(p.head) elif p_len == 2: p3.setdefault(p.head, set()).add((p.body[0], p.body[1])) - #петли + # петли result = {(n, v, v) for n in p2 for v in graph.nodes} - #переходы по терминалам - increment = {(n, v, u) - for (v, u, tag) in graph.edges.data("label") - for n in p1 - if Terminal(tag) in p1[n]} + # переходы по терминалам + increment = { + (n, v, u) + for (v, u, tag) in graph.edges.data("label") + for n in p1 + if Terminal(tag) in p1[n] + } # i = 0 # for v, u, tag in graph.edges.data("label"): # for n in p1: From 1b440ed0c7eadcd2d59227e27d84fe94173f1d9b Mon Sep 17 00:00:00 2001 From: heli0dus Date: Sat, 11 May 2024 13:50:56 +0300 Subject: [PATCH 9/9] style fixes --- tests/test_task6_local.py | 47 +++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/tests/test_task6_local.py b/tests/test_task6_local.py index aaf89061a..7c03b8146 100644 --- a/tests/test_task6_local.py +++ b/tests/test_task6_local.py @@ -4,28 +4,51 @@ import project.task6 as task6 from pyformlang import cfg import networkx as nx +from pyformlang.regular_expression import Regex + def test_cfpq(): gramm = cfg.CFG.from_text("S -> $ | a S") - regex_str = "a*" - + regex_str = "a b c*" + a = Regex("a b c*") + # b = Regex("(abc)*") + # assert Regex("abc*") == Regex("(abc)*") gr = nx.MultiDiGraph() - gr.add_edge(0, 1, label='a') - gr.add_edge(1, 2, label='b') - gr.add_edge(2, 0, label='a') - start_nodes = {0, 1, 2} - final_nodes = {0, 1} + gr.add_edges_from( + [ + (0, 1, "l"), + (1, 2, "l"), + (2, 0, "b"), + (2, 1, "b"), + (2, 5, "l"), + (2, 8, "l"), + (3, 1, "l"), + (3, 0, "e"), + (4, 2, "e"), + (6, 0, "b"), + (7, 5, "b"), + ] + ) + # gr.add_edge(0, 1, label='a') + # gr.add_edge(1, 2, label='b') + # gr.add_edge(2, 0, label='a') + # start_nodes = {0, 1, 2} + # final_nodes = {0, 1} + start_nodes = {0, 2, 6} + final_nodes = {1, 2, 4} print() print(gramm.to_text()) print(task6.cfg_to_weak_normal_form(gramm).to_text()) print() - print(task4.reachability_with_constraints( - task3.FiniteAutomaton(task2.graph_to_nfa(gr, start_nodes, final_nodes)), - task3.FiniteAutomaton(task2.regex_to_dfa(regex_str)), - )) + print( + task4.reachability_with_constraints( + task3.FiniteAutomaton(task2.graph_to_nfa(gr, start_nodes, final_nodes)), + task3.FiniteAutomaton(task2.regex_to_dfa(regex_str)), + ) + ) print(task6.cfpq_with_hellings(gramm, gr, start_nodes, final_nodes)) print(task3.paths_ends(gr, start_nodes, final_nodes, regex_str)) - assert True \ No newline at end of file + assert True