-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement
cfg_to_weak_normal_form
and hellings_based_cfpq
m…
…ethods
- Loading branch information
Showing
4 changed files
with
82 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from pyformlang.cfg import CFG, Production, Epsilon | ||
|
||
|
||
def cfg_to_weak_normal_form(cfg: CFG) -> CFG: | ||
cnf = cfg.to_normal_form() | ||
cnf_productions = cnf.productions | ||
|
||
cfg_nullable_symbols = cfg.get_nullable_symbols() | ||
|
||
wcnf_productions = set() | ||
|
||
for production in cnf_productions: | ||
wcnf_productions.add(production) | ||
|
||
for sym in cfg_nullable_symbols: | ||
wcnf_productions.add(Production(sym, [Epsilon()], filtering=False)) | ||
|
||
return CFG(start_symbol=cfg.start_symbol, productions=wcnf_productions) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from pyformlang.cfg import CFG, Terminal | ||
import networkx as nx | ||
|
||
from project.cfg_utils import cfg_to_weak_normal_form | ||
|
||
|
||
def hellings_based_cfpq( | ||
cfg: CFG, | ||
graph: nx.DiGraph, | ||
start_nodes: set[int] = None, | ||
final_nodes: set[int] = None, | ||
) -> set[tuple[int, int]]: | ||
wcnf = cfg_to_weak_normal_form(cfg) | ||
wcnf_productions = wcnf.productions | ||
wcnf_nullable_symbols = wcnf.get_nullable_symbols() | ||
|
||
m = set() | ||
r = set() | ||
|
||
edges = graph.edges(data="label") | ||
|
||
for u, v, label in edges: | ||
for production in wcnf_productions: | ||
if Terminal(label) in production.body: | ||
m.add((production.head, u, v)) | ||
r.add((production.head, u, v)) | ||
|
||
for node in graph.nodes: | ||
for sym in wcnf_nullable_symbols: | ||
m.add((sym, node, node)) | ||
r.add((sym, node, node)) | ||
|
||
while m: | ||
(N, a, b) = m.pop() | ||
for M, c, d in r.copy(): | ||
if b == c: | ||
for production in wcnf_productions: | ||
if [N, M] == production.body: | ||
tr = (production.head, a, d) | ||
if tr not in r: | ||
m.add(tr) | ||
r.add(tr) | ||
if a == d: | ||
for production in wcnf_productions: | ||
if [M, N] == production.body: | ||
tr = (production.head, c, b) | ||
if tr not in r: | ||
m.add(tr) | ||
r.add(tr) | ||
|
||
result = set() | ||
for N, a, b in r: | ||
if ( | ||
N == wcnf.start_symbol | ||
and (not start_nodes or a in start_nodes) | ||
and (not final_nodes or b in final_nodes) | ||
): | ||
result.add((a, b)) | ||
|
||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters