#include "rdf_rule_core.h"
#include "rdf_index.h"
#include "rdf_graph.h"
#include "rule_internal.h"
#include "knowledge_base.h"
#include "rule_session.h"
namespace rdf {
void index_triple_cback::triple_inserted(rule::rule_session * session_p,index_type const s, index_type const p, index_type const o)const
{
rule::internal::rule_term_ptr_type const& rule_term_p = m_kterm_p->get_rule_term();
rule::internal::beta_relation& relation = session_p->get_beta_relation(m_v);
// consider only if the rule already fired
if(!relation.has_fired()) return;
if(session_p->is_verbose()) {
std::cout << "\n@@@index_triple_cback::triple_inserted: '"<< m_kterm_p->get_name()
<< "' notified of triple " << triple(s, p, o) << std::endl;
}
if(rule_term_p->is_assertion_term()) {
perform_merge_row(session_p, relation, rule_term_p, s, p, o);
} else {
perform_remove_row(session_p, relation, rule_term_p, s, p, o);
};
};
void index_triple_cback::triple_deleted(rule::rule_session *session_p, index_type const s, index_type const p, index_type const o)const
{
rule::internal::rule_term_ptr_type const& rule_term_p = m_kterm_p->get_rule_term();
rule::internal::beta_relation& relation = session_p->get_beta_relation(m_v);
// consider only if the rule already fired
if(!relation.has_fired()) return;
if(session_p->is_verbose()) {
std::cout << "\n@@@index_triple_cback::triple_deleted: '"<< m_kterm_p->get_name()
<< "' notified of triple " << triple(s, p, o) << std::endl;
}
if(rule_term_p->is_assertion_term()) {
perform_remove_row(session_p, relation, rule_term_p, s, p, o);
} else {
perform_merge_row(session_p, relation, rule_term_p, s, p, o);
};
};
void index_triple_cback::perform_merge_row(
rule::rule_session *session_p,
rule::internal::beta_relation& relation,
rule::internal::rule_term_ptr_type const& rule_term_p,
index_type const s, index_type const p, index_type const o)const
{
rule::internal::beta_relation& left_relation = session_p->get_beta_relation(m_u);
index_type buf[] = {s, p, o};
relation.reset_propagation_qx();
unsigned int count = rule_term_p->merge_rows(session_p, left_relation, buf, relation);
if(count > 0) {
// percolate down the added row
// - apply to forward rules (which have been fired by now) or
// - apply to backward rules that have been fired
if(m_krule_p and
m_krule_p->get_rule_type()==rule::backward_chaining_rule and
!session_p->has_backward_chaining_rule_fired(m_krule_p->get_dependency_graph_vertex())) return;
// fire the nodes on the rete network w/o computing the inferred triple (hence the false in last arg.)
// to avoid recursive calls to this call back.
session_p->execute_rules(m_v, false);
}
};
void index_triple_cback::perform_remove_row(
rule::rule_session *session_p,
rule::internal::beta_relation& relation,
rule::internal::rule_term_ptr_type const& rule_term_p,
index_type const s, index_type const p, index_type const o)const
{
rule::internal::beta_relation& left_relation = session_p->get_beta_relation(m_u);
index_type buf[] = {s, p, o};
relation.reset_propagation_qx();
unsigned int count = rule_term_p->remove_rows(session_p, left_relation, buf, relation);
if(count > 0) {
// percolate down the removed row
// - apply to forward rules (which have been fired by now) or
// - apply to backward rules that have been fired
if(m_krule_p and
m_krule_p->get_rule_type()==rule::backward_chaining_rule and
!session_p->has_backward_chaining_rule_fired(m_krule_p->get_dependency_graph_vertex())) return;
// fire the nodes on the rete network to remove rows in beta_relation that were created
// by the presence of this triple.
// DO not compute the consequent terms - which would be retract_triple to avoid
// recursive call s to this call back
session_p->execute_retract_rules(m_v);
}
};
}; /* rdf namespace */