#ifndef PSEARCH_RULE_H_
#define PSEARCH_RULE_H_
#include "psearch_core.h"
namespace psearch {
/////////////////////////////////////////////////////////////////////////////////////////
// class Rule
//
// Logical class used for authoring Patterns, this class generate the associated patterns:
// o contains a set of categories having an existential relationship (at least one
// of their node must be activated - a pattern is create for each node).
// o contains c1 node which are in conjuction together - translate to ci nodes of pattern
/////////////////////////////////////////////////////////////////////////////////////////
class Rule: public PSBase
{
public:
inline Rule(PSearchDB * db_p, index_type index):
PSBase(db_p, index),
m_patterns(),
m_weight(0),
m_ex_categories(),
m_c1_nodes(),
m_c2_nodes(),
m_negated_nodes(),
m_is_active(true),
m_patterns_generated(false)
{};
inline rule_index_type
get_rule_index()const
{
return this;
};
inline bool
is_active() const
{
return m_is_active;
};
inline unsigned int
get_weight() const
{
return m_weight;
};
bool
is_consistent()const;
//////////////////////////////////////////////////////////////////////////////////////
// relationship with Pattern
/////////////////////////////////////////////////////////////////////////////////////
inline bool
has_pattern(pattern_index_type pindex)const
{
return m_patterns.find(pindex) != m_patterns.end();
};
inline pattern_const_iterator_type
get_patterns_begin()const
{
return m_patterns.begin();
};
inline pattern_const_iterator_type
get_patterns_end()const
{
return m_patterns.end();
};
inline pattern_set_const_iterator
get_patterns_iterator()const
{
return pattern_set_const_iterator(get_patterns_begin(), get_patterns_end());
};
inline size_t
get_nbr_patterns()const
{
return m_patterns.size();
};
///////////////////////////////////////////////////////////////////////////////////////
// relationship to Category
//////////////////////////////////////////////////////////////////////////////////////
inline bool
has_ex_category(category_index_type category_index)const
{
return m_ex_categories.find(category_index) != m_ex_categories.end();
};
inline category_const_iterator_type
get_ex_categories_begin()const
{
return m_ex_categories.begin();
};
inline category_const_iterator_type
get_ex_categories_end()const
{
return m_ex_categories.end();
};
inline category_set_const_iterator
get_ex_categories_iterator()const
{
return category_set_const_iterator(get_ex_categories_begin(), get_ex_categories_end());
};
inline size_t
get_nbr_ex_categories()const
{
return m_ex_categories.size();
};
///////////////////////////////////////////////////////////////////////////////////////
// relationship to Node
//////////////////////////////////////////////////////////////////////////////////////
// this consider only nodes (not negated_nodes)
inline bool
is_c1_node(node_index_type node_index)const
{
return m_c1_nodes.find(node_index) != m_c1_nodes.end();
};
// which includes c1 nodes.
inline bool
is_c2_node(node_index_type node_index)const
{
return m_c2_nodes.find(node_index) != m_c2_nodes.end();
};
// based on negated_node
inline bool
is_negated_by_node(node_index_type node_index)const
{
return m_negated_nodes.find(node_index) != m_negated_nodes.end();
};
inline node_const_iterator_type
get_c1_nodes_begin()const
{
return m_c1_nodes.begin();
};
inline node_const_iterator_type
get_c1_nodes_end()const
{
return m_c1_nodes.end();
};
inline node_set_const_iterator
get_c1_nodes_iterator()const
{
return node_set_const_iterator(get_c1_nodes_begin(), get_c1_nodes_end());
};
inline node_const_iterator_type
get_c2_nodes_begin()const
{
return m_c2_nodes.begin();
};
inline node_const_iterator_type
get_c2_nodes_end()const
{
return m_c2_nodes.end();
};
inline node_set_const_iterator
get_c2_nodes_iterator()const
{
return node_set_const_iterator(get_c2_nodes_begin(), get_c2_nodes_end());
};
inline node_exclude_set_const_iterator
get_c2_nodes_only_iterator()const
{
return node_exclude_set_const_iterator(get_c2_nodes_begin(), get_c2_nodes_end(), m_c1_nodes);
};
inline node_const_iterator_type
get_negated_nodes_begin()const
{
return m_negated_nodes.begin();
};
inline node_const_iterator_type
get_negated_nodes_end()const
{
return m_negated_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());
};
protected:
inline void
set_active(bool b)
{
m_is_active = b;
};
inline void
set_weight(unsigned int weight)
{
m_weight = weight;
};
inline void
add_ex_category(category_index_type category_index)
{
if(!category_index) return;
m_ex_categories.insert(category_index);
};
inline void
remove_ex_category(category_index_type category_index)
{
m_ex_categories.erase(category_index);
};
inline void
remove_all_ex_categories()
{
m_ex_categories.clear();
};
inline void
add_c1_node(node_index_type node_index)
{
if(!node_index) return;
m_c1_nodes.insert(node_index);
m_c2_nodes.insert(node_index);
};
inline void
add_c2_node(node_index_type node_index)
{
if(!node_index) return;
m_c2_nodes.insert(node_index);
};
inline void
add_negated_node(node_index_type node_index)
{
if(!node_index) return;
m_negated_nodes.insert(node_index);
};
inline void
remove_c1_node(node_index_type node_index)
{
m_c1_nodes.erase(node_index);
m_c2_nodes.erase(node_index);
};
inline void
remove_c2_node(node_index_type node_index)
{
m_c2_nodes.erase(node_index);
};
inline void
remove_negated_node(node_index_type node_index)
{
m_negated_nodes.erase(node_index);
};
inline void
remove_all_nodes()
{
m_c1_nodes.clear();
m_c2_nodes.clear();
m_negated_nodes.clear();
};
void
generate_patterns(PSearchDB * db_p, bool verbose);
void
generate_xp_patterns(PSearchDB * db_p, node_set_type const& x_nodes, category_vector_type const& categories_stack, bool verbose);
void
init_pattern(PSearchDB * db_p, Pattern & pattern);
inline void
clear_generated_patterns()
{
m_patterns_generated = false;
m_patterns.clear();
};
inline bool
is_patterns_generated()const
{
return m_patterns_generated;
};
private:
friend class PSearchDB;
friend std::ostream& operator<<(std::ostream& out, Rule const& pattern);
friend std::ostream& operator<<(std::ostream& out, rule_index_type rule_index);
pattern_set_type m_patterns;
unsigned int m_weight;
category_set_type m_ex_categories;
node_set_type m_c1_nodes;
node_set_type m_c2_nodes;
node_set_type m_negated_nodes;
bool m_is_active;
bool m_patterns_generated;
};
inline std::ostream& operator<<(std::ostream& out, rule_index_type rule_index)
{
out << *rule_index;
return out;
};
}; /* psearch namespace */
#endif /*PSEARCH_RULE_H_*/