Skip to content
1 change: 0 additions & 1 deletion src/agents/evolution/QueryEvolutionProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,6 @@ void QueryEvolutionProcessor::evolve_query(shared_ptr<StoppableThread> monitor,
#endif
proxy->new_population_sampled(population);
if (population.size() > 0) {
proxy->flush_answer_bundle();
STOP_WATCH_START(selection);
select_best_individuals(proxy, population, selected);
STOP_WATCH_FINISH(selection, "EvolutionIndividualSelection");
Expand Down
1 change: 0 additions & 1 deletion src/agents/link_creation_agent/LinkCreationProcessor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ void LinkCreationProcessor::link_creation(shared_ptr<StoppableThread> monitor,
}
}
proxy->flush_determiners();
proxy->flush_answer_bundle();
proxy->cycle_ended();
if (!pm_proxy->finished()) {
// stopping pattern matching query
Expand Down
4 changes: 4 additions & 0 deletions src/agents/link_creation_agent/LinkCreationProxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ string LinkCreationProxy::MAX_ROUNDS = "max_rounds";
string LinkCreationProxy::LINK_CREATION_STRENGTH_THRESHOLD = "link_creation_strength_threshold";
string LinkCreationProxy::LINK_CREATION_LOG_FILE_NAME = "link_creation_log_file_name";
string LinkCreationProxy::LOG_NEW_LINKS = "log_new_links";
string LinkCreationProxy::LINK_CREATOR_EXTRA_PARAMETERS = "link_creator_extra_parameters";

LinkCreationProxy::LinkCreationProxy() {
// constructor typically used in processor
Expand All @@ -44,6 +45,7 @@ LinkCreationProxy::~LinkCreationProxy() {}
void LinkCreationProxy::init() {
this->command = ServiceBus::LINK_CREATION;
this->link_creation_function_object = shared_ptr<LinkCreator>(nullptr);
this->link_creator_function_tag = "";
this->round_count = 0;
this->parameters[LOG_NEW_LINKS] = true;
this->parameters += SystemParametersSingleton::get_instance()->get_link_creation_agent_params();
Expand Down Expand Up @@ -143,6 +145,8 @@ void LinkCreationProxy::set_link_creator_function_tag(const string& tag) {
this->parameters.get_or<string>(LINK_CREATION_LOG_FILE_NAME, ""));
this->link_creation_function_object->set_log_new_links(
this->parameters.get<bool>(LOG_NEW_LINKS));
this->link_creation_function_object->extra_parameters(
this->parameters.get_or<string>(LINK_CREATOR_EXTRA_PARAMETERS, ""));
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/agents/link_creation_agent/LinkCreationProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class LinkCreationProxy : public BaseQueryProxy {
static string LINK_CREATION_STRENGTH_THRESHOLD;
static string LINK_CREATION_LOG_FILE_NAME;

// LOG_NEW_LINKS is an optional parameter but it is not part of the configuration file as it
// is meant to be used only in tests.
// Optional parameter which are not part of the configuration file
static string LOG_NEW_LINKS;
static string LINK_CREATOR_EXTRA_PARAMETERS;

LinkCreationProxy();

Expand Down
16 changes: 9 additions & 7 deletions src/agents/link_creation_agent/link_creators/AndTwoPredicates.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ LinkCreationStats AndTwoPredicates::create(shared_ptr<QueryAnswer> query_answer)
}
string key = predicates[0] + " " + predicates[1] + concept_;

LinkCreationStats stats = LinkCreationStats(false, 0, 0);
LinkCreationStats stats;
if (predicates[0] != predicates[1]) {
if (!visited(key)) {
visit(key);
Expand All @@ -37,17 +37,19 @@ LinkCreationStats AndTwoPredicates::create(shared_ptr<QueryAnswer> query_answer)
extract_mentioned_predicates(mentioned_predicates1, predicates[1]);
if (!Utils::intersects(mentioned_predicates0, mentioned_predicates1)) {
vector<string> targets = {LOGICAL_AND_HANDLE, predicates[0], predicates[1]};
add_or_update_link(targets, 1.0);
stats.created++;
if (add_or_update_link(targets, 1.0) == CREATED) {
stats.created++;
}
double strength = 1;
for (string& h : query_answer->get_handles_vector()) {
strength *= get_strength(h);
}
if (strength >= strength_threshold()) {
stats.created++;
string new_predicate_handle = Hasher::link_handle(EXPRESSION, targets);
string new_predicate_handle = Hasher::link_handle(EXPRESSION, targets);
AddLinkStatus add_status =
add_or_update_link({EVALUATION_HANDLE, new_predicate_handle, concept_}, strength);
} else {
if (add_status == CREATED) {
stats.created++;
} else if (add_status == UPDATED) {
stats.updated++;
}
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include "CustomizableLinkCreator.h"

#include "Hasher.h"
#include "tags.h"

using namespace link_creators;

// -------------------------------------------------------------------------------------------------
// Public methods

CustomizableLinkCreator::CustomizableLinkCreator() {}

CustomizableLinkCreator::~CustomizableLinkCreator() {}

LinkCreationStats CustomizableLinkCreator::create(shared_ptr<QueryAnswer> query_answer) {
STACK_TRACE();
LinkCreationStats stats;
for (LinkSpecification& spec : this->link_specification) {
if ((spec.target_elements.size() == 0) || (spec.link_type == "")) {
RAISE_ERROR("Invalid empty target elements or link_type");
Comment thread
andre-senna marked this conversation as resolved.
break;
}
vector<string> handles;
vector<double> strength_components;
handles.push_back(Hasher::node_handle(SYMBOL, spec.link_type));
for (QueryAnswerElement& element : spec.target_elements) {
handles.push_back(query_answer->get(element));
}
string key = Utils::join(handles, ' ');
if (!visited(key)) {
visit(key);
stats.visited = true;
for (QueryAnswerElement& element : spec.strength_elements) {
strength_components.push_back(get_strength(query_answer->get(element)));
}
AddLinkStatus add_status = add_or_update_link(
handles, compute_strength(strength_components, spec.strength_composition));
if (add_status == CREATED) {
stats.created++;
} else if (add_status == UPDATED) {
stats.updated++;
}
}
}
return stats;
}

void CustomizableLinkCreator::extra_parameters(const string& extra_parameters) {
if (extra_parameters != "") {
vector<string> tokens = Utils::split(extra_parameters);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
untokenize(tokens);
}
}

void CustomizableLinkCreator::add_link_specification(const vector<QueryAnswerElement>& target_elements,
const vector<QueryAnswerElement>& strength_elements,
StrengthComposition strength_composition,
const string& link_type) {
string trimmed_type = Utils::trim(link_type);
if ((trimmed_type == "") || (trimmed_type.find(' ') != std::string::npos)) {
RAISE_ERROR("Invalid link_type: " + link_type);
}

link_specification.emplace_back(
target_elements, strength_elements, strength_composition, trimmed_type);
}

void CustomizableLinkCreator::tokenize(vector<string>& tokens) {
tokens.push_back(std::to_string(this->link_specification.size()));
for (LinkSpecification& spec : this->link_specification) {
tokens.push_back(std::to_string(spec.target_elements.size()));
for (QueryAnswerElement& element : spec.target_elements) {
tokens.push_back(element.to_string());
}
tokens.push_back(std::to_string(spec.strength_elements.size()));
for (QueryAnswerElement& element : spec.strength_elements) {
tokens.push_back(element.to_string());
}
tokens.push_back(std::to_string(spec.strength_composition));
tokens.push_back(spec.link_type);
}
}

static inline string& safe_get_next_token(vector<string>& tokens, unsigned int& cursor) {
if (cursor >= tokens.size()) {
RAISE_ERROR("Invalid tokens for CustomizableLinkCreator");
}
return tokens[cursor++];
}

void CustomizableLinkCreator::untokenize(vector<string>& tokens) {
unsigned int cursor = 0;
unsigned int num_specs = Utils::string_to_uint(safe_get_next_token(tokens, cursor));
for (unsigned int i = 0; i < num_specs; i++) {
vector<QueryAnswerElement> _target_elements;
vector<QueryAnswerElement> _strength_elements;
StrengthComposition _strength_composition;
string _link_type;
unsigned int num_elements = Utils::string_to_uint(safe_get_next_token(tokens, cursor));
for (unsigned int j = 0; j < num_elements; j++) {
_target_elements.push_back(
QueryAnswerElement::from_string(safe_get_next_token(tokens, cursor)));
}
num_elements = Utils::string_to_uint(safe_get_next_token(tokens, cursor));
for (unsigned int j = 0; j < num_elements; j++) {
_strength_elements.push_back(
QueryAnswerElement::from_string(safe_get_next_token(tokens, cursor)));
}
_strength_composition =
(StrengthComposition) Utils::string_to_uint(safe_get_next_token(tokens, cursor));
_link_type = safe_get_next_token(tokens, cursor);
add_link_specification(_target_elements, _strength_elements, _strength_composition, _link_type);
}
if (cursor != tokens.size()) {
RAISE_ERROR("Invalid trailing tokens for CustomizableLinkCreator");
}
}

// -------------------------------------------------------------------------------------------------
// Private methods

double CustomizableLinkCreator::compute_strength(const vector<double>& components,
StrengthComposition composition) {
double answer = 0.0;
switch (composition) {
case PRODUCT:
answer = 1.0;
for (double strength : components) {
answer *= strength;
}
break;
default:
RAISE_ERROR("Invalid strength composition: " + std::to_string(composition));
break;
}
return answer;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once
#include <vector>

#include "LinkCreator.h"

using namespace std;

namespace link_creators {

/**
*
*/
class CustomizableLinkCreator : public LinkCreator {
public:
enum StrengthComposition { UNDEFINED = 0, PRODUCT };

CustomizableLinkCreator();
~CustomizableLinkCreator();

LinkCreationStats create(shared_ptr<QueryAnswer> query_answer);
virtual void extra_parameters(const string& extra_parameters);

private:
class LinkSpecification {
public:
LinkSpecification() = default;
LinkSpecification(const vector<QueryAnswerElement>& target_elements,
const vector<QueryAnswerElement>& strength_elements,
StrengthComposition strength_composition,
string link_type) {
this->target_elements = target_elements;
this->strength_elements = strength_elements;
this->strength_composition = strength_composition;
this->link_type = link_type;
}
vector<QueryAnswerElement> target_elements;
vector<QueryAnswerElement> strength_elements;
StrengthComposition strength_composition;
string link_type;
};

vector<LinkSpecification> link_specification;

double compute_strength(const vector<double>& components, StrengthComposition composition);

public:
void tokenize(vector<string>& tokens);
void untokenize(vector<string>& tokens);
void add_link_specification(const vector<QueryAnswerElement>& target_elements,
const vector<QueryAnswerElement>& strength_elements,
StrengthComposition strength_composition,
const string& link_type);
};

} // namespace link_creators
8 changes: 6 additions & 2 deletions src/agents/link_creation_agent/link_creators/LinkCreator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ LinkCreator::LinkCreator() {
this->_log_new_links = false;
}

bool LinkCreator::add_or_update_link(const vector<string>& targets, double strength) {
LinkCreator::AddLinkStatus LinkCreator::add_or_update_link(const vector<string>& targets,
double strength) {
STACK_TRACE();
if (strength < this->_strength_threshold) {
return REJECTED;
}
auto db = atomdb();
bool new_link_created_flag = false;
shared_ptr<Link> new_link =
Expand Down Expand Up @@ -47,7 +51,7 @@ bool LinkCreator::add_or_update_link(const vector<string>& targets, double stren
save_link_metta(new_link);
}
}
return new_link_created_flag;
return (new_link_created_flag ? CREATED : UPDATED);
}

string LinkCreator::get_node_name(const string& handle) {
Expand Down
12 changes: 11 additions & 1 deletion src/agents/link_creation_agent/link_creators/LinkCreator.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class LinkCreationStats {
*/
class LinkCreator {
public:
enum AddLinkStatus { REJECTED = 0, UPDATED, CREATED };
LinkCreator();
virtual ~LinkCreator() {}

Expand Down Expand Up @@ -142,6 +143,15 @@ class LinkCreator {
*/
virtual LinkCreationStats create(shared_ptr<QueryAnswer> query_answer) = 0;

/**
* Concrete subclasses may implement this in order to receive optional extra parameters passed
* to the LinkCreationProxy by caller under the tag LINK_CREATOR_EXTRA_PARAMETERS.
*
* @param extra_parameters A string which is supposed to be parsed in order to obtain the actual
* parameters.
*/
virtual void extra_parameters(const string& extra_parameters) {}

/**
* Return the AttentionBroker context to be used.
*
Expand All @@ -159,7 +169,7 @@ class LinkCreator {
inline HandleDecoder* decoder() { return static_pointer_cast<HandleDecoder>(atomdb()).get(); }
inline void add_determiners(vector<string>& entry) { this->_buffer_determiners.push_back(entry); }

bool add_or_update_link(const vector<string>& targets, double strength);
AddLinkStatus add_or_update_link(const vector<string>& targets, double strength);
double get_strength(const string& handle);
string get_node_name(const string& handle);
void save_link_metta(shared_ptr<Link> link);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// -------------------------------------------------------------------------------------------------
// ADD your header here
#include "AndTwoPredicates.h"
#include "CustomizableLinkCreator.h"
#include "UnitTestLinkCreator.h"
// -------------------------------------------------------------------------------------------------

Expand All @@ -15,11 +16,11 @@ using namespace commons;
bool LinkCreatorRegistry::INITIALIZED = false;
// -----------------------------------------------------------------------------------------
// ADD your function here using a unique string key
// NOTE: "remote_link_creation_function" is reserved and CAN'T be used here.
// -----------------------------------------------------------------------------------------
string LinkCreatorRegistry::REMOTE_FUNCTION = "remote_link_creation_function";
string LinkCreatorRegistry::UNIT_TEST = "unit_test";
string LinkCreatorRegistry::CUSTOMIZABLE = "customizable";
string LinkCreatorRegistry::AND_TWO_PREDICATES = "and_two_predicates";
// -----------------------------------------------------------------------------------------

void LinkCreatorRegistry::initialize_statics() {
STACK_TRACE();
Expand All @@ -42,6 +43,8 @@ shared_ptr<LinkCreator> LinkCreatorRegistry::function(const string& tag) {
// ADD an "else if" for your function here
} else if (tag == UNIT_TEST) {
answer = make_shared<UnitTestLinkCreator>();
} else if (tag == CUSTOMIZABLE) {
answer = make_shared<CustomizableLinkCreator>();
} else if (tag == AND_TWO_PREDICATES) {
answer = make_shared<AndTwoPredicates>();
// -----------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class LinkCreatorRegistry {
public:
static string REMOTE_FUNCTION;
static string UNIT_TEST;
static string CUSTOMIZABLE;
static string AND_TWO_PREDICATES;

~LinkCreatorRegistry() {}
Expand Down
6 changes: 5 additions & 1 deletion src/commons/Utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ pair<size_t, size_t> Utils::parse_ports_range(const string& str, char delimiter)
return make_pair(start_port, end_port);
}

string Utils::join(const vector<string>& tokens, char delimiter) {
string Utils::join(const vector<string>& tokens, const string& delimiter) {
string result;
for (size_t i = 0; i < tokens.size(); i++) {
if (i > 0) {
Expand All @@ -177,6 +177,10 @@ string Utils::join(const vector<string>& tokens, char delimiter) {
return result;
}

string Utils::join(const vector<string>& tokens, char delimiter) {
return join(tokens, string(1, delimiter));
}

bool Utils::is_number(const string& s) {
return !s.empty() &&
find_if(s.begin(), s.end(), [](unsigned char c) { return !isdigit(c); }) == s.end();
Expand Down
Loading
Loading