#ifndef PSEARCH_SESSION_H_
#define PSEARCH_SESSION_H_
#include "rule_engine.h"
#include "psearch_db.h"
#include "psearch_query.h"
#include "psearch_infer.h"
namespace psearch {
// defined in rule_engine.h:
// class PSearchSession;
// typedef std::tr1::shared_ptr<PSearchSession> psession_ptr_type;
/////////////////////////////////////////////////////////////////////////////////////////
// class PSearchSession
//
// The has_node set remain unchanged during the inferrence process, initialized from the asserted graph.
// The inferred_has_node set is augmented with the inferred nodes and put into the inferred graph.
// The has_not nodes remain unchanged during the inferrence process, initialized from the asserted graph.
/////////////////////////////////////////////////////////////////////////////////////////
class PSearchSession
{
public:
PSearchSession(rule::knowledge_base const* kbase_p, rdf::rdf_session_ptr_type session_p):
m_kbase_p(kbase_p),
m_psearch_db_p(kbase_p->get_psearch_db()),
m_rdf_session_p(session_p),
m_subject(),
m_has_nodes(),
m_inferred_has_nodes(),
m_has_not_nodes(),
has_index(NULL),
has_not_index(NULL)
{
has_index = m_rdf_session_p->create_resource_as_index("top:has_node");
has_not_index = m_rdf_session_p->create_resource_as_index("top:has_not_node");
};
~PSearchSession(){};
inline rule::knowledge_base const*
get_knowledge_base()const
{
return m_kbase_p;
};
inline PSearchDB const*
get_psearch_db()const
{
return m_psearch_db_p;
};
inline rdf::rdf_session_ptr_type
get_rdf_session()
{
return m_rdf_session_p;
};
inline void
set_session_subject(index_type subject_index)
{
m_subject = subject_index;
// initialize the session from assertion/inferred facts from rdf session.
// has nodes
rdf::rdf_graph::index_iterator itor = m_rdf_session_p->get_asserted_graph()->find_index(m_subject, has_index, rdf::all_objects());
while(not itor.is_end()) {
index_type index = itor.get_triple().get_object();
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(node_index) {
m_has_nodes.insert(node_index);
}
itor.next();
}
// inferred has nodes - m_inferred_has_nodes
itor = m_rdf_session_p->get_inferred_graph()->find_index(m_subject, has_index, rdf::all_objects());
while(not itor.is_end()) {
index_type index = itor.get_triple().get_object();
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(node_index) {
m_inferred_has_nodes.insert(node_index);
}
itor.next();
}
// has not nodes
itor = m_rdf_session_p->get_asserted_graph()->find_index(m_subject, has_not_index, rdf::all_objects());
while(not itor.is_end()) {
index_type index = itor.get_triple().get_object();
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(node_index) {
m_has_not_nodes.insert(node_index);
}
itor.next();
}
};
inline void
set_session_subject(std::string const& name)
{
set_session_subject(m_rdf_session_p->create_resource_as_index(name));
};
inline index_type
get_session_subject()const
{
return m_subject;
};
inline unsigned int
get_nbr_nodes()const
{
return m_has_nodes.size() + m_inferred_has_nodes.size();
};
inline unsigned int
get_nbr_negated_nodes()const
{
return m_has_not_nodes.size();
};
inline psresult_ptr_type
query(query_params const& params, bool verbose)
{
if(not m_subject) throw rdf::rdf_exception(rdf::invalid_index, "ERROR-P01: psearch_session subject must be set");
PSearchQuery query(m_psearch_db_p, this);
return query.query(params, verbose);
};
// return the same psresult_ptr_type as it was psearch query but returns all
// nodes of the category (wrapped in nsc)
inline psresult_ptr_type
query(category_index_type category_index, bool verbose)
{
if(not m_subject) throw rdf::rdf_exception(rdf::invalid_index, "ERROR-P01: psearch_session subject must be set");
PSearchQuery query(m_psearch_db_p, this);
return query.query(category_index, verbose);
};
inline psresult_ptr_type
infer(bool verbose)
{
if(not m_subject) throw rdf::rdf_exception(rdf::invalid_index, "ERROR-P01: psearch_session subject must be set");
PSearchInfer infer(m_psearch_db_p, this);
return infer.infer(verbose);
};
/////////////////////////////////////////////////////////////////////////////
// has nodes methods
/////////////////////////////////////////////////////////////////////////////
// asserted nodes
inline node_const_iterator_type
get_nodes_begin()const
{
return m_has_nodes.begin();
};
inline node_const_iterator_type
get_nodes_end()const
{
return m_has_nodes.end();
};
// inferred nodes
inline node_const_iterator_type
get_inferred_nodes_begin()const
{
return m_inferred_has_nodes.begin();
};
inline node_const_iterator_type
get_inferred_nodes_end()const
{
return m_inferred_has_nodes.end();
};
// both asserted and inferred
inline node_dual_set_const_iterator
get_nodes_iterator()const
{
return node_dual_set_const_iterator(
get_nodes_begin(), get_nodes_end(),
get_inferred_nodes_begin(), get_inferred_nodes_end());
};
// asserted only
inline void
add_nodes(node_set_type const& nodes)
{
for(node_set_type::const_iterator itor=nodes.begin(); itor!=nodes.end(); ++itor) add_node(*itor);
};
inline void
add_node(node_index_type node_index)
{
if(!node_index) return;
m_has_nodes.insert(node_index);
m_rdf_session_p->insert(m_subject, has_index, node_index->get_rdf_index());
};
inline void
add_node(std::string const& name)
{
node_index_type node_index = m_psearch_db_p->get_node_index(name);
if(not node_index) return;
add_node(node_index);
};
inline void
add_node(index_type index)
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(not node_index) return;
add_node(node_index);
};
// inferred
inline void
add_inferred_node(node_index_type node_index)
{
if(!node_index) return;
m_inferred_has_nodes.insert(node_index);
m_rdf_session_p->insert_inferred(m_subject, has_index, node_index->get_rdf_index());
};
inline void
add_inferred_node(std::string const& name)
{
node_index_type node_index = m_psearch_db_p->get_node_index(name);
if(not node_index) return;
add_inferred_node(node_index);
};
inline void
add_inferred_node(index_type index)
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(not node_index) return;
add_inferred_node(node_index);
};
// inferred
inline void
clear_inferred_nodes()
{
node_const_iterator_type itor = get_inferred_nodes_begin();
node_const_iterator_type end = get_inferred_nodes_end();
for(; itor!=end; ++itor) {
m_rdf_session_p->erase(m_subject, has_index, (*itor)->get_rdf_index());
}
m_inferred_has_nodes.clear();
};
// either asserted or inferred
inline bool
has_node(node_index_type node_index)const
{
if(!node_index) return false;
if(m_has_nodes.find(node_index) != m_has_nodes.end()) return true;
if(m_inferred_has_nodes.find(node_index) != m_inferred_has_nodes.end()) return true;
return false;
};
inline bool
has_node(index_type index)const
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(!node_index) return false;
if(m_has_nodes.find(node_index) != m_has_nodes.end()) return true;
if(m_inferred_has_nodes.find(node_index) != m_inferred_has_nodes.end()) return true;
return false;
};
inline bool
is_asserted_has_node(node_index_type node_index)const
{
if(!node_index) return false;
if(m_has_nodes.find(node_index) != m_has_nodes.end()) return true;
return false;
};
inline bool
is_asserted_has_node(index_type index)const
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(!node_index) return false;
if(m_has_nodes.find(node_index) != m_has_nodes.end()) return true;
return false;
};
inline void
remove_node(node_index_type node_index)
{
if(!node_index) return;
if(m_has_nodes.erase(node_index) > 0 or m_inferred_has_nodes.erase(node_index) > 0) {
m_rdf_session_p->erase(m_subject, has_index, node_index->get_rdf_index());
}
if(m_has_not_nodes.erase(node_index) > 0) {
m_rdf_session_p->erase(m_subject, has_not_index, node_index->get_rdf_index());
}
};
inline void
remove_node(std::string const& name)
{
node_index_type node_index = m_psearch_db_p->get_node_index(name);
if(not node_index) return;
remove_node(node_index);
};
inline void
remove_node(index_type index)
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(not node_index) return;
remove_node(node_index);
};
/////////////////////////////////////////////////////////////////////////////
// has not nodes methods
/////////////////////////////////////////////////////////////////////////////
inline node_const_iterator_type
get_negated_nodes_begin()const
{
return m_has_not_nodes.begin();
};
inline node_const_iterator_type
get_negated_nodes_end()const
{
return m_has_not_nodes.end();
};
inline node_set_const_iterator
get_negated_nodes_iterator()const
{
return node_set_const_iterator(get_negated_nodes_begin(), get_negated_nodes_end());
};
inline void
add_negated_nodes(node_set_type const& nodes)
{
for(node_set_type::const_iterator itor=nodes.begin(); itor!=nodes.end(); ++itor) add_negated_node(*itor);
};
inline void
add_negated_node(node_index_type node_index)
{
if(!node_index) return;
m_has_not_nodes.insert(node_index);
m_rdf_session_p->insert(m_subject, has_not_index, node_index->get_rdf_index());
};
inline void
add_negated_node(std::string const& name)
{
node_index_type node_index = m_psearch_db_p->get_node_index(name);
if(not node_index) return;
add_negated_node(node_index);
};
inline void
add_negated_node(index_type index)
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(not node_index) return;
add_negated_node(node_index);
};
inline bool
has_negated_node(node_index_type node_index)const
{
if(!node_index) return false;
return m_has_not_nodes.find(node_index) != m_has_not_nodes.end();
};
inline bool
has_negated_node(index_type index)const
{
node_index_type node_index = m_psearch_db_p->get_node_index(index);
if(not node_index) return false;
return m_has_not_nodes.find(node_index) != m_has_not_nodes.end();
};
private:
friend class PSearchQuery;
friend class PSearchInfer;
rule::knowledge_base const* m_kbase_p;
PSearchDB const* m_psearch_db_p;
rdf::rdf_session_ptr_type m_rdf_session_p;
index_type m_subject;
node_set_type m_has_nodes;
node_set_type m_inferred_has_nodes;
node_set_type m_has_not_nodes;
public:
index_type has_index;
index_type has_not_index;
};
}; /* psearch namespace */
namespace rule {
inline psearch::psession_ptr_type
rule_engine::create_psearch_session(rdf::rdf_session_ptr_type rdf_sn_p)
{
psearch::psession_ptr_type session_p(new psearch::PSearchSession(&*m_kbase_p, rdf_sn_p));
return session_p;
};
}; /* rule namespace */
#endif /*PSEARCH_SESSION_H_*/