https://gitlab.inria.fr/line/aide-group/macrovsa
Tip revision: 31a87d848f8ab28a06ccf77d0b359fc966974138 authored by vthierry on 15 December 2025, 21:31:50 UTC
sync from makefile
sync from makefile
Tip revision: 31a87d8
AssociativeMap.cpp
#include "AssociativeMap.hpp"
#include "Binding.hpp"
#include "algo.hpp"
#include <set>
namespace macrovsa {
AssociativeMap::AssociativeMap(const AssociativeMap& symbol) : Symbol(symbol.getName(), associativemap)
{
for(auto it = symbol.values.cbegin(); it != symbol.values.cend(); it++) {
const Symbol& key = *(it->second.first);
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
const Symbol& value = *(jt->second);
add(key, value);
}
}
}
const Belief& AssociativeMap::getBelief() const
{
Belief belief(0, 0);
for(auto it = get().cbegin(); it != get().cend(); it++) {
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
const Symbol& symbol = *(jt->second);
belief.tau += symbol.getBelief().tau * symbol.getBelief().tau, belief.sigma += symbol.getBelief().sigma;
}
}
belief.tau = sqrt(belief.tau);
const_cast < AssociativeMap & > (*this).Symbol::setBelief(belief);
return Symbol::getBelief();
}
void AssociativeMap::setBelief(double tau, double sigma)
{
getBelief();
double g_tau = getBelief().tau != 0 ? tau / getBelief().tau : 0, g_sigma = getBelief().sigma > 0 ? sigma / getBelief().sigma : 0;
for(auto it = get().cbegin(); it != get().cend(); it++) {
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
Symbol& symbol = *(jt->second);
const Belief& b = symbol.getBelief();
symbol.setBelief(g_tau * b.tau, g_sigma * b.sigma);
}
}
}
bool AssociativeMap::equals(const Symbol& symbol, char what) const
{
if(symbol.getType() == associativemap) {
const AssociativeMap& symbol2 = dynamic_cast < const AssociativeMap& > (symbol);
std::set < unsigned int > ids;
// Registers all IDs
{
for(auto it = values.cbegin(); it != values.cend(); it++) {
ids.insert(it->first);
}
for(auto it = symbol2.values.cbegin(); it != symbol2.values.cend(); it++) {
ids.insert(it->first);
}
}
// Loops on all ids
for(auto it = ids.cbegin(); it != ids.cend(); it++) {
auto jt1 = values.find(*it), jt2 = symbol2.values.find(*it);
if(jt1 == values.cend() || jt2 == symbol2.values.cend()) {
return false;
}
if(!Bundling::equals(jt1->second.second, jt2->second.second, what)) {
return false;
}
}
return true;
} else if(symbol.getType() == SymbolType::bundling) {
return getBundling().equals(symbol, what);
}
return false;
}
void AssociativeMap::setVector(double *vector) const
{
getBundling().setVector(vector);
}
void AssociativeMap::add(const Symbol& key, const Symbol& value)
{
// Creates the associative map binding to add to the map bundling
Symbol *y = clone(key), *x = clone(value);
// Here report tau and sigma on x
{
x->setBelief(x->getBelief().tau * y->getBelief().tau, y->getBelief().tau * x->getBelief().sigma + x->getBelief().tau * y->getBelief().sigma);
y->setBelief(1, 0);
}
auto it = values.find(key.getID());
if(it == values.cend()) {
symbols.add(y);
std::unordered_map < unsigned int, Symbol * > m0;
auto jt = values.insert(std::pair < unsigned int, std::pair < const Symbol *, std::unordered_map < unsigned int, Symbol * >> > (key.getID(), std::pair < const Symbol *, std::unordered_map < unsigned int, Symbol * >> (y, m0)));
aidesys::alert(!jt.second, "illegal-state", "in macrovsa::AssociativeMap::add('%s', '%s') new key insertion failed", key.asString().c_str(), value.asString().c_str());
it = jt.first;
} else {
aidesys::alert(!it->second.first->equals(*y), "illegal-state", "in macrovsa::AssociativeMap::add the binding clone '%s' differs from the local value '%s'\n", y->asString().c_str(), it->second.first->asString().c_str());
delete y;
}
symbols.add(x);
Bundling::add(it->second.second, x);
values_changed = true;
}
void AssociativeMap::erase(const Symbol& key)
{
values.erase(key.getID());
values_changed = true;
}
void AssociativeMap::clear()
{
values.clear();
values_changed = true;
}
const Symbol& AssociativeMap::get(const Symbol& key) const
{
auto it = values.find(key.getID());
if(it == values.cend()) {
Binding result(key, *this, false);
return *clone(result, symbols);
}
Symbol *result = it->second.second.cbegin()->second;
if(it->second.second.size() != 1) {
Bundling *b = new Bundling();
symbols.add(b);
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
b->add(*jt->second);
}
result = b;
} else if(key.getBelief().tau != 1 || key.getBelief().sigma != 0) {
result = clone(*(it->second.second.cbegin()->second), symbols);
}
if(key.getBelief().tau != 1 || key.getBelief().sigma != 0) {
// Here report tau and sigma on each bundling x, knowing that the binding has been normalized when adding
result->setBelief(result->getBelief().tau * key.getBelief().tau,
key.getBelief().tau * result->getBelief().sigma + result->getBelief().tau * key.getBelief().sigma);
}
return *result;
}
unsigned int AssociativeMap::getSize() const
{
unsigned int size = 0;
for(auto it = values.cbegin(); it != values.cend(); it++) {
size += it->second.second.size();
}
return size;
}
const Bundling& AssociativeMap::getBundling() const
{
if(values_changed) {
bundling.clear();
for(auto it = values.cbegin(); it != values.cend(); it++) {
const Symbol& key = *(it->second.first);
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
const Symbol& value = *(jt->second);
Binding binding(key, value);
bundling.add(binding);
}
}
values_changed = false;
}
return bundling;
}
std::string AssociativeMap::asString() const
{
std::string result = wjson::quote(getName()) + ": { ";
for(auto it = values.cbegin(); it != values.cend(); it++) {
const Symbol& key = *(it->second.first);
result += key.asString() + ": [ ";
for(auto jt = it->second.second.cbegin(); jt != it->second.second.cend(); jt++) {
const Symbol& value = *(jt->second);
result += value.asString() + " ";
}
result += "]\n";
}
return result + "}" + asStringTail() + "\n";
}
}
