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
Rules.cpp
#include "Rules.hpp"
#include "Binding.hpp"
#include "algo.hpp"
#include "file.hpp"
namespace macrovsa {
Rules::Rules(unsigned int maximalDepth, String trace, String traceOutput) : maximalDepth(maximalDepth), trace(trace), traceOutput(traceOutput)
{}
Rules::~Rules()
{
if(traceBuffer != "") {
aidesys::save(traceOutput, traceBuffer);
}
}
void Rules::add(Rule& rule)
{
rules.push_back(&rule);
rule.rules = this;
}
bool Rules::isDifferent(const Symbol& subject_1, const Symbol& predicate_1, const Symbol& object_1, const Symbol& subject_2, const Symbol& predicate_2, const Symbol& object_2)
{
bool result = true; //+
Belief belief = algo::conj(algo::sim(subject_1, subject_2), algo::sim(predicate_1, predicate_2), algo::sim(object_1, object_2));
if(belief.tau < belief.sigma) {
// return true;
} else {
// return subject_1.getBelief().tau * predicate_1.getBelief().tau * object_1.getBelief().tau > subject_2.getBelief().tau * predicate_2.getBelief().tau * object_2.getBelief().tau + 2 * belief.sigma;
result = subject_1.getBelief().tau * predicate_1.getBelief().tau * object_1.getBelief().tau > subject_2.getBelief().tau * predicate_2.getBelief().tau * object_2.getBelief().tau + 2 * belief.sigma; //+
}
dump("isDifferent(("+subject_1.asString()+", "+ predicate_1.asString()+", "+ object_1.asString()+"); ("+subject_2.asString()+", "+ predicate_2.asString()+", "+ object_2.asString()+")) = "+(result ? "true" : "false")+"\n", 'd'); //+
return result;
}
void Rules::apply(RelationalMap& triples, const RelationalMap& incoming, unsigned int depth)
{
dump(aidesys::echo("Applying inference at depth %d on a relation map of size %d\n", depth, triples.Bundling::get().size()), 'd');
RelationalMap output("output");
dump("Incoming triples: " + incoming.asString() + "\n", 'i');
applyOnce(output, triples, incoming);
triples.add(output);
dump("Added triples: " + output.asString() + "\n", 'o');
if(output.Bundling::get().size() > 0 && (maximalDepth == 0 || depth < maximalDepth)) {
apply(triples, output, depth + 1);
}
}
bool Rules::isDifferent(const Symbol& subject_1, const Symbol& predicate_1, const Symbol& object_1, const RelationalMap& input)
{
bool different = true;
for(auto it_2 = input.Bundling::get().cbegin(); it_2 != input.Bundling::get().cend() && different; it_2++) {
const Binding& binding_spo_2 = dynamic_cast < const Binding& > (*(it_2->second));
const Binding& binding_po_2 = dynamic_cast < const Binding& > (binding_spo_2.x());
const Symbol& subject_2 = binding_spo_2.y(), & predicate_2 = binding_po_2.y(), & object_2 = binding_po_2.x();
different = isDifferent(subject_1, predicate_1, object_1, subject_2, predicate_2, object_2);
}
return different;
}
void Rules::applyOnce(RelationalMap& output, const RelationalMap& input, const RelationalMap& incoming)
{
RelationalMap output_candidates;
// Applies all rules on all incoming triples
for(auto it_1 = incoming.Bundling::get().cbegin(); it_1 != incoming.Bundling::get().cend(); it_1++) {
const Binding& binding_spo = dynamic_cast < const Binding& > (*(it_1->second));
const Binding& binding_po = dynamic_cast < const Binding& > (binding_spo.x());
const Symbol& subject_0 = binding_spo.y(), & predicate_0 = binding_po.y(), & object_0 = binding_po.x();
output_candidates.add(subject_0, predicate_0, object_0);
for(auto it_2 = rules.begin(); it_2 != rules.end(); it_2++) {
(*it_2)->apply(output_candidates, input, subject_0, predicate_0, object_0);
}
}
// Only selects triples that are different from the input and not yet in the output
for(auto it = output_candidates.Bundling::get().cbegin(); it != output_candidates.Bundling::get().cend(); it++) {
const Binding& binding_spo = dynamic_cast < const Binding& > (*(it->second));
const Binding& binding_po = dynamic_cast < const Binding& > (binding_spo.x());
const Symbol& subject_0 = binding_spo.y(), & predicate_0 = binding_po.y(), & object_0 = binding_po.x();
if(isDifferent(subject_0, predicate_0, object_0, input) &&
isDifferent(subject_0, predicate_0, object_0, output))
{
output.add(subject_0, predicate_0, object_0);
}
}
}
void Rules::dump(String string, char what)
{
if(trace.find(what) != std::string::npos) {
// Manages the trace lenght bound
{
traceLenght += string.size();
aidesys::alert(traceLenght > maxTraceLenght, "illegal-state", "in macrovsa:Rules::dump trace buffer overflow");
}
if(traceOutput == "stdout") {
printf("%s", string.c_str());
} else {
traceBuffer += string;
}
}
}
}
