Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
46 changes: 28 additions & 18 deletions src/agents/query_engine/MettaParserActions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,21 @@ MettaParserActions::~MettaParserActions() {}

void MettaParserActions::symbol(const string& name) {
ParserActions::symbol(name);
if ((name == MettaMapping::AND_QUERY_OPERATOR) || (name == MettaMapping::OR_QUERY_OPERATOR) ||
(name == MettaMapping::CHAIN_QUERY_OPERATOR)) {
if ((name == MettaMapping::AND_QUERY_OPERATOR) || (name == MettaMapping::ANDNOT_QUERY_OPERATOR) ||
(name == MettaMapping::OR_QUERY_OPERATOR) || (name == MettaMapping::CHAIN_QUERY_OPERATOR)) {
if (name == MettaMapping::AND_QUERY_OPERATOR) {
this->current_expression_type = AND;
} else if (name == MettaMapping::ANDNOT_QUERY_OPERATOR) {
this->current_expression_type = ANDNOT;
} else if (name == MettaMapping::OR_QUERY_OPERATOR) {
this->current_expression_type = OR;
} else {
this->current_expression_type = CHAIN;
}
} else {
if ((this->current_expression_type == AND) || (this->current_expression_type == OR) ||
(this->current_expression_type == CHAIN)) {
RAISE_ERROR("Invalid query expression: AND/OR/CHAIN can't operate symbols.");
if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR) || (this->current_expression_type == CHAIN)) {
RAISE_ERROR("Invalid query expression: AND/ANDNOT/OR/CHAIN can't operate symbols.");
return;
}
this->current_expression_size++;
Expand All @@ -54,8 +56,9 @@ void MettaParserActions::symbol(const string& name) {

void MettaParserActions::variable(const string& value) {
ParserActions::variable(value);
if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/OR can't operate variables.");
if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/ANDNOT/OR can't operate variables.");
return;
}
if (this->current_expression_type == LINK) {
Expand All @@ -67,8 +70,9 @@ void MettaParserActions::variable(const string& value) {

void MettaParserActions::literal(const string& value) {
ParserActions::literal(value);
if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/OR can't operate literals.");
if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/ANDNOT/OR can't operate literals.");
return;
}
this->current_expression_size++;
Expand All @@ -77,8 +81,9 @@ void MettaParserActions::literal(const string& value) {

void MettaParserActions::literal(int value) {
ParserActions::literal(value);
if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/OR can't operate literals.");
if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR)) {
RAISE_ERROR("Invalid query expression: AND/ANDNOT/OR can't operate literals.");
return;
}
this->current_expression_size++;
Expand All @@ -88,9 +93,9 @@ void MettaParserActions::literal(int value) {

void MettaParserActions::literal(float value) {
ParserActions::literal(value);
if ((this->current_expression_type == AND) || (this->current_expression_type == OR) ||
(this->current_expression_type == CHAIN)) {
RAISE_ERROR("Invalid query expression: AND/OR/CHAIN can't operate float literals.");
if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR) || (this->current_expression_type == CHAIN)) {
RAISE_ERROR("Invalid query expression: AND/ANDNOT/OR/CHAIN can't operate float literals.");
return;
}
this->current_expression_size++;
Expand Down Expand Up @@ -155,10 +160,11 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre
this->proxy->parameters.get<bool>(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE));
this->element_stack.push(new_link_template);
}
} else if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) {
} else if ((this->current_expression_type == AND) || (this->current_expression_type == ANDNOT) ||
(this->current_expression_type == OR)) {
if (this->element_stack.size() >= 2) {
shared_ptr<QueryElement> new_operator;
// When using MeTTa to define a query, AND and OR operations always take 2 arguments.
// When using MeTTa to define a query, AND, ANDNOT and OR operations always take 2 arguments.
array<shared_ptr<QueryElement>, 2> clauses;
vector<shared_ptr<QueryElement>> link_templates;
for (int i = 1; i >= 0; i--) {
Expand All @@ -172,15 +178,19 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre
if (this->element_stack.top()->is_operator) {
clauses[i] = this->element_stack.top();
} else {
RAISE_ERROR("All AND clauses are supposed to be LinkTemplate or Operator");
RAISE_ERROR(
"All AND/ANDNOT/OR clauses are supposed to be LinkTemplate or Operator");
return;
}
}
this->element_stack.pop();
}
if (this->current_expression_type == AND) {
LOG_DEBUG("Pushing AND");
new_operator = make_shared<And<2>>(clauses, link_templates);
new_operator = make_shared<And<2>>(clauses, link_templates, false);
} else if (this->current_expression_type == ANDNOT) {
LOG_DEBUG("Pushing ANDNOT");
new_operator = make_shared<And<2>>(clauses, link_templates, true);
} else {
LOG_DEBUG("Pushing OR");
new_operator = make_shared<Or<2>>(clauses, link_templates);
Expand Down
2 changes: 1 addition & 1 deletion src/agents/query_engine/MettaParserActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ using namespace query_element;

namespace query_engine {

enum ExpressionType { LINK, LINK_TEMPLATE, AND, OR, CHAIN };
enum ExpressionType { LINK, LINK_TEMPLATE, AND, ANDNOT, OR, CHAIN };

/**
*
Expand Down
35 changes: 21 additions & 14 deletions src/agents/query_engine/PatternMatchingQueryProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ using namespace metta;
using namespace attention_broker;

string PatternMatchingQueryProcessor::AND = "AND";
string PatternMatchingQueryProcessor::ANDNOT = "ANDNOT";
string PatternMatchingQueryProcessor::OR = "OR";
string PatternMatchingQueryProcessor::CHAIN = "CHAIN";

Expand Down Expand Up @@ -297,7 +298,7 @@ shared_ptr<QueryElement> PatternMatchingQueryProcessor::setup_query_tree(
cursor += 3;
} else if ((query_tokens[cursor] == LinkSchema::UNTYPED_VARIABLE) ||
(query_tokens[cursor] == LinkSchema::ATOM) || (query_tokens[cursor] == AND) ||
(query_tokens[cursor] == OR)) {
(query_tokens[cursor] == ANDNOT) || (query_tokens[cursor] == OR)) {
cursor += 2;
} else if (query_tokens[cursor] == CHAIN) {
cursor += 4;
Expand Down Expand Up @@ -327,7 +328,12 @@ shared_ptr<QueryElement> PatternMatchingQueryProcessor::setup_query_tree(
} else if (query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) {
element_stack.push(build_link_template(proxy, cursor, element_stack));
} else if (query_tokens[cursor] == AND) {
element_stack.push(build_and(proxy, cursor, element_stack));
element_stack.push(build_and(proxy, false, cursor, element_stack));
if (proxy->parameters.get<bool>(BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG)) {
element_stack.push(build_unique_assignment_filter(proxy, cursor, element_stack));
}
} else if (query_tokens[cursor] == ANDNOT) {
element_stack.push(build_and(proxy, true, cursor, element_stack));
if (proxy->parameters.get<bool>(BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG)) {
element_stack.push(build_unique_assignment_filter(proxy, cursor, element_stack));
}
Expand Down Expand Up @@ -381,7 +387,7 @@ shared_ptr<QueryElement> PatternMatchingQueryProcessor::build_link_template(
return link_template;
}

#define BUILD_AND(N) \
#define BUILD_AND(N, AND_NOT_FLAG) \
{ \
vector<shared_ptr<QueryElement>> link_templates; \
array<shared_ptr<QueryElement>, N> clauses; \
Expand All @@ -400,11 +406,12 @@ shared_ptr<QueryElement> PatternMatchingQueryProcessor::build_link_template(
} \
element_stack.pop(); \
} \
return make_shared<And<N>>(clauses, link_templates); \
return make_shared<And<N>>(clauses, link_templates, AND_NOT_FLAG); \
}

shared_ptr<QueryElement> PatternMatchingQueryProcessor::build_and(
shared_ptr<PatternMatchingQueryProxy> proxy,
bool and_not_flag,
unsigned int cursor,
stack<shared_ptr<QueryElement>>& element_stack) {
const vector<string> query_tokens = proxy->get_query_tokens();
Expand All @@ -414,16 +421,16 @@ shared_ptr<QueryElement> PatternMatchingQueryProcessor::build_and(
}
// clang-format off
switch (num_clauses) {
case 1: BUILD_AND(1)
case 2: BUILD_AND(2)
case 3: BUILD_AND(3)
case 4: BUILD_AND(4)
case 5: BUILD_AND(5)
case 6: BUILD_AND(6)
case 7: BUILD_AND(7)
case 8: BUILD_AND(8)
case 9: BUILD_AND(9)
case 10: BUILD_AND(10)
case 1: BUILD_AND(1, and_not_flag)
case 2: BUILD_AND(2, and_not_flag)
case 3: BUILD_AND(3, and_not_flag)
case 4: BUILD_AND(4, and_not_flag)
case 5: BUILD_AND(5, and_not_flag)
case 6: BUILD_AND(6, and_not_flag)
case 7: BUILD_AND(7, and_not_flag)
case 8: BUILD_AND(8, and_not_flag)
case 9: BUILD_AND(9, and_not_flag)
case 10: BUILD_AND(10, and_not_flag)
// clang-format on
default: {
RAISE_ERROR("PATTERN_MATCHING_QUERY message: max supported num_clauses for AND: 10");
Expand Down
2 changes: 2 additions & 0 deletions src/agents/query_engine/PatternMatchingQueryProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class PatternMatchingQueryProcessor : public BusCommandProcessor {
stack<shared_ptr<QueryElement>>& element_stack);

shared_ptr<QueryElement> build_and(shared_ptr<PatternMatchingQueryProxy> proxy,
bool and_not_flag,
unsigned int cursor,
stack<shared_ptr<QueryElement>>& element_stack);

Expand Down Expand Up @@ -91,6 +92,7 @@ class PatternMatchingQueryProcessor : public BusCommandProcessor {
shared_ptr<PatternMatchingQueryProxy> proxy;
shared_ptr<AtomDB> atomdb;
static string AND;
static string ANDNOT;
static string OR;
static string CHAIN;
};
Expand Down
Loading
Loading