Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c43e400
feat: adjust output to pipetester requirements
FRutkowski Jun 11, 2023
a88e218
refactor: uncomment an important code
FRutkowski Jun 11, 2023
12f3f69
refactor: put print ready up the loop
FRutkowski Jun 11, 2023
8ea8843
fix: fix pipetester output
KamiloSzcz Jun 13, 2023
fa3818e
fix: return error on one line
MParchan Jun 13, 2023
f56004f
Update main.py
KamiloSzcz Jun 13, 2023
dfd3ffa
Update query_evaluator.py
KamiloSzcz Jun 13, 2023
d0c8378
Update main.py
KamiloSzcz Jun 13, 2023
316ed06
Update main.py
KamiloSzcz Jun 13, 2023
9eefbf5
Update main.py
KamiloSzcz Jun 13, 2023
e52f768
fix: fix tests to new format
MParchan Jun 13, 2023
1c6957e
fix: fix boolean query
MParchan Jun 13, 2023
ee132ce
feat: add prog_line
MParchan Jun 13, 2023
83e0a82
Update design_extractor.py
MParchan Jun 13, 2023
d08c4c7
fix: fix uses and modiifes
MParchan Jun 13, 2023
402f11e
fix: uses and modifies
MParchan Jun 13, 2023
eb817a6
Merge branch 'master' into feat/output-pipetester
wvffle Jun 13, 2023
4332b84
chore: rebase
wvffle Jun 13, 2023
f4c80bd
refactor: cleanup code
wvffle Jun 13, 2023
a1fdca3
fix: fix failing test due to rebasing mistake
wvffle Jun 13, 2023
fa21f49
feat: add `select x` support
wvffle Jun 13, 2023
c679599
feat: better error messages
wvffle Jun 13, 2023
008c6eb
feat: add error about attribute and pattern conditions
wvffle Jun 13, 2023
3b8cb6c
feat: break out when calling a relation with same params
wvffle Jun 13, 2023
4bbcd5d
fix: allow Relation(_, _)
wvffle Jun 14, 2023
aa5fa9f
fix: fix extended parents
wvffle Jun 14, 2023
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
9 changes: 8 additions & 1 deletion ats/pkb/design_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,17 @@ def _dfs(node: nodes.ASTNode):


def extract(tree: nodes.ProgramNode):
stmts = []
statements_by_type = {
"procedure": [],
"variable": set(),
"constant": set(),
"assign": [],
"while": [],
"stmt": [],
"stmt": stmts,
"call": [],
"if": [],
"prog_line": stmts,
}

statements = {}
Expand Down Expand Up @@ -116,6 +119,10 @@ def on_node_enter(node: nodes.ASTNode, context: dict):
call_order.index(node.name), proc_stmt_stack[0].name
)

# Find all constants
if isinstance(node, nodes.ConstantNode):
statements_by_type["constant"].add(int(node.value))

# Find all variables
if isinstance(node, nodes.VariableNode):
variables[node] = node.name
Expand Down
41 changes: 24 additions & 17 deletions ats/pkb/query_evaluator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from ats.ast import nodes
from ats.ast.nodes import ProcedureNode
from ats.pkb.design_extractor import extract
from ats.pkb.utils import process_relation
from ats.pkb.utils import map_result, process_relation


def process_follows(query, context, relation):
Expand Down Expand Up @@ -102,6 +100,8 @@ def resolve_node(param):
if isinstance(param, int):
return context["statements"][param]
else:
if param == relation["parameters"][0]:
return context["procedures"][param[1:-1]]
Comment on lines +103 to +104
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ale wiecie ze to moze byc rowniez stmt?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return param[1:-1]

return process_relation(
Expand All @@ -119,6 +119,8 @@ def resolve_node(param):
if isinstance(param, int):
return context["statements"][param]
else:
if param == relation["parameters"][0]:
return context["procedures"][param[1:-1]]
Comment on lines +122 to +123
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return param[1:-1]

return process_relation(
Expand Down Expand Up @@ -168,9 +170,26 @@ def relation_cb(node_a, node_b):
)


def evaluate_query(node: nodes.ProgramNode, query):
context = extract(node)
def evaluate_query(query, context):
all_results = set()

# if (
# len(query["conditions"]["attributes"]) > 0
# or len(query["conditions"]["patterns"]) > 0
# ):
# raise ValueError("Attribute and pattern conditions are not supported yet")

if query["searching_variable"] != "BOOLEAN":
if len(query["conditions"]["relations"]) == 0:
all_results = set(
map(
map_result,
context["statements_by_type"][
query["variables"][query["searching_variable"]]
],
)
)

for i, relation in enumerate(query["conditions"]["relations"]):
results = all_results if i == 0 else set()
if relation["relation"] == "Follows":
Expand Down Expand Up @@ -206,18 +225,6 @@ def evaluate_query(node: nodes.ProgramNode, query):
if results != all_results:
all_results = all_results.intersection(results)

# assign a1;
# while w1, w2;
# Select a1 such that Parent(w1, a1) and Parent(w2, w1) with w2.stmt# = 5
for i, condition in enumerate(query["conditions"]["attributes"]):
results = all_results if i == 0 else set()

if results != all_results:
all_results = all_results.intersection(results)

for i, condition in enumerate(query["conditions"]["patterns"]):
...

if query["searching_variable"] == "BOOLEAN":
return len(all_results) > 0

Expand Down
11 changes: 11 additions & 0 deletions ats/pkb/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"while": nodes.StmtWhileNode,
"if": nodes.StmtIfNode,
"procedure": nodes.ProcedureNode,
"prog_line": nodes.StmtNode,
}


Expand Down Expand Up @@ -58,6 +59,13 @@ def process_relation(
):
results = set()

if is_variable(query, relation["parameters"][0]) and is_variable(
query, relation["parameters"][1]
):
if relation["parameters"][0] == relation["parameters"][1]:
if relation["parameters"][0] is not Any:
return results

class Break(Exception):
pass

Expand All @@ -70,6 +78,9 @@ def get_needle(stmt_a, stmt_b):

def check_relation(stmt_a, stmt_b):
nonlocal results
if stmt_a is None or stmt_b is None:
if stmt_a is stmt_b:
raise Break()

try:
if relation_cb(stmt_a, stmt_b):
Expand Down
38 changes: 31 additions & 7 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import sys
from threading import Timer

from ats.ast.nodes import ProcedureNode, ProgramNode, StmtLstNode, StmtNode
from ats.parser.parser import parse
from ats.pkb.design_extractor import extract
from ats.pkb.query_evaluator import evaluate_query
from ats.pql.pql import parse_query

if __name__ == "__main__":
sys.stdout.reconfigure(encoding="utf-8")
sys.stdout.reconfigure(encoding="utf-8") # nie powinno być ibm852?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to zmiencie?

if "--print-test-tree" in sys.argv:
tree = parse(
"""
Expand Down Expand Up @@ -45,17 +47,39 @@
Select BOOLEAN such that Calls(_, _)
"""
)
context = extract(tree)
print(evaluate_query(queries[0], context))

print(evaluate_query(tree, queries[0]))
elif len(sys.argv) > 0: # pragma no cover

def no_time_left():
print("\nPreparationTimeout")
exit(1)

elif len(sys.argv) > 0:
with open(sys.argv[-1]) as f:
code = f.read()
tree = parse(code)
# TODO: Extract design patterns here!
context = extract(tree)
print("Ready")
while True:
try:
t = Timer(60, no_time_left)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kiedy to ma sprawdzac?

Copy link
Copy Markdown
Collaborator

@KamiloSzcz KamiloSzcz Jun 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aż nie ma zapytań

t.start()
query = input() + "\n" + input()
t.cancel()

queries = parse_query(query)
result = evaluate_query(queries[0], context)

if isinstance(result, bool):
print("true" if result else "false")
continue

if len(result) == 0:
print("none")
continue

query = input() + "\n" + input()
print(", ".join(str(part) for part in result))

# TODO: use PQL and PKB
print("8")
except Exception as e:
print("# " + e.args[0].replace("\n", " "))
29 changes: 29 additions & 0 deletions simple.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
procedure test {
a = b;
while a {
a = c + d + g;
if e then {
b = a + e;
}
else {
c = f + c;
}
}
b = 10;
while a {
c = a + b;
f = c;
}
}
procedure test2 {
a = b + c;
while d {
if e then {
call test;
}
else {
a = f;
}
}
i = j;
}
51 changes: 18 additions & 33 deletions tests/pkb/test_boolean.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from ats.parser.parser import parse
from ats.pkb.design_extractor import extract
from ats.pkb.query_evaluator import evaluate_query
from ats.pql.pql import parse_query

Expand Down Expand Up @@ -40,6 +41,7 @@ def _get_ast_tree():


tree = _get_ast_tree()
context = extract(tree)


def test_pkb_boolean_with_condition():
Expand All @@ -50,7 +52,7 @@ def test_pkb_boolean_with_condition():
Select BOOLEAN with v.varName = p.procName
"""
)
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is False


Expand All @@ -61,83 +63,66 @@ def test_pkb_boolean_constant_with_condtition():
Select BOOLEAN with c1.value = c2.value and c2.value = 10
"""
)
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is False


def test_pkb_boolean_true_stmt_stmt():
queries = parse_query("stmt s1, s2; Select BOOLEAN such that Follows(s1, s2)")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is True


def test_pkb_boolean_false_stmt_constant():
queries = parse_query("stmt s1, s2; Select BOOLEAN such that Follows(s1, 1)")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is False


def test_pkb_boolean_true_proc_calls():
queries = parse_query("""procedure p; Select BOOLEAN such that Calls(p, "test")""")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is True


def test_pkb_boolean_false_stmt_stmt_follows_with_condition():
queries = parse_query(
"stmt s1, s2; Select BOOLEAN such that Follows(s1, s2) with s1.stmt# = 1 and s2.stmt# = 3"
)
result = evaluate_query(tree, queries[0])
assert result is False


def test_pkb_boolean_true_while_uses():
queries = parse_query("""while w; Select BOOLEAN such that Uses(w,"f")""")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is True


def test_pkb_boolean_false_while_uses_condition():
queries = parse_query(
"""while w; variable v1; Select BOOLEAN such that Uses(w, v1) with v1.varName = "x" """
)
result = evaluate_query(tree, queries[0])
assert result is False


def test_pkb_boolean_true_assign_while_next():
queries = parse_query("assign a; while w; Select BOOLEAN such that Next(a, w)")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is True


def test_pkb_boolean_false_while_while_next():
queries = parse_query("while w1, w2; Select BOOLEAN such that Next(w1, w2)")
result = evaluate_query(tree, queries[0])
result = evaluate_query(queries[0], context)
assert result is False


def test_pkb_boolean_true():
queries = parse_query(
"""
procedure p;
Select BOOLEAN such that Calls ("test3", "test5")
"""
)
tree = parse(
"""
procedure test1 {
call test5;
}

procedure test3 {
call test5;
}

procedure test5 {
call test1;
}
"""
)
result = evaluate_query(tree, queries[0])
queries = parse_query(
"""
procedure p;
Select BOOLEAN such that Calls ("test3", "test5")
"""
)
context = extract(tree)
result = evaluate_query(queries[0], context)
assert result is True
Loading