# PQL
```plantuml
@startuml
participant TestWrapper as TestWrapper
participant PQL as pql
participant PQLParser as parser
participant PQLEvaluator as eval
participant PKB as pkb
TestWrapper -> pql : answerQuery(string query)
activate TestWrapper
pql -> parser: new()
activate parser
pql <-- parser: parser instance
deactivate parser
pql -> parser: runLexer(string query)
activate parser
loop char in query
parser -> parser : tokens.add(token)
end
deactivate parser
pql -> parser : runParser(&synonyms, &selected)
activate parser
parser -> parser : parseDeclarations()
activate parser
parser -> parser : synonyms.add(s)
deactivate parser
parser -> parser : parseSelected()
activate parser
parser -> parser : selected = s
deactivate parser
parser -> parser : parseSuchThat()
activate parser
parser -> parser : relations.add(r)
deactivate parser
deactivate parser
pql -> eval : evalQuery(&synonyms, &selected)
eval -> eval : filterSynonyms()
activate eval
loop synonym in synonyms
eval -> pkb : isType(synonym)
end
deactivate eval
eval -> eval : generateTuples()
activate eval
eval --> eval : tuples(id, .., id)
deactivate eval
eval -> eval : filterTuples()
loop relation in relations
loop tuple in tuples
eval -> pkb : isRelation()
end
end
eval -> eval : getSelectedFromTuple()
activate eval
eval -> pkb : getValue(id)
eval --> eval : vector<string> result
deactivate eval
TestWrapper <-- pql : list<string> results
deactivate TestWrapper
@enduml
```
## PKB design
stmt by type:
vector<int> getAssignments()
vector<int> getIfs()
vector<int> getWhiles()
vector<int> getCalls()
vector<int> getReads()
vector<int> getPrints()
by name:
vector<string> getVariableNames()
vector<string> getProcedureNames()
design abstractions:
bool uses(int assign_ln/print_ln/if_ln/while_ln/call_ln, string var_name)
bool uses(string proc_name, string var_name)
bool modifies(int assign_ln/read_ln/if_ln/while_ln/call_ln, string var_name)
bool modifies(string proc_name, string var_name)
bool follows(int ln1, int ln2)
bool follows*(int ln1, int ln2)
bool parent(int ln1, int ln2)
bool parent*(int ln1, int ln2)
by pattern:
bool pattern(int ln, string lhs, string rhs)
vector<int> pattern(string lhs, string rhs)
assign a; while w;
Select w such that Parent* (w, a) pattern a (“count”, _)
procedure printAscending
{
read num1;
read num2;
noSwap = 0;
if (num1 > num2) then
{
temp = num1;
num1 = num2;
num2 = temp;
}
else
{
noSwap = 1;
}
if (num1 > num2) {
print num1;
}
print num1;
print num2;
print noSwap;
temp = temp + 1
}
assign a; if x;
Select x such that Parent*(x, a) pattern a (“temp”, _)
Select x: 63 and 74
such that Parent* (x, a): 63
pattern a(“temp”, _): 63
variable: v
assign: a
select: a
clauses: uses(a,v), modifies(a,v)
pattern: pattern a (“temp”, _)
variable v; assign a;
Select a such that Uses(a, v) and Modifies(a, v);
v: "temp", "num1", "num2" from PKB
vars = (a, v, x)
set = {()}
for var in vars:
new_set = {}
for tuple in set:
for attr in pkb.get(var.type):
new_tuple = tuple + attr
new_set.add(new_tuple)
set = new_set
a = 61, 52, 44
v = "temp1", "num"
{(61), (52), (44)}
// get stmt line numbers by type:
vector<int> getAssignments();
vector<int> getIfs();
vector<int> getWhiles();
vector<int> getCalls();
vector<int> getReads();
vector<int> getPrints();
// get names
vector<string> getVariableNames();
vector<string> getProcedureNames();
// lineNumber: assign_ln/print_ln/if_ln/while_ln/call_ln
bool isUses(int lineNumber, string varName);
bool isUses(string procName, string varName);
bool isModifies(int lineNumber, string varName);
bool isModifies(string procName, string varName);
bool isFollows(int lineNumber1, int lineNumber2);
bool isFollowsStar(int lineNumber1, int lineNumber2);
bool isParent(int lineNumber1, int lineNumber2);
bool isParentStar(int lineNumber1, int lineNumber2);
// by pattern:
bool isPattern(int lineNumber, string lhs, string rhs);
vector<int> getAssignmentsWithPattern(string lhs, string rhs);
Assign a; Variable v;
Select a such that Uses(a, v);
Token
Type Name
assign assign
name a
; ;
variable variable
name v
; ;
select select
name a
such that such that
uses uses
( (
name a
, ,
name v
) )
; ;
Synonym type:
name: v
type: variable
synonyms.push(s)
Uses:
Uses(a, v)
Uses type:
l: "a", synonym
r: "v", synonym
Uses("procname", a)
Uses type:
l: "procname", procedure
r: "a", synonym
Uses("procname", _)
Uses type:
l: "procname", procedure
r: "_", wildcard
relations.push(...)