From 9111a5577f88a6a5d7086f9d4c934b9aec6393ac Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 27 Jan 2026 16:59:54 -0300 Subject: [PATCH 01/22] WIP --- src/BUILD | 12 + .../evolution/QueryEvolutionProcessor.cc | 20 +- .../PatternMatchingQueryProcessor.cc | 3 +- src/scripts/bazel_build.sh | 2 + src/tests/main/BUILD | 12 + src/tests/main/evaluation_evolution.cc | 791 ++++++++++++++++++ 6 files changed, 832 insertions(+), 8 deletions(-) create mode 100644 src/tests/main/evaluation_evolution.cc diff --git a/src/BUILD b/src/BUILD index 90a61058b..0f322e255 100644 --- a/src/BUILD +++ b/src/BUILD @@ -152,6 +152,18 @@ cc_binary( ], ) +cc_binary( + name = "evaluation_evolution", + srcs = [], + defines = ["BAZEL_BUILD"], + linkstatic = 1, + deps = [ + "//commons:commons_lib", + "//tests/main:evaluation_evolution_main_lib", + "@mbedtls", + ], +) + cc_binary( name = "busnode", srcs = [], diff --git a/src/agents/evolution/QueryEvolutionProcessor.cc b/src/agents/evolution/QueryEvolutionProcessor.cc index 6fb861e9c..e19cbca0a 100644 --- a/src/agents/evolution/QueryEvolutionProcessor.cc +++ b/src/agents/evolution/QueryEvolutionProcessor.cc @@ -293,7 +293,7 @@ float eval_word(const string& handle, string& word) { void QueryEvolutionProcessor::correlate_similar(shared_ptr proxy, shared_ptr correlation_query_answer) { vector query_tokens; - vector handle_list; + map> handle_lists; vector> correlation_queries = proxy->get_correlation_queries(); vector> correlation_replacements = proxy->get_correlation_replacements(); @@ -350,24 +350,30 @@ void QueryEvolutionProcessor::correlate_similar(shared_ptr } // Update AttentionBroker - handle_list.clear(); - handle_list.push_back(correlation_query_answer->get(correlation_mappings[0].first)); + handle_lists.clear(); auto pm_query = issue_correlation_query(proxy, query_tokens); while (!pm_query->finished()) { shared_ptr answer = pm_query->pop(); string word; if (answer != NULL) { for (auto pair : correlation_mappings) { - string handle = answer->get(pair.second); - if (handle != "") { - handle_list.push_back(handle); + string key = answer->get(pair.first, true); + string handle = answer->get(pair.second, true); + if ((key != "") && (handle != "")) { + if (handle_lists.find(key) == handle_lists.end()) { + handle_lists[key] = {key}; + } else { + handle_lists[key].push_back(handle); + } } } } else { Utils::sleep(); } } - AttentionBrokerClient::asymmetric_correlate(handle_list, proxy->get_context()); + for (auto pair : handle_lists) { + AttentionBrokerClient::asymmetric_correlate(pair.second, proxy->get_context()); + } } } diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index b6b51417b..2a20a067f 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -85,9 +85,9 @@ void PatternMatchingQueryProcessor::update_attention_broker_single_answer( for (auto pair : answer->assignment.table) { single_answer.insert(pair.second); joint_answer.insert(pair.second); - single_answer.insert(pair.second); } + /* // Correlate handles which are the query answer for (string handle : answer->handles) { execution_stack.push(handle); @@ -109,6 +109,7 @@ void PatternMatchingQueryProcessor::update_attention_broker_single_answer( } } } + */ if (single_answer.size() > 1) { AttentionBrokerClient::correlate(single_answer, proxy->get_context()); } else { diff --git a/src/scripts/bazel_build.sh b/src/scripts/bazel_build.sh index 90adc752b..06efc0443 100755 --- a/src/scripts/bazel_build.sh +++ b/src/scripts/bazel_build.sh @@ -41,6 +41,7 @@ if [ "$BUILD_BINARIES" = true ]; then BUILD_TARGETS+=" //:word_query" BUILD_TARGETS+=" //:word_query_evolution" BUILD_TARGETS+=" //:implication_query_evolution" + BUILD_TARGETS+=" //:evaluation_evolution" BUILD_TARGETS+=" //:tests_db_loader" # Move targets @@ -54,6 +55,7 @@ if [ "$BUILD_BINARIES" = true ]; then MOVE_BIN_TARGETS+=" bazel-bin/word_query" MOVE_BIN_TARGETS+=" bazel-bin/word_query_evolution" MOVE_BIN_TARGETS+=" bazel-bin/implication_query_evolution" + MOVE_BIN_TARGETS+=" bazel-bin/evaluation_evolution" MOVE_BIN_TARGETS+=" bazel-bin/tests_db_loader" diff --git a/src/tests/main/BUILD b/src/tests/main/BUILD index 87c833fdb..743cc70d1 100644 --- a/src/tests/main/BUILD +++ b/src/tests/main/BUILD @@ -55,3 +55,15 @@ cc_library( "//service_bus:service_bus_lib", ], ) + +cc_library( + name = "evaluation_evolution_main_lib", + srcs = ["evaluation_evolution.cc"], + deps = [ + "//agents/context_broker:context_broker_lib", + "//agents/evolution:evolution_lib", + "//atomdb:atomdb_singleton", + "//hasher:hasher_lib", + "//service_bus:service_bus_lib", + ], +) diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc new file mode 100644 index 000000000..d1a0219d3 --- /dev/null +++ b/src/tests/main/evaluation_evolution.cc @@ -0,0 +1,791 @@ +#include + +#define LOG_LEVEL LOCAL_DEBUG_LEVEL + +#include +#include +#include +#include + +#include "AtomDBSingleton.h" +#include "AtomSpace.h" +#include "AttentionBrokerClient.h" +#include "Context.h" +#include "ContextBrokerProxy.h" +#include "CountLetterFunction.h" +#include "FitnessFunctionRegistry.h" +#include "Hasher.h" +#include "Logger.h" +#include "MettaParser.h" +#include "commons/atoms/MettaParserActions.h" +#include "QueryAnswer.h" +#include "QueryEvolutionProxy.h" +#include "ServiceBusSingleton.h" +#include "Utils.h" + +#define MAX_QUERY_ANSWERS ((unsigned int) 100000) + +// Symbols +#define AND_OPERATOR "AND" +#define OR_OPERATOR "OR" +#define LINK_TEMPLATE "LINK_TEMPLATE" +#define LINK "LINK" +#define NODE "NODE" +#define VARIABLE "VARIABLE" +#define ATOM "ATOM" +#define EXPRESSION "Expression" +#define SYMBOL "Symbol" +#define SENTENCE "Sentence" +#define WORD "Word" +#define CONTAINS "Contains" +#define EVALUATION "Evaluation" +#define PREDICATE "Predicate" +#define CONCEPT "Concept" +#define EQUIVALENCE "Equivalence" +#define IMPLICATION "Implication" + +// Variables +#define V1 "V1" +#define V2 "V2" +#define V3 "V3" +#define PREDICATE1 "Predicate1" +#define PREDICATE2 "Predicate2" +#define PREDICATE3 "Predicate3" +#define CONCEPT1 "Concept1" +#define CONCEPT2 "Concept2" +#define CONCEPT3 "Concept3" + +// Misc +#define STRENGTH "strength" +#define IS_LITERAL "is_literal" +#define FITNESS_FUNCTION "multiply_strength" + +static string IMPLICATION_HANDLE = Hasher::node_handle(SYMBOL, IMPLICATION); +static string EQUIVALENCE_HANDLE = Hasher::node_handle(SYMBOL, EQUIVALENCE); +static string PREDICATE_HANDLE = Hasher::node_handle(SYMBOL, PREDICATE); +static string EVALUATION_HANDLE = Hasher::node_handle(SYMBOL, EVALUATION); +static float RENT_RATE = 0.25; +static float SPREADING_RATE_LOWERBOUND = 0.90; +static float SPREADING_RATE_UPPERBOUND = 0.90; +static double SELECTION_RATE = 0.10; +static double ELITISM_RATE = 0.08; +static unsigned int LINK_BUILDING_QUERY_SIZE = 150; +static unsigned int POPULATION_SIZE = 50; +static unsigned int MAX_GENERATIONS = 20; +static unsigned int NUM_ITERATIONS = 10; + +static bool SAVE_NEW_LINKS = true; +static string NEW_LINKS_FILE_NAME = "newly_created_links.txt"; +static string CONTEXT_FILE_NAME = "_CONTEXT_DUMP"; + +using namespace std; +using namespace atomdb; +using namespace atom_space; +using namespace query_engine; +using namespace evolution; +using namespace service_bus; +using namespace attention_broker; +using namespace context_broker; + +static shared_ptr db; +static shared_ptr bus; +static vector> buffer_determiners; +static map> weight_calculation_cache; + +static void save_link(Link& link) { + ofstream file; + file.open(NEW_LINKS_FILE_NAME, std::ios::app); + if (file.is_open()) { + vector tokens; + link.tokenize(tokens); + for (unsigned int i = 0; i < tokens.size(); i++) { + file << tokens[i]; + if (i != tokens.size() - 1) { + file << " "; + } + } + file << endl; + file.close(); + } else { + Utils::error("Couldn't open file for writing: " + NEW_LINKS_FILE_NAME); + } +} + +/* +static double get_strength(string handle) { + shared_ptr atom = db->get_atom(handle); + double strength = 0; + if (atom != nullptr) { + strength = atom->custom_attributes.get_or(STRENGTH, 0); + } + return strength; +} +*/ + +static shared_ptr issue_link_building_query( + const vector& query_tokens, const string& context, unsigned int max_answers) { + auto proxy = make_shared(query_tokens, context); + proxy->parameters[BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG] = true; + proxy->parameters[BaseQueryProxy::ATTENTION_UPDATE_FLAG] = false; + // proxy->parameters[BaseQueryProxy::USE_LINK_TEMPLATE_CACHE] = true; // Use the default value + proxy->parameters[PatternMatchingQueryProxy::MAX_ANSWERS] = (unsigned int) max_answers; + proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = true; + proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = false; + proxy->parameters[BaseQueryProxy::POPULATE_METTA_MAPPING] = false; + proxy->parameters[PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG] = true; + + ServiceBusSingleton::get_instance()->issue_bus_command(proxy); + return proxy; +} + +// Fazer um cache que permita lembrar dos handles da resposta do QA e recalcular apenas os counts (que +// dependem dos weight) +static shared_ptr issue_weight_count_query(const vector& query_tokens, + const string& context) { + auto proxy = make_shared(query_tokens, context); + proxy->parameters[BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG] = true; + proxy->parameters[BaseQueryProxy::ATTENTION_UPDATE_FLAG] = false; + proxy->parameters[BaseQueryProxy::USE_LINK_TEMPLATE_CACHE] = true; + proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = false; + proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = false; + proxy->parameters[BaseQueryProxy::POPULATE_METTA_MAPPING] = false; + + ServiceBusSingleton::get_instance()->issue_bus_command(proxy); + return proxy; +} + +static void attention_allocation_query( + const vector& query_tokens, const string& context) { + + auto proxy = make_shared(query_tokens, context); + proxy->parameters[BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG] = true; + proxy->parameters[BaseQueryProxy::ATTENTION_UPDATE_FLAG] = true; + proxy->parameters[BaseQueryProxy::USE_LINK_TEMPLATE_CACHE] = false; + proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = false; + proxy->parameters[PatternMatchingQueryProxy::COUNT_FLAG] = true; + proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = false; + proxy->parameters[BaseQueryProxy::POPULATE_METTA_MAPPING] = false; + + ServiceBusSingleton::get_instance()->issue_bus_command(proxy); + while (!proxy->finished()) { + Utils::sleep(); + } +} + +static void insert_or_update(map& count_map, const string& key, double value) { + auto iterator = count_map.find(key); + if (iterator == count_map.end()) { + count_map[key] = value; + } else { + if (value > iterator->second) { + count_map[key] = value; + } + } +} + +static void compute_counts(const vector>& query_tokens, + const string& context, + const QueryAnswerElement& target_element, + const string& handle0, + const string& handle1, + double& count_0, + double& count_1, + double& count_intersection, + double& count_union) { + LOG_LOCAL_DEBUG("Computing counts for " + handle0 + " and " + handle1); + shared_ptr proxy[2]; + + count_0 = 0.0; + count_1 = 0.0; + count_intersection = 0.0; + count_union = 0.0; + + map count_map[2]; + map count_map_union; + map count_map_intersection; + + double d; + string handle; + for (unsigned int i = 0; i < 2; i++) { + proxy[i] = issue_weight_count_query(query_tokens[i], context); + } + LOG_LOCAL_DEBUG("Queries issued"); + shared_ptr query_answer; + for (unsigned int i = 0; i < 2; i++) { + LOG_LOCAL_DEBUG("i: " + to_string(i)); + ServiceBusSingleton::get_instance()->issue_bus_command(proxy[i]); + while (!proxy[i]->finished()) { + if ((query_answer = proxy[i]->pop()) == NULL) { + Utils::sleep(); + } else { + if (query_answer->handles.size() == 1) { + d = 1.0; + } else { + string link_handle = query_answer->handles[1]; + auto link = db->get_atom(link_handle); + d = link->custom_attributes.get(STRENGTH); + } + handle = query_answer->get(target_element); + insert_or_update(count_map[i], handle, d); + } + } + } + LOG_LOCAL_DEBUG("Query answers processed"); + count_map_union = count_map[0]; + for (auto pair : count_map[1]) { + auto iterator = count_map[0].find(pair.first); + if (iterator == count_map[0].end()) { + insert_or_update(count_map_union, pair.first, pair.second); + } else { + insert_or_update(count_map_union, pair.first, pair.second); + insert_or_update(count_map_intersection, pair.first, min(pair.second, iterator->second)); + } + } + + for (auto pair : count_map_intersection) { + count_intersection += pair.second; + } + for (auto pair : count_map_union) { + count_union += pair.second; + } + for (auto pair : count_map[0]) { + count_0 += pair.second; + } + for (auto pair : count_map[1]) { + count_1 += pair.second; + } + LOG_DEBUG("Counts: " + to_string(count_0) + " " + to_string(count_1) + " " + + to_string(count_intersection) + " " + to_string(count_union)); +} + +static Link add_or_update_link(const string& type_handle, + const string& target1, + const string& target2, + double strength) { + LOG_DEBUG("add_or_update_link(" + type_handle + ", " + target1 + ", " + target2 + ", " + + to_string(strength) + ")"); + Link new_link(EXPRESSION, {type_handle, target1, target2}, true, {{STRENGTH, strength}}); + LOG_DEBUG("Add or update: " + new_link.to_string()); + string handle = new_link.handle(); + if (db->link_exists(handle)) { + auto old_link = db->get_atom(handle); + LOG_DEBUG("Link already exists: " + old_link->to_string()); + if (strength > old_link->custom_attributes.get(STRENGTH)) { + LOG_DEBUG("Updating"); + db->delete_link(handle, false); + db->add_link(&new_link); + if (SAVE_NEW_LINKS) { + save_link(new_link); + } + } + } else { + db->add_link(&new_link); + buffer_determiners.push_back({handle, target1, target2}); + if (SAVE_NEW_LINKS) { + save_link(new_link); + } + } + return new_link; +} + +static Link add_predicate(const string& handle1, const string& handle2) { + Link new_link(EXPRESSION, {handle1, handle2}, false); + if (!db->link_exists(new_link.handle())) { + db->add_link(&new_link); + } + return new_link; +} + +static void build_implication_link(shared_ptr query_answer, const string& context, const string& custom_handle) { + + string predicates[2]; + if (custom_handle == "") { + predicates[0] = query_answer->get(PREDICATE1); + predicates[1] = query_answer->get(PREDICATE2); + } else { + predicates[0] = custom_handle; + predicates[1] = query_answer->get(0); + } + + if (predicates[0] == predicates[1]) { + LOG_DEBUG("Skipping link building because targets are the same: " + predicates[0]); + return; + } + + vector> query; + for (unsigned int i = 0; i < 2; i++) { + // clang-format off + query.push_back({ + OR_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + ATOM, predicates[i], + VARIABLE, CONCEPT1, + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + ATOM, predicates[i], + VARIABLE, CONCEPT2, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EQUIVALENCE, + VARIABLE, CONCEPT2, + VARIABLE, CONCEPT1, + }); + // clang-format on + } + double count_0, count_1, count_intersection, count_union; + QueryAnswerElement target_element(CONCEPT1); + compute_counts(query, + context, + target_element, + predicates[0], + predicates[1], + count_0, + count_1, + count_intersection, + count_union); + if (count_intersection > 0) { + if (count_0 > 0) { + double strength = count_intersection / count_0; + add_or_update_link(IMPLICATION_HANDLE, predicates[0], predicates[1], strength); + } + if (count_1 > 0) { + double strength = count_intersection / count_1; + add_or_update_link(IMPLICATION_HANDLE, predicates[1], predicates[0], strength); + } + } +} + +static void build_and_predicate_link(shared_ptr query_answer, const string& context, const string& custom_handle) { + string predicate1 = query_answer->get(PREDICATE1); + string predicate2 = query_answer->get(PREDICATE2); + string concept1 = query_answer->get(CONCEPT); + + if (predicate1 == predicate2) { + LOG_DEBUG("Skipping link building because targets are the same: " + predicate1); + return; + } + + Link new_predicate = add_predicate(predicate1, predicate2); + add_or_update_link(EVALUATION_HANDLE, new_predicate.handle(), concept1, 1.0); +} + +static void build_equivalence_link(shared_ptr query_answer, const string& context, const string& custom_handle) { + + string concepts[2]; + if (custom_handle == "") { + concepts[0] = query_answer->get(CONCEPT1); + concepts[1] = query_answer->get(CONCEPT2); + } else { + concepts[0] = custom_handle; + concepts[1] = query_answer->get(0); + } + + if (concepts[0] == concepts[1]) { + LOG_DEBUG("Skipping link building because targets are the same: " + concepts[0]); + return; + } + + vector> query; + for (unsigned int i = 0; i < 2; i++) { + // clang-format off + query.push_back({ + OR_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE1, + ATOM, concepts[i], + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE2, + ATOM, concepts[i], + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, IMPLICATION, + VARIABLE, PREDICATE2, + VARIABLE, PREDICATE1, + }); + // clang-format on + } + double count_0, count_1, count_intersection, count_union; + QueryAnswerElement target_element(PREDICATE1); + compute_counts(query, + context, + target_element, + concepts[0], + concepts[1], + count_0, + count_1, + count_intersection, + count_union); + if ((count_intersection > 0) && (count_union > 0)) { + double strength = count_intersection / count_union; + add_or_update_link(EQUIVALENCE_HANDLE, concepts[0], concepts[1], strength); + add_or_update_link(EQUIVALENCE_HANDLE, concepts[1], concepts[0], strength); + } +} + +static void build_links(const vector& query, + const string& context, + unsigned int num_links, + const string& custom_handle, + void (*build_link)(shared_ptr query_answer, + const string& context, + const string& custom_handle)) { + auto proxy = issue_link_building_query(query, context, num_links); + unsigned int count = 0; + shared_ptr query_answer; + while (!proxy->finished()) { + if ((query_answer = proxy->pop()) == nullptr) { + Utils::sleep(); + } else { + if (++count <= num_links) { + if (query_answer->handles.size() == 2) { + LOG_DEBUG("Processing query answer " + to_string(count) + ": " + + query_answer->to_string()); + build_link(query_answer, context, custom_handle); + } + } else { + Utils::sleep(); + if (! proxy->finished()) { + proxy->abort(); + } + break; + } + } + } +} + +static void print_answer(shared_ptr query_answer) { + unsigned int answer_arity = query_answer->handles.size(); + cout << fixed << setw(6) << setprecision(4) << setfill('0'); + cout << query_answer->strength << " [" << to_string(answer_arity) << "]"; + cout << endl; +} + +// clang-format off +static void evolve_chain_query( + const vector& query_to_evolve, + const vector>& correlation_query_template, + const vector>& correlation_query_constants, + const vector>& correlation_mapping, + const string& context) { + + QueryEvolutionProxy* proxy_ptr = new QueryEvolutionProxy( + query_to_evolve, + correlation_query_template, + correlation_query_constants, + correlation_mapping, + context, + FITNESS_FUNCTION); + + shared_ptr proxy(proxy_ptr); + proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = false; + proxy->parameters[BaseQueryProxy::POPULATE_METTA_MAPPING] = false; + proxy->parameters[QueryEvolutionProxy::POPULATION_SIZE] = (unsigned int) POPULATION_SIZE; + proxy->parameters[QueryEvolutionProxy::MAX_GENERATIONS] = (unsigned int) MAX_GENERATIONS; + proxy->parameters[QueryEvolutionProxy::ELITISM_RATE] = (double) ELITISM_RATE; + proxy->parameters[QueryEvolutionProxy::SELECTION_RATE] = (double) SELECTION_RATE; + proxy->parameters[QueryEvolutionProxy::TOTAL_ATTENTION_TOKENS] = (unsigned int) 100000; + proxy->parameters[BaseQueryProxy::MAX_BUNDLE_SIZE] = (unsigned int) 1000; + bus->issue_bus_command(proxy); + + shared_ptr query_answer; + unsigned int count_answers = 0; + static double best_fitness = 0.0; + static unsigned int count_iterations = 1; + + while (!proxy->finished()) { + if ((query_answer = proxy->pop()) == NULL) { + Utils::sleep(); + } else { + count_answers++; + if (query_answer->strength > best_fitness) { + best_fitness = query_answer->strength; + print_answer(query_answer); + } + } + } + cout << "Total answers in iteration " << count_iterations++ << ": " << count_answers << endl; +} +// clang-format on + +static void run(const string& target_predicate_handle, + const string& target_concept_handle, + const string& context_tag) { + + // clang-format off + + vector implication_query = { + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE1, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE2, + VARIABLE, CONCEPT, + }; + + vector equivalence_query = { + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + VARIABLE, CONCEPT1, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + VARIABLE, CONCEPT2, + }; + + vector and_predicate_query = { + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE1, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE2, + VARIABLE, CONCEPT, + }; + + vector query_to_evolve = { + OR_OPERATOR, "3", + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + ATOM, target_predicate_handle, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EQUIVALENCE, + VARIABLE, CONCEPT, + ATOM, target_concept_handle, + AND_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + ATOM, target_concept_handle, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, IMPLICATION, + VARIABLE, PREDICATE, + ATOM, target_predicate_handle, + AND_OPERATOR, "3", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EQUIVALENCE, + VARIABLE, CONCEPT, + ATOM, target_concept_handle, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, IMPLICATION, + VARIABLE, PREDICATE, + ATOM, target_predicate_handle, + }; + + vector> correlation_query_template = {{ + OR_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, V1, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + VARIABLE, V2, + }}; + + vector context_query = { + OR_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, V2, + VARIABLE, V3, + }; + + vector initialization_STI_query = { + OR_OPERATOR, "2", + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + ATOM, target_predicate_handle, + VARIABLE, CONCEPT, + LINK_TEMPLATE, EXPRESSION, "3", + NODE, SYMBOL, EVALUATION, + VARIABLE, PREDICATE, + ATOM, target_concept_handle, + }; + + vector custom_initial_equivalence_query = { + LINK_TEMPLATE, EXPRESSION, "2", + NODE, SYMBOL, CONCEPT, + VARIABLE, V1, + }; + + vector custom_initial_implication_query = { + LINK_TEMPLATE, EXPRESSION, "2", + NODE, SYMBOL, PREDICATE, + VARIABLE, V1, + }; + + QueryAnswerElement qa_predicate(PREDICATE); + QueryAnswerElement qa_concept(CONCEPT); + + vector> correlation_query_constants = { + {{V1, qa_predicate}, {V2, qa_concept}} + }; + + vector>> correlation_mapping = { + {{qa_predicate, qa_predicate}, {qa_concept, qa_concept}} + }; + + // clang-format on + + LOG_INFO("Setting up context for tag: " + context_tag); + QueryAnswerElement target2(V2); + QueryAnswerElement target3(V3); + QueryAnswerElement toplevel_link(0); + // For some reason, make_shared was not compiling so I'm explicitly creating the shared_ptr + shared_ptr context_proxy(new ContextBrokerProxy( + context_tag, context_query, {{toplevel_link, target2}, {toplevel_link, target3}}, {})); + context_proxy->parameters[ContextBrokerProxy::USE_CACHE] = (bool) true; + context_proxy->parameters[ContextBrokerProxy::ENFORCE_CACHE_RECREATION] = (bool) false; + context_proxy->parameters[ContextBrokerProxy::INITIAL_RENT_RATE] = (double) RENT_RATE; + context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_LOWERBOUND] = (double) SPREADING_RATE_LOWERBOUND; + context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_UPPERBOUND] = (double) SPREADING_RATE_UPPERBOUND; + // Issue the ContextBrokerProxy to create context + ServiceBusSingleton::get_instance()->issue_bus_command(context_proxy); + // Wait for ContextBrokerProxy to finish context creation + LOG_INFO("Waiting for context creation to finish..."); + while (!context_proxy->is_context_created()) { + Utils::sleep(); + } + string context = context_proxy->get_key(); + LOG_INFO("Context " + context + " is ready"); + + LOG_INFO("Pre-processing..."); + LOG_INFO("Initializing STI"); + attention_allocation_query(initialization_STI_query, context); + LOG_INFO("Building initial custom links"); + build_links(custom_initial_equivalence_query, context, 0, target_concept_handle, build_equivalence_link); + build_links(custom_initial_implication_query, context, 0, target_predicate_handle, build_implication_link); + LOG_INFO("Pre-processing complete"); + + for (unsigned int i = 0; i < NUM_ITERATIONS; i++) { + LOG_INFO("--------------------------------------------------------------------------------"); + LOG_INFO("Iteration " + to_string(i + 1)); + LOG_INFO("--------------------------------------------------------------------------------"); + LOG_INFO("----- Building links"); + LOG_DEBUG("AND predicates"); + build_links(and_predicate_query, context, LINK_BUILDING_QUERY_SIZE, "", build_and_predicate_link); + LOG_DEBUG("Equivalence"); + build_links(equivalence_query, context, LINK_BUILDING_QUERY_SIZE, "", build_equivalence_link); + LOG_DEBUG("Implication"); + build_links(implication_query, context, LINK_BUILDING_QUERY_SIZE, "", build_implication_link); + LOG_INFO("----- Updating AttentionBroker"); + AttentionBrokerClient::set_determiners(buffer_determiners, context); + buffer_determiners.clear(); + LOG_INFO("----- Evolving query"); + evolve_chain_query(query_to_evolve, + correlation_query_template, + correlation_query_constants, + correlation_mapping[0], + context); + } +} + +void insert_type_symbols() { + vector to_insert = {EQUIVALENCE, IMPLICATION}; + Node* node; + for (string node_name : to_insert) { + node = new Node(SYMBOL, node_name); + if (!db->node_exists(node->handle())) { + db->add_node(node); + } + delete (node); + } +} + +int main(int argc, char* argv[]) { + // clang-format off + if (argc != 15) { + cerr << "Usage: " << argv[0] + << " " + " " + " " + " " << endl; + cerr << endl; + cerr << " are MeTTa expressions" << endl; + cerr << endl; + cerr << endl; + cerr << "Suggested safe parameters:" << endl; + cerr << endl; + cerr << " RENT_RATE: 0.25" << endl; + cerr << " SPREADING_RATE_LOWERBOUND: 0.90" << endl; + cerr << " SPREADING_RATE_UPPERBOUND: 0.90" << endl; + cerr << " ELITISM_RATE: 0.08" << endl; + cerr << " SELECTION_RATE: 0.10" << endl; + cerr << " POPULATION_SIZE: 500" << endl; + cerr << " MAX_GENERATIONS: 20" << endl; + cerr << " NUM_ITERATIONS: 10" << endl; + exit(1); + } + // clang-format on + + unsigned int cursor = 0; + + string client_endpoint = argv[++cursor]; + string server_endpoint = argv[++cursor]; + auto ports_range = Utils::parse_ports_range(argv[++cursor]); + + string context_tag = argv[++cursor]; + string target_predicate = argv[++cursor]; + string target_concept = argv[++cursor]; + + RENT_RATE = Utils::string_to_float(string(argv[++cursor])); + SPREADING_RATE_LOWERBOUND = Utils::string_to_float(string(argv[++cursor])); + SPREADING_RATE_UPPERBOUND = Utils::string_to_float(string(argv[++cursor])); + + ELITISM_RATE = (double) Utils::string_to_float(string(argv[++cursor])); + SELECTION_RATE = (double) Utils::string_to_float(string(argv[++cursor])); + POPULATION_SIZE = (unsigned int) Utils::string_to_int(string(argv[++cursor])); + MAX_GENERATIONS = (unsigned int) Utils::string_to_int(string(argv[++cursor])); + NUM_ITERATIONS = (unsigned int) Utils::string_to_int(string(argv[++cursor])); + + if (cursor != 14) { + Utils::error("Error setting up parameters"); + } + + AtomDBSingleton::init(); + db = AtomDBSingleton::get_instance(); + ServiceBusSingleton::init(client_endpoint, server_endpoint, ports_range.first, ports_range.second); + FitnessFunctionRegistry::initialize_statics(); + bus = ServiceBusSingleton::get_instance(); + AttentionBrokerClient::set_parameters(RENT_RATE, SPREADING_RATE_LOWERBOUND, SPREADING_RATE_UPPERBOUND); + insert_type_symbols(); + + LOG_INFO("ELITISM_RATE: " + to_string(ELITISM_RATE)); + LOG_INFO("RENT_RATE: " + to_string(RENT_RATE)); + LOG_INFO("SPREADING_RATE_LOWERBOUND: " + to_string(SPREADING_RATE_LOWERBOUND)); + LOG_INFO("SPREADING_RATE_UPPERBOUND: " + to_string(SPREADING_RATE_UPPERBOUND)); + LOG_INFO("ELITISM_RATE: " + to_string(ELITISM_RATE)); + LOG_INFO("SELECTION_RATE: " + to_string(SELECTION_RATE)); + LOG_INFO("POPULATION_SIZE: " + to_string(POPULATION_SIZE)); + LOG_INFO("MAX_GENERATIONS: " + to_string(MAX_GENERATIONS)); + LOG_INFO("NUM_ITERATIONS: " + to_string(NUM_ITERATIONS)); + + shared_ptr predicate_pa = make_shared(); + shared_ptr concept_pa = make_shared(); + MettaParser predicate_p(target_predicate, predicate_pa); + MettaParser concept_p(target_concept, concept_pa); + + LOG_INFO("Target predicate: " + target_predicate + " Handle: " + predicate_pa->metta_expression_handle); + LOG_INFO("Target concept: " + target_concept + " Handle: " + concept_pa->metta_expression_handle); + + run(predicate_pa->metta_expression_handle, concept_pa->metta_expression_handle, context_tag); + + return 0; +} From d349fcd90b7e0efbc8767475fcba81fbb90b9cc9 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Fri, 30 Jan 2026 09:36:52 -0300 Subject: [PATCH 02/22] WIP --- src/tests/main/evaluation_evolution.cc | 31 ++++++++++++++++++-------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index d1a0219d3..2832c3252 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -74,8 +74,11 @@ static unsigned int POPULATION_SIZE = 50; static unsigned int MAX_GENERATIONS = 20; static unsigned int NUM_ITERATIONS = 10; -static bool SAVE_NEW_LINKS = true; static string NEW_LINKS_FILE_NAME = "newly_created_links.txt"; +static bool WRITE_CREATED_LINKS_TO_DB = false; +static bool WRITE_CREATED_LINKS_TO_FILE = true; +static bool PRINT_CREATED_LINKS_METTA = true; + static string CONTEXT_FILE_NAME = "_CONTEXT_DUMP"; using namespace std; @@ -266,22 +269,32 @@ static Link add_or_update_link(const string& type_handle, to_string(strength) + ")"); Link new_link(EXPRESSION, {type_handle, target1, target2}, true, {{STRENGTH, strength}}); LOG_DEBUG("Add or update: " + new_link.to_string()); + if (PRINT_CREATED_LINKS_METTA) { + LOG_INFO("ADD LINK: " + new_link.metta_representation(*static_pointer_cast(db).get())); + } string handle = new_link.handle(); if (db->link_exists(handle)) { auto old_link = db->get_atom(handle); LOG_DEBUG("Link already exists: " + old_link->to_string()); if (strength > old_link->custom_attributes.get(STRENGTH)) { - LOG_DEBUG("Updating"); - db->delete_link(handle, false); - db->add_link(&new_link); - if (SAVE_NEW_LINKS) { + if (WRITE_CREATED_LINKS_TO_DB) { + LOG_DEBUG("Updating Link in AtomDB"); + db->delete_link(handle, false); + db->add_link(&new_link); + } + if (WRITE_CREATED_LINKS_TO_FILE) { + LOG_DEBUG("Writing Link to file: " + NEW_LINKS_FILE_NAME); save_link(new_link); } } } else { - db->add_link(&new_link); + if (WRITE_CREATED_LINKS_TO_DB) { + LOG_DEBUG("Creating Link in AtomDB"); + db->add_link(&new_link); + } buffer_determiners.push_back({handle, target1, target2}); - if (SAVE_NEW_LINKS) { + if (WRITE_CREATED_LINKS_TO_FILE) { + LOG_DEBUG("Writing Link to file: " + NEW_LINKS_FILE_NAME); save_link(new_link); } } @@ -464,7 +477,7 @@ static void print_answer(shared_ptr query_answer) { } // clang-format off -static void evolve_chain_query( +static void query_evolution( const vector& query_to_evolve, const vector>& correlation_query_template, const vector>& correlation_query_constants, @@ -689,7 +702,7 @@ static void run(const string& target_predicate_handle, AttentionBrokerClient::set_determiners(buffer_determiners, context); buffer_determiners.clear(); LOG_INFO("----- Evolving query"); - evolve_chain_query(query_to_evolve, + query_evolution(query_to_evolve, correlation_query_template, correlation_query_constants, correlation_mapping[0], From 12793908ebb4d2264ae1931f5c1a7b5d2f085694 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 2 Feb 2026 10:45:42 -0300 Subject: [PATCH 03/22] WIP --- src/tests/main/evaluation_evolution.cc | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index 2832c3252..c06c8cce6 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -74,13 +74,12 @@ static unsigned int POPULATION_SIZE = 50; static unsigned int MAX_GENERATIONS = 20; static unsigned int NUM_ITERATIONS = 10; +static string CONTEXT_FILE_NAME = "_CONTEXT_DUMP"; static string NEW_LINKS_FILE_NAME = "newly_created_links.txt"; static bool WRITE_CREATED_LINKS_TO_DB = false; static bool WRITE_CREATED_LINKS_TO_FILE = true; static bool PRINT_CREATED_LINKS_METTA = true; -static string CONTEXT_FILE_NAME = "_CONTEXT_DUMP"; - using namespace std; using namespace atomdb; using namespace atom_space; @@ -613,7 +612,6 @@ static void run(const string& target_predicate_handle, }}; vector context_query = { - OR_OPERATOR, "2", LINK_TEMPLATE, EXPRESSION, "3", NODE, SYMBOL, EVALUATION, VARIABLE, V2, @@ -724,12 +722,12 @@ void insert_type_symbols() { int main(int argc, char* argv[]) { // clang-format off - if (argc != 15) { + if (argc < 15) { cerr << "Usage: " << argv[0] << " " " " " " - " " << endl; + " [--use-mork]" << endl; cerr << endl; cerr << " are MeTTa expressions" << endl; cerr << endl; @@ -748,7 +746,7 @@ int main(int argc, char* argv[]) { } // clang-format on - unsigned int cursor = 0; + int cursor = 0; string client_endpoint = argv[++cursor]; string server_endpoint = argv[++cursor]; @@ -772,7 +770,12 @@ int main(int argc, char* argv[]) { Utils::error("Error setting up parameters"); } - AtomDBSingleton::init(); + if ((++cursor < argc) && (string(argv[cursor]) == string("--use-mork"))) { + AtomDBSingleton::init(atomdb_api_types::ATOMDB_TYPE::MORKDB); + } else { + AtomDBSingleton::init(); + } + db = AtomDBSingleton::get_instance(); ServiceBusSingleton::init(client_endpoint, server_endpoint, ports_range.first, ports_range.second); FitnessFunctionRegistry::initialize_statics(); @@ -794,6 +797,8 @@ int main(int argc, char* argv[]) { shared_ptr concept_pa = make_shared(); MettaParser predicate_p(target_predicate, predicate_pa); MettaParser concept_p(target_concept, concept_pa); + predicate_p.parse(); + concept_p.parse(); LOG_INFO("Target predicate: " + target_predicate + " Handle: " + predicate_pa->metta_expression_handle); LOG_INFO("Target concept: " + target_concept + " Handle: " + concept_pa->metta_expression_handle); From d8352da3eed35c193d42c37a437809a71036c504 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 2 Feb 2026 14:47:30 -0300 Subject: [PATCH 04/22] WIP --- src/agents/query_engine/MettaParserActions.cc | 1 + .../query_engine/PatternMatchingQueryProcessor.cc | 1 + src/agents/query_engine/PatternMatchingQueryProxy.cc | 2 ++ src/agents/query_engine/PatternMatchingQueryProxy.h | 4 ++++ src/agents/query_engine/query_element/LinkTemplate.cc | 10 +++++++++- src/agents/query_engine/query_element/LinkTemplate.h | 2 ++ 6 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/agents/query_engine/MettaParserActions.cc b/src/agents/query_engine/MettaParserActions.cc index aa4731668..3794aba21 100644 --- a/src/agents/query_engine/MettaParserActions.cc +++ b/src/agents/query_engine/MettaParserActions.cc @@ -129,6 +129,7 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre targets, this->proxy->get_context(), this->proxy->parameters.get(PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG), + this->proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), this->proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), this->proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE))); } diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index 2a20a067f..22b53272c 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -343,6 +343,7 @@ shared_ptr PatternMatchingQueryProcessor::build_link_template( targets, proxy->get_context(), proxy->parameters.get(PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG), + proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); return link_template; diff --git a/src/agents/query_engine/PatternMatchingQueryProxy.cc b/src/agents/query_engine/PatternMatchingQueryProxy.cc index 0460fc4dc..0170c5d43 100644 --- a/src/agents/query_engine/PatternMatchingQueryProxy.cc +++ b/src/agents/query_engine/PatternMatchingQueryProxy.cc @@ -13,6 +13,7 @@ using namespace query_engine; string PatternMatchingQueryProxy::COUNT = "count"; string PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG = "positive_importance_flag"; +string PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG = "disregard_importance_flag"; string PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG = "unique_value_flag"; string PatternMatchingQueryProxy::COUNT_FLAG = "count_flag"; @@ -32,6 +33,7 @@ PatternMatchingQueryProxy::PatternMatchingQueryProxy(const vector& token void PatternMatchingQueryProxy::set_default_parameters() { this->parameters[POSITIVE_IMPORTANCE_FLAG] = false; + this->parameters[DISREGARD_IMPORTANCE_FLAG] = false; this->parameters[UNIQUE_VALUE_FLAG] = false; this->parameters[COUNT_FLAG] = false; } diff --git a/src/agents/query_engine/PatternMatchingQueryProxy.h b/src/agents/query_engine/PatternMatchingQueryProxy.h index 65ebd944e..ae139c4c5 100644 --- a/src/agents/query_engine/PatternMatchingQueryProxy.h +++ b/src/agents/query_engine/PatternMatchingQueryProxy.h @@ -35,6 +35,10 @@ class PatternMatchingQueryProxy : public BaseQueryProxy { static string POSITIVE_IMPORTANCE_FLAG; // Indicates that only answers whose importance > 0 // are supposed to be returned + static string DISREGARD_IMPORTANCE_FLAG; // When set true, importance values are not fetched from + // Attention Broker, thus the order of query answers + // are not determined by importance. + static string UNIQUE_VALUE_FLAG; // When true, QueryAnswers won't be allowed to have the same // handle assigned to different values. For instance, if a // variable V1 is assigned to a handle H1, if this parameter diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 8f3996d6e..1d09d89aa 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -21,12 +21,17 @@ LinkTemplate::LinkTemplate(const string& type, const vector>& targets, const string& context, bool positive_importance_flag, + bool disregard_importance_flag, bool unique_value_flag, bool use_cache) : link_schema(type, targets.size()) { this->targets = targets; this->context = context; + if (positive_importance_flag && disregard_importance_flag) { + Utils::error("Conficting settings for positive_importance_flag and disregard_importance_flag"); + } this->positive_importance_flag = positive_importance_flag; + this->disregard_importance_flag = disregard_importance_flag; this->unique_value_flag = unique_value_flag; this->use_cache = use_cache; this->inner_flag = true; @@ -136,6 +141,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { LinkTemplate::fetched_links_cache().set(link_schema_handle, handles); } LOG_DEBUG("Positive importance flag: " + string(this->positive_importance_flag ? "true" : "false")); + LOG_DEBUG("Disregard importance flag: " + string(this->disregard_importance_flag ? "true" : "false")); LOG_DEBUG("Unique value flag: " + string(this->unique_value_flag ? "true" : "false")); LOG_INFO("Fetched " + std::to_string(handles->size()) + " atoms in " + link_schema_handle); @@ -146,7 +152,9 @@ void LinkTemplate::processor_method(shared_ptr monitor) { while ((handle = iterator->next()) != nullptr) { tagged_handles.push_back(make_pair((char*) handle, 0)); } - compute_importance(tagged_handles); + if (! this->disregard_importance_flag) { + compute_importance(tagged_handles); + } } unsigned int pending = tagged_handles.size(); unsigned int cursor = 0; diff --git a/src/agents/query_engine/query_element/LinkTemplate.h b/src/agents/query_engine/query_element/LinkTemplate.h index a4e50980b..75d3988e5 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.h +++ b/src/agents/query_engine/query_element/LinkTemplate.h @@ -54,6 +54,7 @@ class LinkTemplate : public QueryElement { vector> targets; string context; bool positive_importance_flag; + bool disregard_importance_flag; bool unique_value_flag; bool use_cache; bool inner_flag; @@ -74,6 +75,7 @@ class LinkTemplate : public QueryElement { const vector>& targets, const string& context, bool positive_importance_flag, + bool disregard_importance_flag, bool unique_value_flag, bool use_cache); From 914b95a613803cd43c8e5d96c70907540763593d Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 2 Feb 2026 14:57:01 -0300 Subject: [PATCH 05/22] WIP --- src/agents/context_broker/ContextBrokerProcessor.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/context_broker/ContextBrokerProcessor.cc b/src/agents/context_broker/ContextBrokerProcessor.cc index 3000282ed..9ff65342d 100644 --- a/src/agents/context_broker/ContextBrokerProcessor.cc +++ b/src/agents/context_broker/ContextBrokerProcessor.cc @@ -122,8 +122,8 @@ void ContextBrokerProcessor::create_context(shared_ptr monitor, proxy->parameters.get_or(BaseQueryProxy::ATTENTION_UPDATE_FLAG, false); pattern_proxy->parameters[BaseQueryProxy::USE_LINK_TEMPLATE_CACHE] = proxy->parameters.get_or(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE, false); - pattern_proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = - proxy->parameters.get_or(PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG, false); + pattern_proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = false; + pattern_proxy->parameters[PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG] = true; pattern_proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = proxy->parameters.get_or(BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS, false); From 2d298193559cf8d0746976f7ebeb90176957f1b0 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 3 Feb 2026 11:09:26 -0300 Subject: [PATCH 06/22] WIP --- src/agents/query_engine/MettaParserActions.cc | 8 ++++++-- src/agents/query_engine/MettaParserActions.h | 1 + .../query_engine/PatternMatchingQueryProcessor.cc | 13 +++++++++++-- .../query_engine/PatternMatchingQueryProcessor.h | 3 ++- .../query_engine/query_element/LinkTemplate.cc | 1 + .../query_engine/query_element/LinkTemplate.h | 2 ++ 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/agents/query_engine/MettaParserActions.cc b/src/agents/query_engine/MettaParserActions.cc index 3794aba21..4d7abc240 100644 --- a/src/agents/query_engine/MettaParserActions.cc +++ b/src/agents/query_engine/MettaParserActions.cc @@ -26,6 +26,7 @@ MettaParserActions::MettaParserActions(shared_ptr pro this->proxy = proxy; this->current_expression_size = 0; this->current_expression_type = LINK; + this->count_open_expression = 0; } MettaParserActions::~MettaParserActions() {} @@ -97,6 +98,7 @@ void MettaParserActions::expression_begin() { this->expression_type_stack.push(this->current_expression_type); this->current_expression_size = 0; this->current_expression_type = LINK; + this->count_open_expression++; } void MettaParserActions::expression_end(bool toplevel, const string& metta_expression) { @@ -124,14 +126,16 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre this->element_stack.push(make_shared(MettaMapping::EXPRESSION_LINK_TYPE, targets)); } else { LOG_DEBUG("Pushing LINK_TEMPLATE"); - this->element_stack.push(make_shared( + auto new_link_template = make_shared( MettaMapping::EXPRESSION_LINK_TYPE, targets, this->proxy->get_context(), this->proxy->parameters.get(PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG), this->proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), this->proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), - this->proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE))); + this->proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); + new_link_template->flat_pattern_flag = (this->count_open_expression == 1); + this->element_stack.push(new_link_template); } } else if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) { if (element_stack.size() >= 2) { diff --git a/src/agents/query_engine/MettaParserActions.h b/src/agents/query_engine/MettaParserActions.h index c76314e88..2646c3695 100644 --- a/src/agents/query_engine/MettaParserActions.h +++ b/src/agents/query_engine/MettaParserActions.h @@ -68,6 +68,7 @@ class MettaParserActions : public ParserActions { ExpressionType current_expression_type; stack expression_size_stack; stack expression_type_stack; + unsigned int count_open_expression; }; } // namespace query_engine diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index 22b53272c..61c1c3dc6 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -263,6 +263,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( unsigned int cursor = 0; const vector query_tokens = proxy->get_query_tokens(); unsigned int tokens_count = query_tokens.size(); + unsigned int count_nested_elements = 0; while (cursor < tokens_count) { execution_stack.push(cursor); @@ -277,7 +278,13 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } else { Utils::error("Invalid token in query: " + query_tokens[cursor]); } + if ((query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) || + (query_tokens[cursor] == OR) || + (query_tokens[cursor] == AND)) { + count_nested_elements++; + } } + bool flat_pattern_flag = (count_nested_elements == 1); if (cursor != tokens_count) { Utils::error("Parse error in query tokens"); @@ -298,7 +305,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } else if (query_tokens[cursor] == LinkSchema::LINK) { element_stack.push(build_link(proxy, cursor, element_stack)); } else if (query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) { - element_stack.push(build_link_template(proxy, cursor, element_stack)); + element_stack.push(build_link_template(proxy, cursor, element_stack, flat_pattern_flag)); } else if (query_tokens[cursor] == AND) { element_stack.push(build_and(proxy, cursor, element_stack)); if (proxy->parameters.get(BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG)) { @@ -325,7 +332,8 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( shared_ptr PatternMatchingQueryProcessor::build_link_template( shared_ptr proxy, unsigned int cursor, - stack>& element_stack) { + stack>& element_stack, + bool flat_pattern_flag) { const vector query_tokens = proxy->get_query_tokens(); unsigned int arity = std::stoi(query_tokens[cursor + 2]); if (element_stack.size() < arity) { @@ -346,6 +354,7 @@ shared_ptr PatternMatchingQueryProcessor::build_link_template( proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); + link_template->flat_pattern_flag = flat_pattern_flag; return link_template; } diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.h b/src/agents/query_engine/PatternMatchingQueryProcessor.h index 3f30b6ec1..066b98601 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.h +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.h @@ -57,7 +57,8 @@ class PatternMatchingQueryProcessor : public BusCommandProcessor { shared_ptr proxy); shared_ptr build_link_template(shared_ptr proxy, unsigned int cursor, - stack>& element_stack); + stack>& element_stack, + bool flat_pattern_flag); shared_ptr build_link_template2(shared_ptr proxy, unsigned int cursor, diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 1d09d89aa..e9f2a6e94 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -39,6 +39,7 @@ LinkTemplate::LinkTemplate(const string& type, this->processor = nullptr; this->random_generator = new std::mt19937(std::chrono::system_clock::now().time_since_epoch().count()); + this->flat_pattern_flag = false; } LinkTemplate::~LinkTemplate() { diff --git a/src/agents/query_engine/query_element/LinkTemplate.h b/src/agents/query_engine/query_element/LinkTemplate.h index 75d3988e5..e95b9636c 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.h +++ b/src/agents/query_engine/query_element/LinkTemplate.h @@ -105,5 +105,7 @@ class LinkTemplate : public QueryElement { * Empty implementation. There are no QueryNode element or local thread to shut down. */ virtual void graceful_shutdown() {} + + bool flat_pattern_flag; }; } // namespace query_element From 5b9d3262eca825c5ccca0634b1c74c42cf16721d Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 3 Feb 2026 11:22:26 -0300 Subject: [PATCH 07/22] WIP --- src/agents/query_engine/query_element/LinkTemplate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index e9f2a6e94..34de8dac1 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -167,7 +167,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { pending = 0; } else { if (tagged_handle.second > 0 || !this->positive_importance_flag) { - if (db->allow_nested_indexing()) { + if (db->allow_nested_indexing() || this->flat_pattern_flag) { this->source_element->add_handle( tagged_handle.first, tagged_handle.second, From e2e8af90c8dbc9e07e2592f7ca9d84896fbc38f8 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 3 Feb 2026 12:21:45 -0300 Subject: [PATCH 08/22] WIP --- src/agents/query_engine/query_element/LinkTemplate.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 34de8dac1..96a4aea04 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -158,6 +158,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { } } unsigned int pending = tagged_handles.size(); + unsigned int processed = 0; unsigned int cursor = 0; Assignment assignment(this->unique_value_flag); unsigned int count_matched = 0; @@ -181,6 +182,9 @@ void LinkTemplate::processor_method(shared_ptr monitor) { count_matched++; } } + if (! (++processed % 1000000)) { + LOG_INFO("Processed " + std::to_string(processed++) + "/" + std::to_string(tagged_handles.size()) + ". " + std::to_string(count_matched) + " matched so far."); + } pending--; } } From 60f8d20cab2d484fbd086b5d02f338702fe0f91a Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Wed, 4 Feb 2026 09:16:29 -0300 Subject: [PATCH 09/22] WIP --- src/agents/query_engine/query_element/LinkTemplate.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 96a4aea04..c00f516a6 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -8,7 +8,7 @@ #include "AttentionBrokerClient.h" #include "Terminal.h" -#define LOG_LEVEL INFO_LEVEL +#define LOG_LEVEL DEBUG_LEVEL #include "Logger.h" using namespace query_element; @@ -144,6 +144,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { LOG_DEBUG("Positive importance flag: " + string(this->positive_importance_flag ? "true" : "false")); LOG_DEBUG("Disregard importance flag: " + string(this->disregard_importance_flag ? "true" : "false")); LOG_DEBUG("Unique value flag: " + string(this->unique_value_flag ? "true" : "false")); + LOG_DEBUG("Flat pattern flag: " + string(this->flat_pattern_flag ? "true" : "false")); LOG_INFO("Fetched " + std::to_string(handles->size()) + " atoms in " + link_schema_handle); vector> tagged_handles; @@ -183,7 +184,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { } } if (! (++processed % 1000000)) { - LOG_INFO("Processed " + std::to_string(processed++) + "/" + std::to_string(tagged_handles.size()) + ". " + std::to_string(count_matched) + " matched so far."); + LOG_INFO("Processed " + std::to_string(processed) + "/" + std::to_string(tagged_handles.size()) + ". " + std::to_string(count_matched) + " matched so far."); } pending--; } From 6b3c3fde75e32b1e7b8a525cd7f80a5c1e58ebbb Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Thu, 5 Feb 2026 11:58:59 -0300 Subject: [PATCH 10/22] WIP --- src/agents/context_broker/ContextBrokerProcessor.cc | 2 +- src/agents/query_engine/MettaParserActions.cc | 2 +- src/agents/query_engine/PatternMatchingQueryProcessor.cc | 3 ++- src/agents/query_engine/query_element/LinkTemplate.h | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/agents/context_broker/ContextBrokerProcessor.cc b/src/agents/context_broker/ContextBrokerProcessor.cc index 9ff65342d..f4f26567e 100644 --- a/src/agents/context_broker/ContextBrokerProcessor.cc +++ b/src/agents/context_broker/ContextBrokerProcessor.cc @@ -8,7 +8,7 @@ #include "ServiceBus.h" #include "ServiceBusSingleton.h" -#define LOG_LEVEL INFO_LEVEL +#define LOG_LEVEL DEBUG_LEVEL #include "Logger.h" using namespace context_broker; diff --git a/src/agents/query_engine/MettaParserActions.cc b/src/agents/query_engine/MettaParserActions.cc index 4d7abc240..617d16fb7 100644 --- a/src/agents/query_engine/MettaParserActions.cc +++ b/src/agents/query_engine/MettaParserActions.cc @@ -134,7 +134,7 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre this->proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), this->proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), this->proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); - new_link_template->flat_pattern_flag = (this->count_open_expression == 1); + new_link_template->set_flat_pattern_flag(this->count_open_expression == 1); this->element_stack.push(new_link_template); } } else if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) { diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index 61c1c3dc6..51394910b 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -285,6 +285,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } } bool flat_pattern_flag = (count_nested_elements == 1); + LOG_DEBUG("count_nested_elements: " + count_nested_elements); if (cursor != tokens_count) { Utils::error("Parse error in query tokens"); @@ -354,7 +355,7 @@ shared_ptr PatternMatchingQueryProcessor::build_link_template( proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); - link_template->flat_pattern_flag = flat_pattern_flag; + link_template->set_flat_pattern_flag(flat_pattern_flag); return link_template; } diff --git a/src/agents/query_engine/query_element/LinkTemplate.h b/src/agents/query_engine/query_element/LinkTemplate.h index e95b9636c..f100394b5 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.h +++ b/src/agents/query_engine/query_element/LinkTemplate.h @@ -58,6 +58,7 @@ class LinkTemplate : public QueryElement { bool unique_value_flag; bool use_cache; bool inner_flag; + bool flat_pattern_flag; LinkSchema link_schema; shared_ptr source_element; shared_ptr processor; @@ -106,6 +107,6 @@ class LinkTemplate : public QueryElement { */ virtual void graceful_shutdown() {} - bool flat_pattern_flag; + void set_flat_pattern_flag(bool value) {this->flat_pattern_flag = value;} }; } // namespace query_element From 3220ce05609754a93b57e39c52e6177d3bf9a86d Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Thu, 5 Feb 2026 12:27:56 -0300 Subject: [PATCH 11/22] WIP --- src/agents/query_engine/MettaParserActions.cc | 3 --- src/agents/query_engine/MettaParserActions.h | 1 - .../query_engine/PatternMatchingQueryProcessor.cc | 10 ++-------- .../query_engine/PatternMatchingQueryProcessor.h | 3 +-- .../query_engine/query_element/LinkTemplate.cc | 13 ++++++++++--- .../query_engine/query_element/LinkTemplate.h | 2 -- .../query_engine/query_element/QueryElement.cc | 1 + .../query_engine/query_element/QueryElement.h | 1 + 8 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/agents/query_engine/MettaParserActions.cc b/src/agents/query_engine/MettaParserActions.cc index 617d16fb7..f17899bce 100644 --- a/src/agents/query_engine/MettaParserActions.cc +++ b/src/agents/query_engine/MettaParserActions.cc @@ -26,7 +26,6 @@ MettaParserActions::MettaParserActions(shared_ptr pro this->proxy = proxy; this->current_expression_size = 0; this->current_expression_type = LINK; - this->count_open_expression = 0; } MettaParserActions::~MettaParserActions() {} @@ -98,7 +97,6 @@ void MettaParserActions::expression_begin() { this->expression_type_stack.push(this->current_expression_type); this->current_expression_size = 0; this->current_expression_type = LINK; - this->count_open_expression++; } void MettaParserActions::expression_end(bool toplevel, const string& metta_expression) { @@ -134,7 +132,6 @@ void MettaParserActions::expression_end(bool toplevel, const string& metta_expre this->proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), this->proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), this->proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); - new_link_template->set_flat_pattern_flag(this->count_open_expression == 1); this->element_stack.push(new_link_template); } } else if ((this->current_expression_type == AND) || (this->current_expression_type == OR)) { diff --git a/src/agents/query_engine/MettaParserActions.h b/src/agents/query_engine/MettaParserActions.h index 2646c3695..c76314e88 100644 --- a/src/agents/query_engine/MettaParserActions.h +++ b/src/agents/query_engine/MettaParserActions.h @@ -68,7 +68,6 @@ class MettaParserActions : public ParserActions { ExpressionType current_expression_type; stack expression_size_stack; stack expression_type_stack; - unsigned int count_open_expression; }; } // namespace query_engine diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index 51394910b..d48500844 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -263,7 +263,6 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( unsigned int cursor = 0; const vector query_tokens = proxy->get_query_tokens(); unsigned int tokens_count = query_tokens.size(); - unsigned int count_nested_elements = 0; while (cursor < tokens_count) { execution_stack.push(cursor); @@ -281,11 +280,8 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( if ((query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) || (query_tokens[cursor] == OR) || (query_tokens[cursor] == AND)) { - count_nested_elements++; } } - bool flat_pattern_flag = (count_nested_elements == 1); - LOG_DEBUG("count_nested_elements: " + count_nested_elements); if (cursor != tokens_count) { Utils::error("Parse error in query tokens"); @@ -306,7 +302,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } else if (query_tokens[cursor] == LinkSchema::LINK) { element_stack.push(build_link(proxy, cursor, element_stack)); } else if (query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) { - element_stack.push(build_link_template(proxy, cursor, element_stack, flat_pattern_flag)); + 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)); if (proxy->parameters.get(BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG)) { @@ -333,8 +329,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( shared_ptr PatternMatchingQueryProcessor::build_link_template( shared_ptr proxy, unsigned int cursor, - stack>& element_stack, - bool flat_pattern_flag) { + stack>& element_stack) { const vector query_tokens = proxy->get_query_tokens(); unsigned int arity = std::stoi(query_tokens[cursor + 2]); if (element_stack.size() < arity) { @@ -355,7 +350,6 @@ shared_ptr PatternMatchingQueryProcessor::build_link_template( proxy->parameters.get(PatternMatchingQueryProxy::DISREGARD_IMPORTANCE_FLAG), proxy->parameters.get(PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG), proxy->parameters.get(BaseQueryProxy::USE_LINK_TEMPLATE_CACHE)); - link_template->set_flat_pattern_flag(flat_pattern_flag); return link_template; } diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.h b/src/agents/query_engine/PatternMatchingQueryProcessor.h index 066b98601..3f30b6ec1 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.h +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.h @@ -57,8 +57,7 @@ class PatternMatchingQueryProcessor : public BusCommandProcessor { shared_ptr proxy); shared_ptr build_link_template(shared_ptr proxy, unsigned int cursor, - stack>& element_stack, - bool flat_pattern_flag); + stack>& element_stack); shared_ptr build_link_template2(shared_ptr proxy, unsigned int cursor, diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index c00f516a6..09ca76dea 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -39,7 +39,13 @@ LinkTemplate::LinkTemplate(const string& type, this->processor = nullptr; this->random_generator = new std::mt19937(std::chrono::system_clock::now().time_since_epoch().count()); - this->flat_pattern_flag = false; + unsigned int max_reverse_nesting = 0; + for (auto element: targets) { + if (element->reverse_nesting_level > max_reverse_nesting) { + max_reverse_nesting = element->reverse_nesting_level; + } + } + this->reverse_nesting_level = max_reverse_nesting + 1; } LinkTemplate::~LinkTemplate() { @@ -141,10 +147,11 @@ void LinkTemplate::processor_method(shared_ptr monitor) { handles = db->query_for_pattern(this->link_schema); LinkTemplate::fetched_links_cache().set(link_schema_handle, handles); } + bool flat_pattern_flag = (this->reverse_nesting_level <= 1); LOG_DEBUG("Positive importance flag: " + string(this->positive_importance_flag ? "true" : "false")); LOG_DEBUG("Disregard importance flag: " + string(this->disregard_importance_flag ? "true" : "false")); LOG_DEBUG("Unique value flag: " + string(this->unique_value_flag ? "true" : "false")); - LOG_DEBUG("Flat pattern flag: " + string(this->flat_pattern_flag ? "true" : "false")); + LOG_DEBUG("Flat pattern flag: " + string(flat_pattern_flag ? "true" : "false")); LOG_INFO("Fetched " + std::to_string(handles->size()) + " atoms in " + link_schema_handle); vector> tagged_handles; @@ -169,7 +176,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { pending = 0; } else { if (tagged_handle.second > 0 || !this->positive_importance_flag) { - if (db->allow_nested_indexing() || this->flat_pattern_flag) { + if (db->allow_nested_indexing() || flat_pattern_flag) { this->source_element->add_handle( tagged_handle.first, tagged_handle.second, diff --git a/src/agents/query_engine/query_element/LinkTemplate.h b/src/agents/query_engine/query_element/LinkTemplate.h index f100394b5..f206f01f1 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.h +++ b/src/agents/query_engine/query_element/LinkTemplate.h @@ -58,7 +58,6 @@ class LinkTemplate : public QueryElement { bool unique_value_flag; bool use_cache; bool inner_flag; - bool flat_pattern_flag; LinkSchema link_schema; shared_ptr source_element; shared_ptr processor; @@ -107,6 +106,5 @@ class LinkTemplate : public QueryElement { */ virtual void graceful_shutdown() {} - void set_flat_pattern_flag(bool value) {this->flat_pattern_flag = value;} }; } // namespace query_element diff --git a/src/agents/query_engine/query_element/QueryElement.cc b/src/agents/query_engine/query_element/QueryElement.cc index 0fa348e2e..cb1881b6f 100644 --- a/src/agents/query_engine/query_element/QueryElement.cc +++ b/src/agents/query_engine/query_element/QueryElement.cc @@ -10,6 +10,7 @@ QueryElement::QueryElement() { this->is_terminal = false; this->is_operator = false; this->arity = 0; + this->reverse_nesting_level = 0; } QueryElement::~QueryElement() {} diff --git a/src/agents/query_engine/query_element/QueryElement.h b/src/agents/query_engine/query_element/QueryElement.h index 566b25c64..3012095db 100644 --- a/src/agents/query_engine/query_element/QueryElement.h +++ b/src/agents/query_engine/query_element/QueryElement.h @@ -53,6 +53,7 @@ class QueryElement { string id; string subsequent_id; unsigned int arity; + unsigned int reverse_nesting_level; /** * Basic constructor which solely initialize variables. From ac8af6130c2e1ce64d1cfe7a8009d6be5d61f623 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Thu, 5 Feb 2026 12:44:46 -0300 Subject: [PATCH 12/22] WIP --- src/agents/query_engine/query_element/LinkTemplate.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 09ca76dea..aa87f3e92 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -176,14 +176,14 @@ void LinkTemplate::processor_method(shared_ptr monitor) { pending = 0; } else { if (tagged_handle.second > 0 || !this->positive_importance_flag) { - if (db->allow_nested_indexing() || flat_pattern_flag) { + if (db->allow_nested_indexing()) { this->source_element->add_handle( tagged_handle.first, tagged_handle.second, handles->get_assignments_by_handle(tagged_handle.first), handles->get_metta_expressions_by_handle(tagged_handle.first)); count_matched++; - } else if (this->link_schema.match(string(tagged_handle.first), assignment, *db.get())) { + } else if (flat_pattern_flag || this->link_schema.match(string(tagged_handle.first), assignment, *db.get())) { this->source_element->add_handle( tagged_handle.first, tagged_handle.second, assignment); assignment.clear(); From 9f6090317ea5ebb4befdc75be076cadda4d8c44f Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Thu, 5 Feb 2026 13:58:46 -0300 Subject: [PATCH 13/22] WIP --- .../query_element/LinkTemplate.cc | 12 +++++---- src/commons/atoms/LinkSchema.cc | 27 ++++++++++++------- src/commons/atoms/LinkSchema.h | 3 ++- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index aa87f3e92..0f2b96bb2 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -183,11 +183,13 @@ void LinkTemplate::processor_method(shared_ptr monitor) { handles->get_assignments_by_handle(tagged_handle.first), handles->get_metta_expressions_by_handle(tagged_handle.first)); count_matched++; - } else if (flat_pattern_flag || this->link_schema.match(string(tagged_handle.first), assignment, *db.get())) { - this->source_element->add_handle( - tagged_handle.first, tagged_handle.second, assignment); - assignment.clear(); - count_matched++; + } else { + bool matched = (flat_pattern_flag ? this->link_schema.match_flat_pattern(string(tagged_handle.first), assignment, *db.get()) : this->link_schema.match(string(tagged_handle.first), assignment, *db.get())); + if (matched) { + this->source_element->add_handle(tagged_handle.first, tagged_handle.second, assignment); + assignment.clear(); + count_matched++; + } } } if (! (++processed % 1000000)) { diff --git a/src/commons/atoms/LinkSchema.cc b/src/commons/atoms/LinkSchema.cc index f41d44497..628b4bf00 100644 --- a/src/commons/atoms/LinkSchema.cc +++ b/src/commons/atoms/LinkSchema.cc @@ -154,7 +154,8 @@ unsigned int LinkSchema::arity() const { return this->_arity; } bool LinkSchema::SchemaElement::match(const string& handle, Assignment& assignment, HandleDecoder& decoder, - Atom* atom_ptr) { + Atom* atom_ptr, + bool flat_pattern_flag) { LOG_DEBUG((handle != "" ? "Matching handle: " + handle : "Matching atom " + atom_ptr->to_string())); shared_ptr atom; if (this->is_link) { @@ -170,14 +171,18 @@ bool LinkSchema::SchemaElement::match(const string& handle, atom_ptr = (Link*) atom.get(); } if (Atom::is_link(*atom_ptr) && (atom_ptr->arity() == this->targets.size())) { - unsigned int cursor = 0; - for (string target_handle : ((Link*) atom_ptr)->targets) { - if (!this->targets[cursor++].match(target_handle, assignment, decoder, NULL)) { - LOG_DEBUG("Target[" + std::to_string(cursor - 1) + "] mismatches. NO MATCH."); - return false; + if (flat_pattern_flag) { + LOG_DEBUG("Flat pattern. MATCH."); + } else { + unsigned int cursor = 0; + for (string target_handle : ((Link*) atom_ptr)->targets) { + if (!this->targets[cursor++].match(target_handle, assignment, decoder, NULL, false)) { + LOG_DEBUG("Target[" + std::to_string(cursor - 1) + "] mismatches. NO MATCH."); + return false; + } } + LOG_DEBUG("All targets matched. MATCH."); } - LOG_DEBUG("All targets matched. MATCH."); return true; } else { LOG_DEBUG("Atom isn't a link or has wrong arity. NO MATCH."); @@ -196,11 +201,15 @@ bool LinkSchema::SchemaElement::match(const string& handle, } bool LinkSchema::match(Link& link, Assignment& assignment, HandleDecoder& decoder) { - return this->_schema_element.match("", assignment, decoder, &link); + return this->_schema_element.match("", assignment, decoder, &link, false); } bool LinkSchema::match(const string& handle, Assignment& assignment, HandleDecoder& decoder) { - return this->_schema_element.match(handle, assignment, decoder, NULL); + return this->_schema_element.match(handle, assignment, decoder, NULL, false); +} + +bool LinkSchema::match_flat_pattern(const string& handle, Assignment& assignment, HandleDecoder& decoder) { + return this->_schema_element.match(handle, assignment, decoder, NULL, true); } // ------------------------------------------------------------------------------------------------- diff --git a/src/commons/atoms/LinkSchema.h b/src/commons/atoms/LinkSchema.h index 7df7d0cb6..1d4abc077 100644 --- a/src/commons/atoms/LinkSchema.h +++ b/src/commons/atoms/LinkSchema.h @@ -20,7 +20,7 @@ class LinkSchema : public Wildcard { bool is_link; bool is_wildcard; SchemaElement() : is_link(false), is_wildcard(false) {} - bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder, Atom* atom_ptr); + bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder, Atom* atom_ptr, bool flat_pattern_flag); }; bool _frozen; unsigned int _arity; @@ -164,6 +164,7 @@ class LinkSchema : public Wildcard { bool match(Link& link, Assignment& assignment, HandleDecoder& decoder); bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder) override; + bool match_flat_pattern(const string& handle, Assignment& assignment, HandleDecoder& decoder); // --------------------------------------------------------------------------------------------- // Public API to build LinkSchema objects From 6d0c5eaf4ef722de7d590a3a189a08a17f35d06d Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Thu, 5 Feb 2026 14:52:10 -0300 Subject: [PATCH 14/22] WIP --- .../query_element/LinkTemplate.cc | 3 +-- src/commons/atoms/LinkSchema.cc | 27 +++++++------------ src/commons/atoms/LinkSchema.h | 3 +-- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 0f2b96bb2..f93010892 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -184,8 +184,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { handles->get_metta_expressions_by_handle(tagged_handle.first)); count_matched++; } else { - bool matched = (flat_pattern_flag ? this->link_schema.match_flat_pattern(string(tagged_handle.first), assignment, *db.get()) : this->link_schema.match(string(tagged_handle.first), assignment, *db.get())); - if (matched) { + if (this->link_schema.match(string(tagged_handle.first), assignment, *db.get())) { this->source_element->add_handle(tagged_handle.first, tagged_handle.second, assignment); assignment.clear(); count_matched++; diff --git a/src/commons/atoms/LinkSchema.cc b/src/commons/atoms/LinkSchema.cc index 628b4bf00..f41d44497 100644 --- a/src/commons/atoms/LinkSchema.cc +++ b/src/commons/atoms/LinkSchema.cc @@ -154,8 +154,7 @@ unsigned int LinkSchema::arity() const { return this->_arity; } bool LinkSchema::SchemaElement::match(const string& handle, Assignment& assignment, HandleDecoder& decoder, - Atom* atom_ptr, - bool flat_pattern_flag) { + Atom* atom_ptr) { LOG_DEBUG((handle != "" ? "Matching handle: " + handle : "Matching atom " + atom_ptr->to_string())); shared_ptr atom; if (this->is_link) { @@ -171,18 +170,14 @@ bool LinkSchema::SchemaElement::match(const string& handle, atom_ptr = (Link*) atom.get(); } if (Atom::is_link(*atom_ptr) && (atom_ptr->arity() == this->targets.size())) { - if (flat_pattern_flag) { - LOG_DEBUG("Flat pattern. MATCH."); - } else { - unsigned int cursor = 0; - for (string target_handle : ((Link*) atom_ptr)->targets) { - if (!this->targets[cursor++].match(target_handle, assignment, decoder, NULL, false)) { - LOG_DEBUG("Target[" + std::to_string(cursor - 1) + "] mismatches. NO MATCH."); - return false; - } + unsigned int cursor = 0; + for (string target_handle : ((Link*) atom_ptr)->targets) { + if (!this->targets[cursor++].match(target_handle, assignment, decoder, NULL)) { + LOG_DEBUG("Target[" + std::to_string(cursor - 1) + "] mismatches. NO MATCH."); + return false; } - LOG_DEBUG("All targets matched. MATCH."); } + LOG_DEBUG("All targets matched. MATCH."); return true; } else { LOG_DEBUG("Atom isn't a link or has wrong arity. NO MATCH."); @@ -201,15 +196,11 @@ bool LinkSchema::SchemaElement::match(const string& handle, } bool LinkSchema::match(Link& link, Assignment& assignment, HandleDecoder& decoder) { - return this->_schema_element.match("", assignment, decoder, &link, false); + return this->_schema_element.match("", assignment, decoder, &link); } bool LinkSchema::match(const string& handle, Assignment& assignment, HandleDecoder& decoder) { - return this->_schema_element.match(handle, assignment, decoder, NULL, false); -} - -bool LinkSchema::match_flat_pattern(const string& handle, Assignment& assignment, HandleDecoder& decoder) { - return this->_schema_element.match(handle, assignment, decoder, NULL, true); + return this->_schema_element.match(handle, assignment, decoder, NULL); } // ------------------------------------------------------------------------------------------------- diff --git a/src/commons/atoms/LinkSchema.h b/src/commons/atoms/LinkSchema.h index 1d4abc077..7df7d0cb6 100644 --- a/src/commons/atoms/LinkSchema.h +++ b/src/commons/atoms/LinkSchema.h @@ -20,7 +20,7 @@ class LinkSchema : public Wildcard { bool is_link; bool is_wildcard; SchemaElement() : is_link(false), is_wildcard(false) {} - bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder, Atom* atom_ptr, bool flat_pattern_flag); + bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder, Atom* atom_ptr); }; bool _frozen; unsigned int _arity; @@ -164,7 +164,6 @@ class LinkSchema : public Wildcard { bool match(Link& link, Assignment& assignment, HandleDecoder& decoder); bool match(const string& handle, Assignment& assignment, HandleDecoder& decoder) override; - bool match_flat_pattern(const string& handle, Assignment& assignment, HandleDecoder& decoder); // --------------------------------------------------------------------------------------------- // Public API to build LinkSchema objects From 23a1897fcf4ea1ead3cb2c93446f358710086b16 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Fri, 6 Feb 2026 12:24:40 -0300 Subject: [PATCH 15/22] WIP --- src/attention_broker/AttentionBrokerClient.cc | 1 + src/attention_broker/AttentionBrokerServer.cc | 2 +- src/attention_broker/AttentionBrokerServer.h | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/attention_broker/AttentionBrokerClient.cc b/src/attention_broker/AttentionBrokerClient.cc index 426fe91b1..30f17a6ab 100644 --- a/src/attention_broker/AttentionBrokerClient.cc +++ b/src/attention_broker/AttentionBrokerClient.cc @@ -120,6 +120,7 @@ void AttentionBrokerClient::set_determiners(const vector>& handle request.clear_list(); handle_count = 0; } + Utils::sleep(10000); } void AttentionBrokerClient::get_importance(const vector& handles, diff --git a/src/attention_broker/AttentionBrokerServer.cc b/src/attention_broker/AttentionBrokerServer.cc index 43c82c16c..d2f890bd1 100644 --- a/src/attention_broker/AttentionBrokerServer.cc +++ b/src/attention_broker/AttentionBrokerServer.cc @@ -2,7 +2,7 @@ #include "RequestSelector.h" -#define LOG_LEVEL INFO_LEVEL +#define LOG_LEVEL DEBUG_LEVEL #include "Logger.h" using namespace attention_broker; diff --git a/src/attention_broker/AttentionBrokerServer.h b/src/attention_broker/AttentionBrokerServer.h index 695a23b54..80b1e8f4a 100644 --- a/src/attention_broker/AttentionBrokerServer.h +++ b/src/attention_broker/AttentionBrokerServer.h @@ -1,7 +1,5 @@ #pragma once -#define DEBUG - #include #include From 9c2a622fc1293c4b4937469eb0754df4a98b9e83 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 9 Feb 2026 11:08:09 -0300 Subject: [PATCH 16/22] WIP --- src/attention_broker/AttentionBrokerClient.cc | 1 - src/attention_broker/AttentionBrokerServer.cc | 2 +- src/tests/main/evaluation_evolution.cc | 10 +++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/attention_broker/AttentionBrokerClient.cc b/src/attention_broker/AttentionBrokerClient.cc index 30f17a6ab..426fe91b1 100644 --- a/src/attention_broker/AttentionBrokerClient.cc +++ b/src/attention_broker/AttentionBrokerClient.cc @@ -120,7 +120,6 @@ void AttentionBrokerClient::set_determiners(const vector>& handle request.clear_list(); handle_count = 0; } - Utils::sleep(10000); } void AttentionBrokerClient::get_importance(const vector& handles, diff --git a/src/attention_broker/AttentionBrokerServer.cc b/src/attention_broker/AttentionBrokerServer.cc index d2f890bd1..43c82c16c 100644 --- a/src/attention_broker/AttentionBrokerServer.cc +++ b/src/attention_broker/AttentionBrokerServer.cc @@ -2,7 +2,7 @@ #include "RequestSelector.h" -#define LOG_LEVEL DEBUG_LEVEL +#define LOG_LEVEL INFO_LEVEL #include "Logger.h" using namespace attention_broker; diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index c06c8cce6..159dcf714 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -1,6 +1,6 @@ #include -#define LOG_LEVEL LOCAL_DEBUG_LEVEL +#define LOG_LEVEL INFO_LEVEL #include #include @@ -69,7 +69,7 @@ static float SPREADING_RATE_LOWERBOUND = 0.90; static float SPREADING_RATE_UPPERBOUND = 0.90; static double SELECTION_RATE = 0.10; static double ELITISM_RATE = 0.08; -static unsigned int LINK_BUILDING_QUERY_SIZE = 150; +static unsigned int LINK_BUILDING_QUERY_SIZE = 50; static unsigned int POPULATION_SIZE = 50; static unsigned int MAX_GENERATIONS = 20; static unsigned int NUM_ITERATIONS = 10; @@ -690,11 +690,11 @@ static void run(const string& target_predicate_handle, LOG_INFO("Iteration " + to_string(i + 1)); LOG_INFO("--------------------------------------------------------------------------------"); LOG_INFO("----- Building links"); - LOG_DEBUG("AND predicates"); + LOG_INFO("Building AND predicates"); build_links(and_predicate_query, context, LINK_BUILDING_QUERY_SIZE, "", build_and_predicate_link); - LOG_DEBUG("Equivalence"); + LOG_INFO("Building Equivalence links"); build_links(equivalence_query, context, LINK_BUILDING_QUERY_SIZE, "", build_equivalence_link); - LOG_DEBUG("Implication"); + LOG_INFO("Building Implication links"); build_links(implication_query, context, LINK_BUILDING_QUERY_SIZE, "", build_implication_link); LOG_INFO("----- Updating AttentionBroker"); AttentionBrokerClient::set_determiners(buffer_determiners, context); From 2eef1408a95181e2ed411b69386a1aba88132149 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 9 Feb 2026 11:13:01 -0300 Subject: [PATCH 17/22] WIP --- src/tests/main/evaluation_evolution.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index 159dcf714..26b9e197c 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -76,7 +76,7 @@ static unsigned int NUM_ITERATIONS = 10; static string CONTEXT_FILE_NAME = "_CONTEXT_DUMP"; static string NEW_LINKS_FILE_NAME = "newly_created_links.txt"; -static bool WRITE_CREATED_LINKS_TO_DB = false; +static bool WRITE_CREATED_LINKS_TO_DB = true; static bool WRITE_CREATED_LINKS_TO_FILE = true; static bool PRINT_CREATED_LINKS_METTA = true; From d8aa5a8b797be1242be1da2003474c4f2365fd03 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 9 Feb 2026 12:35:12 -0300 Subject: [PATCH 18/22] WIP --- src/tests/main/evaluation_evolution.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index 26b9e197c..c4e6ed991 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -131,7 +131,7 @@ static shared_ptr issue_link_building_query( proxy->parameters[BaseQueryProxy::ATTENTION_UPDATE_FLAG] = false; // proxy->parameters[BaseQueryProxy::USE_LINK_TEMPLATE_CACHE] = true; // Use the default value proxy->parameters[PatternMatchingQueryProxy::MAX_ANSWERS] = (unsigned int) max_answers; - proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = true; + proxy->parameters[PatternMatchingQueryProxy::POSITIVE_IMPORTANCE_FLAG] = (max_answers != 0); proxy->parameters[BaseQueryProxy::USE_METTA_AS_QUERY_TOKENS] = false; proxy->parameters[BaseQueryProxy::POPULATE_METTA_MAPPING] = false; proxy->parameters[PatternMatchingQueryProxy::UNIQUE_VALUE_FLAG] = true; From 4b06324694ad8e873fe48adc69e96b7e538a7f4a Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Mon, 9 Feb 2026 15:35:08 -0300 Subject: [PATCH 19/22] Update unit tests to new LinkTemplate constructor --- src/tests/cpp/iterator_test.cc | 2 +- src/tests/cpp/link_template_test.cc | 2 +- src/tests/cpp/nested_link_template_test.cc | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tests/cpp/iterator_test.cc b/src/tests/cpp/iterator_test.cc index f0cc63d11..cf89dd6fb 100644 --- a/src/tests/cpp/iterator_test.cc +++ b/src/tests/cpp/iterator_test.cc @@ -84,7 +84,7 @@ TEST(Iterator, link_template_integration) { auto human = make_shared(symbol, "\"human\""); LinkTemplate* link_template = - new LinkTemplate("Expression", {similarity, human, v1}, "", false, false, false); + new LinkTemplate("Expression", {similarity, human, v1}, "", false, false, false, false); link_template->build(); Iterator query_answer_iterator(link_template->get_source_element()); diff --git a/src/tests/cpp/link_template_test.cc b/src/tests/cpp/link_template_test.cc index 30bea8f16..30794f5d1 100644 --- a/src/tests/cpp/link_template_test.cc +++ b/src/tests/cpp/link_template_test.cc @@ -30,7 +30,7 @@ TEST(LinkTemplate, basics) { similarity->handle = Hasher::node_handle(symbol, "Similarity"); auto human = make_shared(symbol, "\"human\""); - LinkTemplate link_template1("Expression", {similarity, human, v1}, "", false, false, false); + LinkTemplate link_template1("Expression", {similarity, human, v1}, "", false, false, false, false); link_template1.build(); link_template1.get_source_element()->subsequent_id = server_node_id; link_template1.get_source_element()->setup_buffers(); diff --git a/src/tests/cpp/nested_link_template_test.cc b/src/tests/cpp/nested_link_template_test.cc index 086568da2..083b13ccb 100644 --- a/src/tests/cpp/nested_link_template_test.cc +++ b/src/tests/cpp/nested_link_template_test.cc @@ -28,10 +28,10 @@ TEST(LinkTemplate, basics) { auto odd_link = make_shared(symbol, "OddLink"); LinkTemplate* inner_template_ptr = - new LinkTemplate(expression, {similarity, v1, v2}, "", false, false, false); + new LinkTemplate(expression, {similarity, v1, v2}, "", false, false, false, false); shared_ptr inner_template(inner_template_ptr); LinkTemplate* outter_template_ptr = - new LinkTemplate(expression, {odd_link, inner_template}, "", false, false, false); + new LinkTemplate(expression, {odd_link, inner_template}, "", false, false, false, false); outter_template_ptr->build(); Iterator iterator(outter_template_ptr->get_source_element()); @@ -59,13 +59,13 @@ TEST(LinkTemplate, nested_variables) { auto human = make_shared(symbol, "\"human\""); LinkTemplate* inner_template_ptr = - new LinkTemplate(expression, {similarity, v1, v2}, "", false, false, false); + new LinkTemplate(expression, {similarity, v1, v2}, "", false, false, false, false); shared_ptr inner_template(inner_template_ptr); LinkTemplate* outter_template = - new LinkTemplate(expression, {odd_link, inner_template}, "", false, false, false); + new LinkTemplate(expression, {odd_link, inner_template}, "", false, false, false, false); outter_template->build(); LinkTemplate* human_template = - new LinkTemplate(expression, {similarity, v1, human}, "", false, false, false); + new LinkTemplate(expression, {similarity, v1, human}, "", false, false, false, false); human_template->build(); auto and_operator = make_shared>(array, 2>( {human_template->get_source_element(), outter_template->get_source_element()})); From 49a5866c7afd053b8ce3708fd7aded6d808a5397 Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 10 Feb 2026 11:01:00 -0300 Subject: [PATCH 20/22] Format fixes --- .../PatternMatchingQueryProcessor.cc | 3 +- .../query_engine/PatternMatchingQueryProxy.h | 30 +++++----- .../query_element/LinkTemplate.cc | 16 +++-- .../query_engine/query_element/LinkTemplate.h | 1 - src/tests/main/evaluation_evolution.cc | 59 +++++++++++-------- 5 files changed, 60 insertions(+), 49 deletions(-) diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index d48500844..f163ba5b6 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -277,8 +277,7 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } else { Utils::error("Invalid token in query: " + query_tokens[cursor]); } - if ((query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) || - (query_tokens[cursor] == OR) || + if ((query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) || (query_tokens[cursor] == OR) || (query_tokens[cursor] == AND)) { } } diff --git a/src/agents/query_engine/PatternMatchingQueryProxy.h b/src/agents/query_engine/PatternMatchingQueryProxy.h index ae139c4c5..f9b4c6632 100644 --- a/src/agents/query_engine/PatternMatchingQueryProxy.h +++ b/src/agents/query_engine/PatternMatchingQueryProxy.h @@ -32,21 +32,21 @@ class PatternMatchingQueryProxy : public BaseQueryProxy { static string COUNT; // Delivery of the final result of a count_only query // Query command's optional parameters - static string POSITIVE_IMPORTANCE_FLAG; // Indicates that only answers whose importance > 0 - // are supposed to be returned - - static string DISREGARD_IMPORTANCE_FLAG; // When set true, importance values are not fetched from - // Attention Broker, thus the order of query answers - // are not determined by importance. - - static string UNIQUE_VALUE_FLAG; // When true, QueryAnswers won't be allowed to have the same - // handle assigned to different values. For instance, if a - // variable V1 is assigned to a handle H1, if this parameter - // is true then it's assured that no other variable will be - // assigned with the same value H1. When this parameter is - // false (which is the default value, btw), it's possible - // to have a QueryAnswer with an assignment like this, for - // example: V1: H1, V2: H2, V3, H1. + static string POSITIVE_IMPORTANCE_FLAG; // Indicates that only answers whose importance > 0 + // are supposed to be returned + + static string DISREGARD_IMPORTANCE_FLAG; // When set true, importance values are not fetched from + // Attention Broker, thus the order of query answers + // are not determined by importance. + + static string UNIQUE_VALUE_FLAG; // When true, QueryAnswers won't be allowed to have the same + // handle assigned to different values. For instance, if a + // variable V1 is assigned to a handle H1, if this parameter + // is true then it's assured that no other variable will be + // assigned with the same value H1. When this parameter is + // false (which is the default value, btw), it's possible + // to have a QueryAnswer with an assignment like this, for + // example: V1: H1, V2: H2, V3, H1. static string COUNT_FLAG; // Indicates that this query is supposed to count the results and not // actually provide the query answers (i.e. no QueryAnswer is sent diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index f93010892..1e23b9aaf 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -40,7 +40,7 @@ LinkTemplate::LinkTemplate(const string& type, this->random_generator = new std::mt19937(std::chrono::system_clock::now().time_since_epoch().count()); unsigned int max_reverse_nesting = 0; - for (auto element: targets) { + for (auto element : targets) { if (element->reverse_nesting_level > max_reverse_nesting) { max_reverse_nesting = element->reverse_nesting_level; } @@ -149,7 +149,8 @@ void LinkTemplate::processor_method(shared_ptr monitor) { } bool flat_pattern_flag = (this->reverse_nesting_level <= 1); LOG_DEBUG("Positive importance flag: " + string(this->positive_importance_flag ? "true" : "false")); - LOG_DEBUG("Disregard importance flag: " + string(this->disregard_importance_flag ? "true" : "false")); + LOG_DEBUG("Disregard importance flag: " + + string(this->disregard_importance_flag ? "true" : "false")); LOG_DEBUG("Unique value flag: " + string(this->unique_value_flag ? "true" : "false")); LOG_DEBUG("Flat pattern flag: " + string(flat_pattern_flag ? "true" : "false")); LOG_INFO("Fetched " + std::to_string(handles->size()) + " atoms in " + link_schema_handle); @@ -161,7 +162,7 @@ void LinkTemplate::processor_method(shared_ptr monitor) { while ((handle = iterator->next()) != nullptr) { tagged_handles.push_back(make_pair((char*) handle, 0)); } - if (! this->disregard_importance_flag) { + if (!this->disregard_importance_flag) { compute_importance(tagged_handles); } } @@ -185,14 +186,17 @@ void LinkTemplate::processor_method(shared_ptr monitor) { count_matched++; } else { if (this->link_schema.match(string(tagged_handle.first), assignment, *db.get())) { - this->source_element->add_handle(tagged_handle.first, tagged_handle.second, assignment); + this->source_element->add_handle( + tagged_handle.first, tagged_handle.second, assignment); assignment.clear(); count_matched++; } } } - if (! (++processed % 1000000)) { - LOG_INFO("Processed " + std::to_string(processed) + "/" + std::to_string(tagged_handles.size()) + ". " + std::to_string(count_matched) + " matched so far."); + if (!(++processed % 1000000)) { + LOG_INFO("Processed " + std::to_string(processed) + "/" + + std::to_string(tagged_handles.size()) + ". " + std::to_string(count_matched) + + " matched so far."); } pending--; } diff --git a/src/agents/query_engine/query_element/LinkTemplate.h b/src/agents/query_engine/query_element/LinkTemplate.h index 73c1e5e9d..38651581b 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.h +++ b/src/agents/query_engine/query_element/LinkTemplate.h @@ -106,6 +106,5 @@ class LinkTemplate : public QueryElement { * Empty implementation. There are no QueryNode element or local thread to shut down. */ virtual void graceful_shutdown() {} - }; } // namespace query_element diff --git a/src/tests/main/evaluation_evolution.cc b/src/tests/main/evaluation_evolution.cc index c4e6ed991..73d2a6fc6 100644 --- a/src/tests/main/evaluation_evolution.cc +++ b/src/tests/main/evaluation_evolution.cc @@ -17,11 +17,11 @@ #include "Hasher.h" #include "Logger.h" #include "MettaParser.h" -#include "commons/atoms/MettaParserActions.h" #include "QueryAnswer.h" #include "QueryEvolutionProxy.h" #include "ServiceBusSingleton.h" #include "Utils.h" +#include "commons/atoms/MettaParserActions.h" #define MAX_QUERY_ANSWERS ((unsigned int) 100000) @@ -156,9 +156,7 @@ static shared_ptr issue_weight_count_query(const vect return proxy; } -static void attention_allocation_query( - const vector& query_tokens, const string& context) { - +static void attention_allocation_query(const vector& query_tokens, const string& context) { auto proxy = make_shared(query_tokens, context); proxy->parameters[BaseQueryProxy::UNIQUE_ASSIGNMENT_FLAG] = true; proxy->parameters[BaseQueryProxy::ATTENTION_UPDATE_FLAG] = true; @@ -269,7 +267,8 @@ static Link add_or_update_link(const string& type_handle, Link new_link(EXPRESSION, {type_handle, target1, target2}, true, {{STRENGTH, strength}}); LOG_DEBUG("Add or update: " + new_link.to_string()); if (PRINT_CREATED_LINKS_METTA) { - LOG_INFO("ADD LINK: " + new_link.metta_representation(*static_pointer_cast(db).get())); + LOG_INFO("ADD LINK: " + + new_link.metta_representation(*static_pointer_cast(db).get())); } string handle = new_link.handle(); if (db->link_exists(handle)) { @@ -308,8 +307,9 @@ static Link add_predicate(const string& handle1, const string& handle2) { return new_link; } -static void build_implication_link(shared_ptr query_answer, const string& context, const string& custom_handle) { - +static void build_implication_link(shared_ptr query_answer, + const string& context, + const string& custom_handle) { string predicates[2]; if (custom_handle == "") { predicates[0] = query_answer->get(PREDICATE1); @@ -368,7 +368,9 @@ static void build_implication_link(shared_ptr query_answer, const s } } -static void build_and_predicate_link(shared_ptr query_answer, const string& context, const string& custom_handle) { +static void build_and_predicate_link(shared_ptr query_answer, + const string& context, + const string& custom_handle) { string predicate1 = query_answer->get(PREDICATE1); string predicate2 = query_answer->get(PREDICATE2); string concept1 = query_answer->get(CONCEPT); @@ -382,8 +384,9 @@ static void build_and_predicate_link(shared_ptr query_answer, const add_or_update_link(EVALUATION_HANDLE, new_predicate.handle(), concept1, 1.0); } -static void build_equivalence_link(shared_ptr query_answer, const string& context, const string& custom_handle) { - +static void build_equivalence_link(shared_ptr query_answer, + const string& context, + const string& custom_handle) { string concepts[2]; if (custom_handle == "") { concepts[0] = query_answer->get(CONCEPT1); @@ -439,10 +442,10 @@ static void build_equivalence_link(shared_ptr query_answer, const s static void build_links(const vector& query, const string& context, - unsigned int num_links, + unsigned int num_links, const string& custom_handle, void (*build_link)(shared_ptr query_answer, - const string& context, + const string& context, const string& custom_handle)) { auto proxy = issue_link_building_query(query, context, num_links); unsigned int count = 0; @@ -459,7 +462,7 @@ static void build_links(const vector& query, } } else { Utils::sleep(); - if (! proxy->finished()) { + if (!proxy->finished()) { proxy->abort(); } break; @@ -525,7 +528,6 @@ static void query_evolution( static void run(const string& target_predicate_handle, const string& target_concept_handle, const string& context_tag) { - // clang-format off vector implication_query = { @@ -665,8 +667,10 @@ static void run(const string& target_predicate_handle, context_proxy->parameters[ContextBrokerProxy::USE_CACHE] = (bool) true; context_proxy->parameters[ContextBrokerProxy::ENFORCE_CACHE_RECREATION] = (bool) false; context_proxy->parameters[ContextBrokerProxy::INITIAL_RENT_RATE] = (double) RENT_RATE; - context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_LOWERBOUND] = (double) SPREADING_RATE_LOWERBOUND; - context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_UPPERBOUND] = (double) SPREADING_RATE_UPPERBOUND; + context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_LOWERBOUND] = + (double) SPREADING_RATE_LOWERBOUND; + context_proxy->parameters[ContextBrokerProxy::INITIAL_SPREADING_RATE_UPPERBOUND] = + (double) SPREADING_RATE_UPPERBOUND; // Issue the ContextBrokerProxy to create context ServiceBusSingleton::get_instance()->issue_bus_command(context_proxy); // Wait for ContextBrokerProxy to finish context creation @@ -681,8 +685,10 @@ static void run(const string& target_predicate_handle, LOG_INFO("Initializing STI"); attention_allocation_query(initialization_STI_query, context); LOG_INFO("Building initial custom links"); - build_links(custom_initial_equivalence_query, context, 0, target_concept_handle, build_equivalence_link); - build_links(custom_initial_implication_query, context, 0, target_predicate_handle, build_implication_link); + build_links( + custom_initial_equivalence_query, context, 0, target_concept_handle, build_equivalence_link); + build_links( + custom_initial_implication_query, context, 0, target_predicate_handle, build_implication_link); LOG_INFO("Pre-processing complete"); for (unsigned int i = 0; i < NUM_ITERATIONS; i++) { @@ -691,7 +697,8 @@ static void run(const string& target_predicate_handle, LOG_INFO("--------------------------------------------------------------------------------"); LOG_INFO("----- Building links"); LOG_INFO("Building AND predicates"); - build_links(and_predicate_query, context, LINK_BUILDING_QUERY_SIZE, "", build_and_predicate_link); + build_links( + and_predicate_query, context, LINK_BUILDING_QUERY_SIZE, "", build_and_predicate_link); LOG_INFO("Building Equivalence links"); build_links(equivalence_query, context, LINK_BUILDING_QUERY_SIZE, "", build_equivalence_link); LOG_INFO("Building Implication links"); @@ -701,10 +708,10 @@ static void run(const string& target_predicate_handle, buffer_determiners.clear(); LOG_INFO("----- Evolving query"); query_evolution(query_to_evolve, - correlation_query_template, - correlation_query_constants, - correlation_mapping[0], - context); + correlation_query_template, + correlation_query_constants, + correlation_mapping[0], + context); } } @@ -780,7 +787,8 @@ int main(int argc, char* argv[]) { ServiceBusSingleton::init(client_endpoint, server_endpoint, ports_range.first, ports_range.second); FitnessFunctionRegistry::initialize_statics(); bus = ServiceBusSingleton::get_instance(); - AttentionBrokerClient::set_parameters(RENT_RATE, SPREADING_RATE_LOWERBOUND, SPREADING_RATE_UPPERBOUND); + AttentionBrokerClient::set_parameters( + RENT_RATE, SPREADING_RATE_LOWERBOUND, SPREADING_RATE_UPPERBOUND); insert_type_symbols(); LOG_INFO("ELITISM_RATE: " + to_string(ELITISM_RATE)); @@ -800,7 +808,8 @@ int main(int argc, char* argv[]) { predicate_p.parse(); concept_p.parse(); - LOG_INFO("Target predicate: " + target_predicate + " Handle: " + predicate_pa->metta_expression_handle); + LOG_INFO("Target predicate: " + target_predicate + + " Handle: " + predicate_pa->metta_expression_handle); LOG_INFO("Target concept: " + target_concept + " Handle: " + concept_pa->metta_expression_handle); run(predicate_pa->metta_expression_handle, concept_pa->metta_expression_handle, context_tag); From 7a43e40ab71a38c4db2a5a65bdf1fcdb6b8a5cbe Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 10 Feb 2026 11:23:05 -0300 Subject: [PATCH 21/22] Fix LOG level --- src/agents/context_broker/ContextBrokerProcessor.cc | 2 +- src/agents/query_engine/query_element/LinkTemplate.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/agents/context_broker/ContextBrokerProcessor.cc b/src/agents/context_broker/ContextBrokerProcessor.cc index f4f26567e..9ff65342d 100644 --- a/src/agents/context_broker/ContextBrokerProcessor.cc +++ b/src/agents/context_broker/ContextBrokerProcessor.cc @@ -8,7 +8,7 @@ #include "ServiceBus.h" #include "ServiceBusSingleton.h" -#define LOG_LEVEL DEBUG_LEVEL +#define LOG_LEVEL INFO_LEVEL #include "Logger.h" using namespace context_broker; diff --git a/src/agents/query_engine/query_element/LinkTemplate.cc b/src/agents/query_engine/query_element/LinkTemplate.cc index 1e23b9aaf..cf2eb7deb 100644 --- a/src/agents/query_engine/query_element/LinkTemplate.cc +++ b/src/agents/query_engine/query_element/LinkTemplate.cc @@ -8,7 +8,7 @@ #include "AttentionBrokerClient.h" #include "Terminal.h" -#define LOG_LEVEL DEBUG_LEVEL +#define LOG_LEVEL INFO_LEVEL #include "Logger.h" using namespace query_element; From 6e94a28119eb830e0a921824879229b2dbdfed8c Mon Sep 17 00:00:00 2001 From: Andre Senna <“andre.senna@gmail.com”> Date: Tue, 10 Feb 2026 16:35:36 -0300 Subject: [PATCH 22/22] Minor fix --- src/agents/query_engine/PatternMatchingQueryProcessor.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/agents/query_engine/PatternMatchingQueryProcessor.cc b/src/agents/query_engine/PatternMatchingQueryProcessor.cc index f163ba5b6..22b53272c 100644 --- a/src/agents/query_engine/PatternMatchingQueryProcessor.cc +++ b/src/agents/query_engine/PatternMatchingQueryProcessor.cc @@ -277,9 +277,6 @@ shared_ptr PatternMatchingQueryProcessor::setup_query_tree( } else { Utils::error("Invalid token in query: " + query_tokens[cursor]); } - if ((query_tokens[cursor] == LinkSchema::LINK_TEMPLATE) || (query_tokens[cursor] == OR) || - (query_tokens[cursor] == AND)) { - } } if (cursor != tokens_count) {