Skip to content

Commit

Permalink
Add complex test
Browse files Browse the repository at this point in the history
Add test with multi grammars and graphs.
Add some comments and functions into to_program_parser
  • Loading branch information
KubEF committed May 26, 2024
1 parent 7208040 commit 582cefd
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 41 deletions.
61 changes: 56 additions & 5 deletions tests/autotests/test_task12.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import random

import pytest
from to_program_parser import WELL_TYPED, ILL_TYPED, Program
from to_program_parser import (
WELL_TYPED,
ILL_TYPED,
GraphProgram,
GrammarProgram,
QueryProgram,
to_program_parser,
)
from fixtures import graph
from grammars_constants import GRAMMARS_DIFFERENT
from networkx import MultiDiGraph
from pyformlang.cfg import CFG
from helper import generate_rnd_start_and_final
from helper import generate_rnd_start_and_final, generate_rnd_dense_graph
from constants import LABELS

try:
from project.task7 import cfpq_with_matrix
Expand All @@ -22,12 +32,53 @@ def test_well_typed(self, program: str) -> None:
def test_ill_typed(self, program: str) -> None:
assert not typing_program(program)

@pytest.mark.skip("Has errors")
@pytest.mark.parametrize("grammar", GRAMMARS_DIFFERENT)
def test_exec_simple(self, graph: MultiDiGraph, grammar: CFG):
start_nodes, final_nodes = generate_rnd_start_and_final(graph)
program = Program(graph, grammar, start_nodes, final_nodes)
graph_prog = GraphProgram(graph)
cfg_prog = GrammarProgram(grammar)
query = QueryProgram(graph_prog, cfg_prog, start_nodes, final_nodes)
program = query.full_program()
assert typing_program(program)
cfpq_from_prog = exec_program(str(program))[program.result_name]
cfpq_from_prog = exec_program(program)[query.result_name]
cfpq_from_algo = cfpq_with_matrix(grammar, graph, start_nodes, final_nodes)
assert cfpq_from_prog == cfpq_from_algo

# @pytest.mark.parametrize("queries_count", [2, 3, 5])
# def test_exec_one_graph_many_queries(self, graph, queries_count):
# start_nodes, final_nodes = generate_rnd_start_and_final(graph)
# graph_prog = GraphProgram(graph)
# query_list = []
# for i in range(queries_count):
# grammar_prog = GrammarProgram(random.choice(GRAMMARS_DIFFERENT))
# query_list.append(QueryProgram(graph_prog, grammar_prog, start_nodes, final_nodes))
# program, name_result = to_program_parser(query_list)
# result_dict: dict = exec_program(program)
# for var, res in result_dict.items():
# query = name_result[var]
# separate_res = exec_program(query.full_program())
# assert separate_res == res
# assert res == cfpq_with_matrix(query.get_grammar(), query.get_graph(), query.start_nodes, query.final_nodes)
@pytest.mark.parametrize("queries_count", [1, 3, 5])
def test_exec_many_graphs_many_queries(self, queries_count):
query_list = []
for i in range(queries_count):
graph = generate_rnd_dense_graph(1, 40, LABELS)
grammar_prog = GrammarProgram(random.choice(GRAMMARS_DIFFERENT))
graph_prog = GraphProgram(graph)
start_nodes, final_nodes = generate_rnd_start_and_final(graph)
query_list.append(
QueryProgram(graph_prog, grammar_prog, start_nodes, final_nodes)
)
program, name_result = to_program_parser(query_list)
result_dict: dict = exec_program(program)
for var, res in result_dict.items():
query = name_result[var]
separate_res = exec_program(query.full_program())
assert separate_res == res
assert res == cfpq_with_matrix(
query.get_grammar(),
query.get_graph(),
query.start_nodes,
query.final_nodes,
)
73 changes: 37 additions & 36 deletions tests/autotests/to_program_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, graph: nx.MultiDiGraph):
)

def __str__(self):
program = f"let {self.graph.name} is graph"
program = f"\nlet {self.graph.name} is graph"
for node_from, node_to, data in self.graph.edges(data=True):
program += f'\nadd edge ({node_from}, "{data[LABEL]}", {node_to}) to {self.graph.name}'
return program
Expand Down Expand Up @@ -126,7 +126,17 @@ def __init__(
self.start_nodes = start_nodes
self.final_nodes = final_nodes

def __str__(self) -> str:
def get_graph(self):
return self.graph_program.graph

def get_grammar(self):
return self.grammar_program.grammar

def query_program(self) -> str:
"""
if you want only want to get query
:return: just select expression
"""
query_name = self.grammar_program.start_nonterminal_name
start_set_expr = (
"["
Expand Down Expand Up @@ -156,42 +166,33 @@ def __str__(self) -> str:
f"reachable from v in {self.graph_program.name} by {query_name}"
)

def full_program(self) -> str:
"""
if you want to work with query as meaningful object
:return: fully query with predefined graph and grammar
"""
return f"\n{self.graph_program}\n{self.grammar_program}\n{self.query_program()}"

class Program:
EPS = '"a"^[0]'
nonterminal_names = {}
result_name = ""

def __init__(
self,
graph: nx.MultiDiGraph,
cfg: pl.cfg.CFG,
start_nodes: set[int],
final_nodes=None,
):
self.graph = graph.copy()
self.graph.name = (
FreshVar.generate_fresh(graph.name)
if graph.name != ""
else FreshVar.generate_fresh("g")
)
self.grammar = copy(cfg)
self.start_nodes = start_nodes
self.final_nodes = final_nodes
self.result_name = FreshVar.generate_fresh("r")
for production in cfg.productions:
if production.head not in self.nonterminal_names.keys():
self.nonterminal_names[production.head] = FreshVar.generate_fresh(
_nonterminal_to_string(production.head)
)

def __str__(self):
program = ""
program += self._graph_to_program()
cfg_pr = self._cfg_to_program()
program += cfg_pr
program += self._query_to_program()
return program
def to_program_parser(
query_list: list[QueryProgram],
) -> tuple[str, dict[str, QueryProgram]]:
result_program = ""
res_name_query = {}
grammar_set = set()
graph_set = set()
for query in query_list:
# if graph is already defined then it is not necessary to define it again
if query.graph_program not in graph_set:
result_program += str(query.graph_program)
graph_set.add(query.graph_program)
# same with grammar
if query.grammar_program not in grammar_set:
result_program += str(query.grammar_program)
grammar_set.add(query.grammar_program)
result_program += query.query_program()
res_name_query.update({query.result_name: query})
return result_program, res_name_query


WELL_TYPED = [
Expand Down

0 comments on commit 582cefd

Please sign in to comment.