#include "rule_session.h"
#include "rule_term_base.h"
#include "rule_term.h"
#include "query_rule_wrapper.h"
#include "rule_propagation.h"
#include "rule_explain_why.h"
#include "psearch_session.h"
namespace rule {
/////////////////////////////////////////////////////////////////////////////////////////
// get_backward_chaining_rule_name
//
/////////////////////////////////////////////////////////////////////////////////////////
std::string
get_backward_chaining_rule_name(knowledge_base const& kbase, internal::rule_vertex const root_vertex)
{
knowledge_rule_ptr_type p = kbase.get_knowledge_rule_ptr(root_vertex);
if(!p) return "ERROR: expecting rule in rule dependency graph at "+boost::lexical_cast<std::string>(root_vertex);
return p->get_rule_name();
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::rule_session
//
/////////////////////////////////////////////////////////////////////////////////////////
rule_session::rule_session(
rdf::rdf_session *session_p,
knowledge_base const& kbase):
m_relations(kbase.get_nbr_vertices()),
m_visited_consequents(),
m_rule_counter_map(kbase.get_nbr_vertices()),
m_is_log_rule_events(false),
m_rule_log(),
m_explain_lookup_map(),
m_rdf_session_p(session_p),
m_reasoners_pkg_scheduled(50),
m_reasoners_scheduled(50),
m_reasoners_executed(50),
m_owl_onProperty(),
m_owl_maxCardinality(),
m_owl_minCardinality(),
m_owl_cardinality(),
m_owl_sameAs(),
m_owl_true(),
m_owl_false(),
m_kbase(kbase),
m_verbose(false),
m_rule_stat_collector_p(),
m_max_rule_visit(m_kbase.get_max_rule_visit())
{
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::get_beta_relation
//
/////////////////////////////////////////////////////////////////////////////////////////
internal::beta_relation&
rule_session::get_beta_relation(internal::rule_vertex v)
{
beta_relation_ptr_type & r = m_relations[v];
if(!r) {
knowledge_term const& kterm = m_kbase.get_knowledge_term(v);
internal::rule_term_ptr_type const& rule_term_p = kterm.get_rule_term();
r.reset(new internal::beta_relation(rule_term_p->get_index_map_size(),
kterm.get_knowledge_rule().get_rule_salience(),
v));
//*O* v, 1000, 1000));
r->set_lookup_index(rule_term_p->get_lookup_index());
r->set_is_consequent_term(kterm.is_consequent());
};
return *r;
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::initialize
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::initialize()
{
// m_relations = beta_relation_map_type(m_relations.size());
internal::beta_relation& head_relation = get_beta_relation(m_kbase.get_head_rule_vertex());
internal::relation_row_ptr_type head_row_p = head_relation.create_relation_row();
head_relation.insert_row(NULL, head_row_p, 0);
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::test_max_cardinality
//
// returns true if succeed owl max cardinality test w/ (c rdf:type owl:Restriction)
/////////////////////////////////////////////////////////////////////////////////////////
bool
rule_session::test_max_cardinality(rdf::index_type const s, rdf::index_type const c)
{
// see if result is already cached
rdf::rdf_session::index_iterator ctor = m_rdf_session_p->find_index(s, c, rdf::all_objects());
if(!ctor.is_end()) {
rdf::index_type o = ctor.get_triple().get_object();
return o == m_owl_true ? true : false;
}
rdf::rdf_graph_ptr_type meta_graph_p = m_kbase.get_meta_graph();
if(!m_owl_onProperty) {
m_owl_onProperty = meta_graph_p->create_resource_as_index("owl:onProperty");
m_owl_maxCardinality = meta_graph_p->create_resource_as_index("owl:maxCardinality");
m_owl_minCardinality = meta_graph_p->create_resource_as_index("owl:minCardinality");
m_owl_cardinality = meta_graph_p->create_resource_as_index("owl:cardinality");
m_owl_sameAs = meta_graph_p->create_resource_as_index("owl:sameAs");
m_owl_true = meta_graph_p->create_literal_as_index("true", int(1));
m_owl_false = meta_graph_p->create_literal_as_index("false", int(0));
}
// get the property of the restriction
rdf::rdf_graph::index_iterator itor = meta_graph_p->find_index(c, m_owl_onProperty, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_max_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
rdf::index_type p = itor.get_triple().get_object();
// get the cardinality restriction
itor = meta_graph_p->find_index(c, m_owl_maxCardinality, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_max_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
float max_n = float(meta_graph_p->get_literal(itor.get_triple().get_object()).get_int());
// compute the cardinality
rdf::rdf_session::index_iterator stor = m_rdf_session_p->find_index(s, p, rdf::all_objects());
float cardi=0.0;
while(!stor.is_end()) {
rdf::index_type o = stor.get_triple().get_object();
// check if the object is owl:sameAs other objects to determine the semanticaly unique relations.
int n_same_as = 0;
rdf::rdf_session::index_iterator jtor = m_rdf_session_p->find_index(o, m_owl_sameAs, rdf::all_objects());
while(!jtor.is_end()) {
++n_same_as;
jtor.next();
}
cardi += 1.0 / (n_same_as + 1.0);
stor.next();
}
bool result = cardi <= (max_n+0.1);
// cache the result in the inferred graph - don't fire any evants since it is of no interest to the rules
m_rdf_session_p->insert_inferred_no_events(s, c, result ? m_owl_true : m_owl_false);
return result;
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::test_min_cardinality
//
// returns true if succeed owl min cardinality test w/ (c rdf:type owl:Restriction)
/////////////////////////////////////////////////////////////////////////////////////////
bool
rule_session::test_min_cardinality(rdf::index_type const s, rdf::index_type const c)
{
// see if result is already cached
rdf::rdf_session::index_iterator ctor = m_rdf_session_p->find_index(s, c, rdf::all_objects());
if(!ctor.is_end()) {
rdf::index_type o = ctor.get_triple().get_object();
return o == m_owl_true ? true : false;
}
rdf::rdf_graph_ptr_type meta_graph_p = m_kbase.get_meta_graph();
if(!m_owl_onProperty) {
m_owl_onProperty = meta_graph_p->create_resource_as_index("owl:onProperty");
m_owl_maxCardinality = meta_graph_p->create_resource_as_index("owl:maxCardinality");
m_owl_minCardinality = meta_graph_p->create_resource_as_index("owl:minCardinality");
m_owl_cardinality = meta_graph_p->create_resource_as_index("owl:cardinality");
m_owl_sameAs = meta_graph_p->create_resource_as_index("owl:sameAs");
m_owl_true = meta_graph_p->create_literal_as_index("true", int(1));
m_owl_false = meta_graph_p->create_literal_as_index("false", int(0));
}
// get the property of the restriction
rdf::rdf_graph::index_iterator itor = meta_graph_p->find_index(c, m_owl_onProperty, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_min_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
rdf::index_type p = itor.get_triple().get_object();
// get the cardinality restriction
itor = meta_graph_p->find_index(c, m_owl_minCardinality, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_min_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
float min_n = float(meta_graph_p->get_literal(itor.get_triple().get_object()).get_int());
// compute the cardinality
rdf::rdf_session::index_iterator stor = m_rdf_session_p->find_index(s, p, rdf::all_objects());
float cardi=0;
bool result = false;
while(!stor.is_end() and !result) {
rdf::index_type o = stor.get_triple().get_object();
// check if the object is owl:sameAs other objects to determine the semanticaly unique relations.
int n_same_as = 0;
rdf::rdf_session::index_iterator jtor = m_rdf_session_p->find_index(o, m_owl_sameAs, rdf::all_objects());
while(!jtor.is_end()) {
++n_same_as;
jtor.next();
}
cardi += 1.0 / (n_same_as + 1.0);
result = (cardi + 0.1) >= min_n;
stor.next();
}
// cache the result in the inferred graph
m_rdf_session_p->insert_inferred_no_events(s, c, result ? m_owl_true : m_owl_false);
return result;
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::test_cardinality
//
// returns true if succeed owl cardinality test w/ (c rdf:type owl:Restriction)
/////////////////////////////////////////////////////////////////////////////////////////
bool
rule_session::test_cardinality(rdf::index_type const s, rdf::index_type const c)
{
// see if result is already cached
rdf::rdf_session::index_iterator ctor = m_rdf_session_p->find_index(s, c, rdf::all_objects());
if(!ctor.is_end()) {
rdf::index_type o = ctor.get_triple().get_object();
return o == m_owl_true ? true : false;
}
rdf::rdf_graph_ptr_type meta_graph_p = m_kbase.get_meta_graph();
if(!m_owl_onProperty) {
m_owl_onProperty = meta_graph_p->create_resource_as_index("owl:onProperty");
m_owl_maxCardinality = meta_graph_p->create_resource_as_index("owl:maxCardinality");
m_owl_minCardinality = meta_graph_p->create_resource_as_index("owl:minCardinality");
m_owl_cardinality = meta_graph_p->create_resource_as_index("owl:cardinality");
m_owl_sameAs = meta_graph_p->create_resource_as_index("owl:sameAs");
m_owl_true = meta_graph_p->create_literal_as_index("true", int(1));
m_owl_false = meta_graph_p->create_literal_as_index("false", int(0));
}
// get the property of the restriction
rdf::rdf_graph::index_iterator itor = meta_graph_p->find_index(c, m_owl_onProperty, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
rdf::index_type p = itor.get_triple().get_object();
// get the cardinality restriction
itor = meta_graph_p->find_index(c, m_owl_cardinality, rdf::all_objects());
if(itor.is_end()) {
if(m_verbose) std::cout << "test_cardinality: The knowledge base meta model is not an OWL model!\n";
return false; // fails the test
}
float card_n = float(meta_graph_p->get_literal(itor.get_triple().get_object()).get_int());
// compute the cardinality
rdf::rdf_session::index_iterator stor = m_rdf_session_p->find_index(s, p, rdf::all_objects());
float cardi=0;
while(!stor.is_end()) {
rdf::index_type o = stor.get_triple().get_object();
// check if the object is owl:sameAs other objects to determine the semanticaly unique relations.
int n_same_as = 0;
rdf::rdf_session::index_iterator jtor = m_rdf_session_p->find_index(o, m_owl_sameAs, rdf::all_objects());
while(!jtor.is_end()) {
++n_same_as;
jtor.next();
}
cardi += 1.0 / (n_same_as + 1.0);
stor.next();
}
bool result = (cardi >= (card_n-0.1) and cardi <= (card_n+0.1));
// cache the result in the inferred graph
m_rdf_session_p->insert_inferred_no_events(s, c, result ? m_owl_true : m_owl_false);
return result;
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::query_rule_wrapper
//
/////////////////////////////////////////////////////////////////////////////////////////
query_rule_wrapper
rule_session::get_query(std::string const& name)
{
return get_query(name, query_params_map());
};
query_rule_wrapper
rule_session::get_query(std::string const& name, query_params_map const& params)
{
return query_rule_wrapper(m_kbase, *this, name, params);
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::execute_rules
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::execute_rules()
{
m_rdf_session_p->get_inferred_graph()->register_call_back_manager(this, m_kbase.get_inferred_cback_mgr());
m_rdf_session_p->get_asserted_graph()->register_call_back_manager(this, m_kbase.get_asserted_cback_mgr());
execute_rules(m_kbase.get_head_rule_vertex(), true);
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::execute_rules
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::execute_rules(internal::rule_vertex const from_vertex, bool apply_consequents)
{
internal::rule_propagator<internal::apply_rule_action> propagator(&m_kbase, internal::apply_rule_action(&m_kbase));
execute_rules_internal(propagator, from_vertex, apply_consequents);
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::execute_retract_rules
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::execute_retract_rules(internal::rule_vertex const from_vertex)
{
internal::rule_propagator<internal::retract_rule_action> propagator(&m_kbase, internal::retract_rule_action(&m_kbase));
execute_rules_internal(propagator, from_vertex, false);
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::apply_consequent_rules
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::apply_consequent_rules()
{
using rule::internal::beta_relation;
using rule::internal::relation_row_map;
rule_event_ptr_type event_p;
while(has_visited_consequents()) {
priority_consequent_ptr_type row_event_p = top_priority_visited_consequent();
internal::relation_row_ptr_type & row_p = row_event_p->row_p;
pop_visited_consequent();
if(row_p->is_processed()) {
continue;
}
knowledge_rule const& rule = m_kbase.get_knowledge_term(row_event_p->vertex).get_knowledge_rule();
beta_relation & b_relation = get_beta_relation(row_event_p->vertex);
if(is_logging_rule_events()) {
event_p.reset(new rule_event_infer(true, &rule, row_p));
event_p->initialize_body_triples(this);
log_rule_event(event_p);
}
if(m_rule_stat_collector_p) {
m_rule_stat_collector_p->triple_inferred(rule);
}
knowledge_rule::kterm_ptr_const_iterator itor = rule.get_consequent_terms_begin();
knowledge_rule::kterm_ptr_const_iterator end = rule.get_consequent_terms_end();
for(; itor != end; ++itor) {
if(row_p->is_inserted()) {
try {
(*itor)->get_rule_term()->compute_inferred_triples(this, *row_p);
} catch(rdf::rdf_exception const& e) {
std::cout << "rule_session::apply_consequent_rules(): Exception caught while processing inserted row: " << e << std::endl;
std::cout << "while processing consequent terms of rule " << rule.get_rule_name() << std::endl;
throw e;
}
} else if(row_p->is_deleted()) {
try {
(*itor)->get_rule_term()->retract_inferred_triples(this, *row_p);
} catch(rdf::rdf_exception const& e) {
std::cout << "rule_session::apply_consequent_rules(): Exception caught while processing deleted row: " << e << std::endl;
std::cout << "while processing consequent terms of rule " << rule.get_rule_name() << std::endl;
throw e;
}
}
}
if(row_p->is_inserted()) {
if(event_p) event_p->set_inferred();
row_p->set_processed();
} else if(row_p->is_deleted()) {
if(event_p) event_p->set_retracted();
b_relation.erase_deleted_row(row_p);
}
// check if any backward chaining rule need to be executed
execute_scheduled_reasoners();
}
};
// ============================================================================================================
// MEMBER FUNCTIONS FOR BACKWARD CHAINING RULES
// ============================================================================================================
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::execute_scheduled_reasoners
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::execute_scheduled_reasoners()
{
while(!m_reasoners_scheduled.empty()) {
backw_rule_vertex_set_t::iterator itor = m_reasoners_scheduled.begin();
internal::rule_vertex rule_vertex = *itor;
if(m_verbose) {
std::cout << "rule_session::execute_scheduled_reasoners: executing backward chaining rule: "
<< get_backward_chaining_rule_name(m_kbase, rule_vertex) << std::endl;
}
m_reasoners_executed.insert(rule_vertex);
m_reasoners_scheduled.erase(itor);
internal::single_rule_propagator<internal::apply_rule_action> propagator(&m_kbase, internal::apply_rule_action(&m_kbase));
try {
propagator(this, rule_vertex);
} catch(rdf::rdf_exception const& e) {
std::cout << "rule_session::execute_scheduled_reasoners: Exception caught while executing backward chaining rules, message: " << e.what() << std::endl;
if(e.code() == rdf::rule_infinite_loop) std::cout << "Infinite loop detected while executing backward chaining rules" << std::endl;
throw e;
} catch(...) {
const char * msg = "rule_session::execute_scheduled_reasoners: Unknown (general) Exception caught while executing forward chaining rules!!, no message available";
std::cout << msg << std::endl;
throw rdf::rdf_exception(rdf::none, msg);
}
}
};
// ============================================================================================================
// MEMBER FUNCTIONS FOR EXPLAIN WHY
// ============================================================================================================
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::explain_why
//
/////////////////////////////////////////////////////////////////////////////////////////
explain_ptr_type
rule_session::explain_why(rdf::index_type const s, rdf::index_type const p, rdf::index_type const o)
{
if(!is_logging_rule_events()) {
std::string message("rule_session::explain_why: ERROR-X1: explain_why facility requires the flag is_logging_rule_events to be set to true.");
std::cout << message << std::endl;
throw rdf::rdf_exception(rdf::explain_why_missing, message);
}
// set up the obj to return
explain_ptr_type explain_ptr(new explain(this));
explain_graph_type & graph = explain_ptr->get_explain_graph();
// find if (s, p, o) is an asserted or inferred triple
if(m_rdf_session_p->get_asserted_graph()->contains(s, p, o)) {
explain_info_ptr_type info_p(new explain_info_triple(rdf::index_triple(s, p, o), true));
explain_vertex explain_v = boost::add_vertex(explain_properties(info_p), graph);
info_p->set_explain_vertex(explain_v);
} else if(m_rdf_session_p->get_inferred_graph()->contains(s, p, o)) {
rdf::index_triple triple(s, p, o);
// set up the root of the graph, then build graph recursively
explain_info_ptr_type info_p(new explain_info_triple(triple, false));
explain_vertex explain_v = boost::add_vertex(explain_properties(info_p), graph);
info_p->set_explain_vertex(explain_v);
// keep a map of visited triples to avoid duplication in explanations
explain_vertex_lookup_map_type lookup_map;
lookup_map.insert(explain_vertex_lookup_map_type::value_type(triple, explain_v));
explain_why_graph(graph, lookup_map, explain_v, triple);
}
return explain_ptr;
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::explain_why_graph
//
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::explain_why_graph(explain_graph_type & graph, explain_vertex_lookup_map_type & lookup_map, explain_vertex const root_vertex, rdf::index_triple const explain_triple)
{
typedef std::pair<explain_vertex, rdf::index_triple > stack_elm;
std::vector<stack_elm> stack;
stack.reserve(100);
stack.push_back(stack_elm(root_vertex, explain_triple));
while(!stack.empty()) {
// get the rule_events that inferred the triple
stack_elm & elm = stack.back();
explain_vertex u = elm.first;
rdf::index_triple triple = elm.second;
stack.pop_back();
explain_lookup_map_type::const_iterator itor;
explain_lookup_map_type::const_iterator end;
boost::tie(itor, end) = m_explain_lookup_map.equal_range(triple);
for(; itor!=end; ++itor) {
rule_event_ptr_type event_p = itor->second;
if(event_p->get_relation_row()->is_deleted()) continue;
explain_info_ptr_type info_p(new explain_info_rule(event_p));
explain_vertex v = boost::add_vertex(explain_properties(info_p), graph);
info_p->set_explain_vertex(v);
boost::add_edge(u, v, graph);
// push all body triples into the stack
rule_event_base::array_body_triples_type::const_iterator body_itor = event_p->body_triples_begin();
rule_event_base::array_body_triples_type::const_iterator body_end = event_p->body_triples_end();
rdf::index_triple body_triple;
bool is_assertion;
for(; body_itor!=body_end; ++body_itor) {
boost::tie(body_triple, is_assertion) = *body_itor;
if(!is_assertion) continue;
// check if triple is already into the graph
explain_vertex_lookup_map_type::const_iterator xitor = lookup_map.find(body_triple);
if(xitor != lookup_map.end()) {
explain_vertex w = xitor->second;
boost::add_edge(v, w, graph);
} else if(m_rdf_session_p->get_asserted_graph()->contains(body_triple)) {
explain_info_ptr_type info_p(new explain_info_triple(body_triple, true));
explain_vertex w = boost::add_vertex(explain_properties(info_p), graph);
info_p->set_explain_vertex(w);
boost::add_edge(v, w, graph);
lookup_map.insert(explain_vertex_lookup_map_type::value_type(body_triple, w));
} else {
// inferred triple that is not in the graph yet
explain_info_ptr_type info_p(new explain_info_triple(body_triple, false));
explain_vertex w = boost::add_vertex(explain_properties(info_p), graph);
info_p->set_explain_vertex(w);
boost::add_edge(v, w, graph);
lookup_map.insert(explain_vertex_lookup_map_type::value_type(body_triple, w));
stack.push_back(stack_elm(w, body_triple));
}
}
}
}
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_session::print_beta_relations
//
// debugging method
/////////////////////////////////////////////////////////////////////////////////////////
void
rule_session::print_beta_relations()const
{
std::cout << "Nodes in the Rete Network (rule graph):\n"
<< "---------------------------------------\n\n";
unsigned int sz = m_relations.size();
for(rule::internal::rule_vertex u=1; u<sz; ++u) {
if(m_relations[u]) {
std::cout << std::endl;
internal::knowledge_term const& kterm = m_kbase.get_knowledge_term(u);
std::string msg(rdf::to_string(kterm) + ", ");
print_beta_relation( msg, u, this);
}
}
};
// ============================================================================================================
// CLASSES FOR QUERY RULE
// ============================================================================================================
/////////////////////////////////////////////////////////////////////////////////////////
// query_rule_wrapper::execute
//
/////////////////////////////////////////////////////////////////////////////////////////
query_result_ptr_type
query_rule_wrapper::execute()
{
// clear all beta_relations of the query rule
// need to do this in case the params of the query have changed since last invokation.
knowledge_rule::rule_vertex_const_iterator itor = m_query_rule_p->get_body_term_vertices_begin();
knowledge_rule::rule_vertex_const_iterator end = m_query_rule_p->get_body_term_vertices_end();
internal::rule_vertex from_vertex = *itor;
internal::beta_relation& from_relation = m_rule_session.get_beta_relation(from_vertex);
if(!from_relation.empty()) {
for(; itor!=end; ++itor) {
m_rule_session.get_beta_relation(*itor).clear();
}
}
// insert a row in the rule first term (pseudo head)
from_relation.clear();
internal::relation_row_ptr_type head_row_p = from_relation.create_relation_row();
std::size_t hash_code = initialize_head_row(head_row_p);
from_relation.insert_row(NULL, head_row_p, hash_code);
internal::single_rule_propagator<internal::apply_rule_action> propagator(&m_kbase, internal::apply_rule_action(&m_kbase));
m_rule_session.execute_rules_internal(propagator, get_rule_vertex(), true);
return query_result_ptr_type(new query_result(m_kbase, *this, m_rule_session.get_beta_relation(get_tail_query_vertex())));
};
/////////////////////////////////////////////////////////////////////////////////////////
// query_rule_wrapper::initialize_head_row
//
/////////////////////////////////////////////////////////////////////////////////////////
std::size_t
query_rule_wrapper::initialize_head_row(internal::relation_row_ptr_type head_row_p)const
{
std::size_t hash_code = 0;
internal::rule_term_ptr_type query_head_rt_p = get_head_rule_term_p();
query_params_map::params_t::const_iterator itor = m_params.get_params_begin();
query_params_map::params_t::const_iterator end = m_params.get_params_end();
for(; itor!=end; ++itor) {
std::string const& key = itor->first;
rdf::index_type const& value = itor->second;
(*head_row_p)[query_head_rt_p->get_index(key).first] = value;
hash_code += std::size_t(value);
};
return hash_code;
};
}; /* rule namespace */