#ifndef RULE_EXPRESSION_H_
#define RULE_EXPRESSION_H_
#include "rdf_rule_core.h"
#include "rdf_date_time.h"
#include "rdf_session.h"
#include "rule_internal.h"
#include "rule_term_base.h"
namespace rule {
class rule_session;
namespace internal {
using rdf::index_type;
using rdf::internal::no_value;
using rdf::literal;
using rdf::int_type;
using rdf::u_int_type;
using rdf::real_type;
using rdf::date_type;
using rdf::time_type;
using rdf::duration_type;
using rdf::unset;
using rdf::integer;
using rdf::unsigned_integer;
using rdf::real;
using rdf::date;
using rdf::time;
using rdf::duration;
using rdf::string;
using rdf::internal::to_literal;
using rdf::internal::to_resource_base;
/////////////////////////////////////////////////////////////////////////////////////////
// class expression_data
//
// class used to pass working data between terms of expression_rule_term
/////////////////////////////////////////////////////////////////////////////////////////
class expression_data
{
public:
expression_data():
m_type(unset),
m_data(),
m_str(),
m_index()
{};
expression_data(
no_value const nv):
m_type(unset),
m_data(nv),
m_str(),
m_index()
{};
expression_data(
int_type const i):
m_type(integer),
m_data(i),
m_str(),
m_index()
{};
expression_data(
u_int_type const ui):
m_type(unsigned_integer),
m_data(ui),
m_str(),
m_index()
{};
expression_data(
real_type const f):
m_type(real),
m_data(f),
m_str(),
m_index()
{};
expression_data(
std::string const& str):
m_type(string),
m_data(),
m_str(str),
m_index()
{};
expression_data(
date_type const d):
m_type(date),
m_data(d),
m_str(),
m_index()
{};
expression_data(
time_type const t):
m_type(time),
m_data(t),
m_str(),
m_index()
{};
expression_data(
duration_type const t):
m_type(duration),
m_data(t),
m_str(),
m_index()
{};
expression_data(
index_type const index):
m_type(rdf::index_internal),
m_data(),
m_str(),
m_index(index)
{};
expression_data(
literal const& l):
m_type(l.m_type),
m_data(l.m_data),
m_str(l.m_str),
m_index(l.get_index())
{};
~expression_data() {};
int const get_type()const{return m_type;};
std::string get_type_name()const
{
switch(m_type)
{
case unset: return "unset";
case integer: return "integer";
case unsigned_integer: return "unsigned_integer";
case real: return "real";
case date: return "date";
case time: return "time";
case duration: return "duration";
case string: return "string";
default: return "index_type";
};
};
inline expression_data & operator=(expression_data const& rhs)
{
m_type = rhs.m_type;
m_data = rhs.m_data;
m_str = rhs.m_str;
m_index = rhs.m_index;
return *this;
};
bool operator==(expression_data const& rhs)const
{
if(m_type != rhs.m_type) return false;
switch(m_type)
{
case unset: return m_data.m_nv == rhs.m_data.m_nv;
case integer: return m_data.m_int == rhs.m_data.m_int;
case unsigned_integer: return m_data.m_uint == rhs.m_data.m_uint;
case real: return m_data.m_real == rhs.m_data.m_real;
case date: return m_data.m_date.d == rhs.m_data.m_date.d;
case time: return m_data.m_time.d == rhs.m_data.m_time.d;
case duration: return m_data.m_duration.d == rhs.m_data.m_duration.d;
case string: return m_str == rhs.m_str;
default: return m_index == rhs.m_index;
};
};
bool operator!=(expression_data const& rhs)const
{
return !operator==(rhs);
};
no_value const get_unset()const
{
if(m_type == unset) return m_data.m_nv;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_unset: this expression_data is not 'unset'");
};
int_type const get_int()const
{
if(m_type == integer) return m_data.m_int;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_int: this expression_data is not 'integer'");
};
u_int_type const get_uint()const
{
if(m_type == unsigned_integer) return m_data.m_uint;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_uint: this expression_data is not 'unsigned_integer'");
};
real_type const get_real()const
{
if(m_type == real) return m_data.m_real;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_real: this expression_data is not 'real'");
};
date_type const get_date()const
{
if(m_type == date) return m_data.m_date;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_date: this expression_data is not 'date'");
};
time_type const get_time()const
{
if(m_type == time) return m_data.m_time;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_time: this expression_data is not 'time'");
};
duration_type const get_duration()const
{
if(m_type == duration) return m_data.m_duration;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_duration: this expression_data is not 'duration'");
};
std::string const& get_string()const
{
if(m_type == string) return m_str;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_string: this expression_data is not 'string'");
};
index_type const get_index()const
{
if(m_type == rdf::index_internal) return m_index;
throw rdf::rdf_exception(rdf::invalid_literal_type,
"expression_data::get_index: this expression_data is not 'index_type'");
};
private:
friend std::ostream& operator<<(std::ostream& out, expression_data const& l);
int m_type;
rdf::internal_data m_data;
std::string m_str;
index_type m_index;
};
inline std::ostream& operator<<(std::ostream& out, expression_data const& l)
{
out << " [";
switch(l.m_type)
{
case unset: out << l.m_data.m_nv; break;
case integer: out << l.m_data.m_int; break;
case unsigned_integer: out << l.m_data.m_uint; break;
case real: out << l.m_data.m_real; break;
case date: out << to_string(l.m_data.m_date); break;
case time: out << to_string(l.m_data.m_time); break;
case duration: out << to_string(l.m_data.m_duration); break;
case string: out << l.m_str; break;
default: out << *l.m_index;
};
out << ", " << l.get_type_name() << "]";
return out;
};
// ---Arguments Classes------------------------------------------------------------------------------
class fi_index_type;
class fi_literal;
class expression_rule_term_base;
class fa
{
public:
inline fa(literal const& l):
m_value(l)
{};
inline fa(index_type const& idx):
m_value(idx)
{
if(idx->is_literal()) m_value = expression_data(to_literal(idx));
};
inline expression_data const operator()(rule_session *, relation_row_map const& row)const{return m_value;};
inline bool is_same_as(fi_index_type const& x)const{return false;};
inline bool is_same_as(fi_literal const& x)const{return false;};
inline bool is_same_as(fa const& x)const
{
return m_value == x.m_value;
};
inline bool is_same_as(expression_rule_term_base const& x)const{return false;};
private:
expression_data m_value;
};
typedef std::tr1::shared_ptr<fa> fa_ptr_type;
class fi_literal
{
public:
inline fi_literal(unsigned int i): m_index(i) {};
inline expression_data const operator()(rule_session *, relation_row_map const& row)const
{
index_type const index = row[m_index];
if(!to_resource_base(index).is_literal()) return expression_data();
return expression_data(to_literal(index));
};
inline bool is_same_as(fi_literal const& x)const{return m_index == x.m_index;};
inline bool is_same_as(fi_index_type const& x)const{return false;};
inline bool is_same_as(fa const& x)const{return false;};
inline bool is_same_as(expression_rule_term_base const& x)const{return false;};
private:
unsigned int m_index;
};
class fi_index_type
{
public:
inline fi_index_type(unsigned int i): m_index(i) {};
inline expression_data const operator()(rule_session *, relation_row_map const& row)const
{
return row[m_index];
};
inline bool is_same_as(fi_index_type const& x)const{return m_index == x.m_index;};
inline bool is_same_as(fi_literal const& x)const{return false;};
inline bool is_same_as(fa const& x)const{return false;};
inline bool is_same_as(expression_rule_term_base const& x)const{return false;};
private:
unsigned int m_index;
};
typedef std::tr1::shared_ptr<fi_literal> fi_literal_ptr_type;
typedef std::tr1::shared_ptr<fi_index_type> fi_index_type_ptr_type;
// --operator-TO_BOOL-----------------------------------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////
// class to_bool
//
/////////////////////////////////////////////////////////////////////////////////////////
struct to_bool
{
typedef bool return_type;
typedef literal_operator_tag operant_type;
return_type operator()(no_value const lhs)const{return false;};
return_type operator()(int_type const lhs)const{return lhs;};
return_type operator()(u_int_type const lhs)const{return lhs;};
return_type operator()(real_type const lhs)const{return lhs;};
return_type operator()(date_type const lhs)const{return lhs.d;};
return_type operator()(time_type const lhs)const{return lhs.d;};
return_type operator()(duration_type const lhs)const{return lhs.d;};
return_type operator()(std::string const& )const{return false;};
return_type operator()(index_type const lhs)const{return lhs;};
};
//enum literal_type {unset, integer, unsigned_integer, real, string};
/////////////////////////////////////////////////////////////////////////////////////////
// apply_visitor
//
// unary operator on literal
/////////////////////////////////////////////////////////////////////////////////////////
template<class Oper>
typename Oper::return_type
apply_visitor(literal_operator_tag const& tag, Oper fv, index_type const& lhs)
{
if(!lhs->is_literal()) {
std::string msg("apply_visitor[1]: Expecting argument of type literal, it looks like it's a resource not a literal");
std::cout << msg << lhs << std::endl;
throw rdf::rdf_exception(rdf::invalid_index, msg);
}
return apply_visitor(tag, fv, expression_data(to_literal(lhs)));
};
template<class Oper>
typename Oper::return_type
apply_visitor(literal_operator_tag const&, Oper fv, expression_data const& lhs)
{
switch(lhs.get_type())
{
case unset: return fv(lhs.get_unset());
case integer: return fv(lhs.get_int());
case unsigned_integer: return fv(lhs.get_uint());
case real: return fv(lhs.get_real());
case date: return fv(lhs.get_date());
case time: return fv(lhs.get_time());
case duration: return fv(lhs.get_duration());
case string: return fv(lhs.get_string());
};
std::string msg("apply_visitor[2]: Invalid literal type: "+lhs.get_type_name()+ ", expression may incorectly mix literals and resources.");
std::cout << msg << lhs << std::endl;
throw rdf::rdf_exception(rdf::unexpected_logic_error, msg);
};
/////////////////////////////////////////////////////////////////////////////////////////
// apply_visitor
//
// unary operator on resource
/////////////////////////////////////////////////////////////////////////////////////////
template<class Oper>
typename Oper::return_type
apply_visitor(resource_operator_tag const& tag, Oper fv, index_type const& lhs)
{
return fv(lhs);
};
template<class Oper>
typename Oper::return_type
apply_visitor(resource_operator_tag const&, Oper fv, expression_data const& lhs)
{
if(!lhs.get_index()) {
std::string msg("apply_visitor[3]: Invalid argument; expecting expression_data as resources but found literal of type: "+lhs.get_type_name()+ ", expression may incorectly mix literals and resources.");
std::cout << msg << lhs << std::endl;
throw rdf::rdf_exception(rdf::unexpected_logic_error, msg);
}
return fv(lhs.get_index());
};
/////////////////////////////////////////////////////////////////////////////////////////
// apply_visitor
//
// binary operator on literals
/////////////////////////////////////////////////////////////////////////////////////////
template<class Oper>
typename Oper::return_type
apply_visitor(literal_operator_tag const& tag, Oper fv, index_type const& lhs, index_type const& rhs)
{
if(!lhs->is_literal()) {
std::string msg("apply_visitor[4]: Expecting argument of type literal, it looks like it's a resource not a literal");
std::cout << msg << lhs << std::endl;
throw rdf::rdf_exception(rdf::invalid_index, msg);
}
if(!rhs->is_literal()) {
std::string msg("apply_visitor[4]: Expecting argument of type literal, it looks like it's a resource not a literal");
std::cout << msg << rhs << std::endl;
throw rdf::rdf_exception(rdf::invalid_index, msg);
}
return apply_visitor(tag, fv, expression_data(to_literal(lhs)), expression_data(to_literal(rhs)));
};
template<class Oper>
typename Oper::return_type
apply_visitor(literal_operator_tag const&, Oper fv, expression_data const& lhs, expression_data const& rhs)
{
switch(lhs.get_type())
{
case unset:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_unset(), rhs.get_unset());
case integer: return fv(lhs.get_unset(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_unset(), rhs.get_uint());
case real: return fv(lhs.get_unset(), rhs.get_real());
case date: return fv(lhs.get_unset(), rhs.get_date());
case time: return fv(lhs.get_unset(), rhs.get_time());
case duration: return fv(lhs.get_unset(), rhs.get_duration());
case string: return fv(lhs.get_unset(), rhs.get_string());
};
break;
case integer:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_int(), rhs.get_unset());
case integer: return fv(lhs.get_int(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_int(), rhs.get_uint());
case real: return fv(lhs.get_int(), rhs.get_real());
case date: return fv(lhs.get_int(), rhs.get_date());
case time: return fv(lhs.get_int(), rhs.get_time());
case duration: return fv(lhs.get_int(), rhs.get_duration());
case string: return fv(lhs.get_int(), rhs.get_string());
};
break;
case unsigned_integer:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_uint(), rhs.get_unset());
case integer: return fv(lhs.get_uint(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_uint(), rhs.get_uint());
case real: return fv(lhs.get_uint(), rhs.get_real());
case date: return fv(lhs.get_uint(), rhs.get_date());
case time: return fv(lhs.get_uint(), rhs.get_time());
case duration: return fv(lhs.get_uint(), rhs.get_duration());
case string: return fv(lhs.get_uint(), rhs.get_string());
};
break;
case real:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_real(), rhs.get_unset());
case integer: return fv(lhs.get_real(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_real(), rhs.get_uint());
case real: return fv(lhs.get_real(), rhs.get_real());
case date: return fv(lhs.get_real(), rhs.get_date());
case time: return fv(lhs.get_real(), rhs.get_time());
case duration: return fv(lhs.get_real(), rhs.get_duration());
case string: return fv(lhs.get_real(), rhs.get_string());
};
break;
case date:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_date(), rhs.get_unset());
case integer: return fv(lhs.get_date(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_date(), rhs.get_uint());
case real: return fv(lhs.get_date(), rhs.get_real());
case date: return fv(lhs.get_date(), rhs.get_date());
case time: return fv(lhs.get_date(), rhs.get_time());
case duration: return fv(lhs.get_date(), rhs.get_duration());
case string: return fv(lhs.get_date(), rhs.get_string());
};
break;
case time:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_time(), rhs.get_unset());
case integer: return fv(lhs.get_time(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_time(), rhs.get_uint());
case real: return fv(lhs.get_time(), rhs.get_real());
case date: return fv(lhs.get_time(), rhs.get_date());
case time: return fv(lhs.get_time(), rhs.get_time());
case duration: return fv(lhs.get_time(), rhs.get_duration());
case string: return fv(lhs.get_time(), rhs.get_string());
};
break;
case duration:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_duration(), rhs.get_unset());
case integer: return fv(lhs.get_duration(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_duration(), rhs.get_uint());
case real: return fv(lhs.get_duration(), rhs.get_real());
case date: return fv(lhs.get_duration(), rhs.get_date());
case time: return fv(lhs.get_duration(), rhs.get_time());
case duration: return fv(lhs.get_duration(), rhs.get_duration());
case string: return fv(lhs.get_duration(), rhs.get_string());
};
break;
case string:
switch(rhs.get_type())
{
case unset: return fv(lhs.get_string(), rhs.get_unset());
case integer: return fv(lhs.get_string(), rhs.get_int());
case unsigned_integer: return fv(lhs.get_string(), rhs.get_uint());
case real: return fv(lhs.get_string(), rhs.get_real());
case date: return fv(lhs.get_string(), rhs.get_date());
case time: return fv(lhs.get_string(), rhs.get_time());
case duration: return fv(lhs.get_string(), rhs.get_duration());
case string: return fv(lhs.get_string(), rhs.get_string());
};
break;
}
std::string msg("apply_visitor[5]: Invalid literal type: "+lhs.get_type_name()+" or "+rhs.get_type_name()+ ", expression may incorectly mix literals and resources.");
std::cout << msg << lhs << " and " << rhs << std::endl;
throw rdf::rdf_exception(rdf::unexpected_logic_error, msg);
};
/////////////////////////////////////////////////////////////////////////////////////////
// apply_visitor
//
// binary operator on resources
/////////////////////////////////////////////////////////////////////////////////////////
template<class Oper>
typename Oper::return_type
apply_visitor(resource_operator_tag const&, Oper fv, index_type const& lhs, index_type const& rhs)
{
return fv(lhs, rhs);
};
template<class Oper>
typename Oper::return_type
apply_visitor(resource_operator_tag const&, Oper fv, expression_data const& lhs, expression_data const& rhs)
{
if(!lhs.get_index() or !rhs.get_index()) {
std::string msg("apply_visitor: Invalid argument; expecting expression_data as resources but found literal of type: "+lhs.get_type_name()+" and "+rhs.get_type_name()+ ", expression may incorectly mix literals and resources.");
std::cout << msg << lhs << " and " << rhs << std::endl;
throw rdf::rdf_exception(rdf::unexpected_logic_error, msg);
}
return fv(lhs.get_index(), rhs.get_index());
};
/////////////////////////////////////////////////////////////////////////////////////////
// class expression_rule_term_base
//
// ---Rule Term Class for Expression (used as filter in the rule terms)
// ---also used as element of filters in the rule head or as element of consequent terms
/////////////////////////////////////////////////////////////////////////////////////////
class expression_rule_term_base;
typedef std::tr1::shared_ptr<expression_rule_term_base> expression_rule_term_ptr_type;
enum xpr_functor_name {fu_name_binary, fw_name_binary, fw_name_unary};
class expression_rule_term_base
{
public:
expression_rule_term_base(){};
virtual ~expression_rule_term_base(){};
virtual bool eval(rule_session * rule_session_p, relation_row_map const& relation_row)const=0;
virtual expression_data const operator()(rule_session * rule_session_p, relation_row_map const& row)const=0;
/* Used by knowledge_rule to merge identical rule_term with existing ones in the rule_graph */
/* see rule_term_base.h */
virtual bool is_same_as(xpr_functor_name const f, fi_literal const&)const=0;
virtual bool is_same_as(xpr_functor_name const f, fi_index_type const&)const=0;
virtual bool is_same_as(xpr_functor_name const f, fa const&)const=0;
virtual bool is_same_as(xpr_functor_name const f, expression_rule_term_base const&)const=0;
virtual bool has_operator(char const* name)const=0;
inline bool is_same_as(expression_rule_term_ptr_type const& rhs)const{return is_same_as(*rhs);};
virtual bool is_same_as(expression_rule_term_base const& rhs)const=0;
inline bool is_same_as(fa const& )const{return false;};
inline bool is_same_as(fi_literal const& )const{return false;};
inline bool is_same_as(fi_index_type const& )const{return false;};
};
/////////////////////////////////////////////////////////////////////////////////////////
// rule_term_base::apply_filter
//
/////////////////////////////////////////////////////////////////////////////////////////
inline bool rule_term_base::apply_filter(rule_session * rule_session_p, relation_row_map const& relation_row)const
{
if(!m_filter_p) return false;
return !m_filter_p->eval(rule_session_p, relation_row);
};
/////////////////////////////////////////////////////////////////////////////////////////
// class expression_rule_term
//
/////////////////////////////////////////////////////////////////////////////////////////
template<class Fu, class Oper, class Fw>
class expression_rule_term: public expression_rule_term_base
{
public:
expression_rule_term(Fu const& fu_, Fw const& fw_):
expression_rule_term_base(),
m_fu(fu_),
m_fw(fw_) {};
~expression_rule_term(){};
expression_data const operator()(rule_session * rule_session_p, relation_row_map const& row)const
{
return apply_visitor(typename Oper::operant_type(), Oper(rule_session_p), (*m_fu)(rule_session_p, row), (*m_fw)(rule_session_p, row));
};
bool eval(rule_session * rule_session_p, relation_row_map const& row)const
{
return apply_visitor(to_bool::operant_type(), to_bool(), (*this)(rule_session_p, row));
};
inline bool is_same_as(xpr_functor_name const f, fi_index_type const& x)const
{
if(f == fu_name_binary) return m_fu->is_same_as(x);
if(f == fw_name_binary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, fi_literal const& x)const
{
if(f == fu_name_binary) return m_fu->is_same_as(x);
if(f == fw_name_binary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, fa const& x)const
{
if(f == fu_name_binary) return m_fu->is_same_as(x);
if(f == fw_name_binary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, expression_rule_term_base const& x)const
{
if(f == fu_name_binary) return m_fu->is_same_as(x);
if(f == fw_name_binary) return m_fw->is_same_as(x);
return false;
};
inline bool has_operator(char const* name)const
{
return strcmp(Oper().name(), name) == 0;
};
inline bool is_same_as(expression_rule_term_base const& ert)const
{
return ert.is_same_as(fu_name_binary, *m_fu) and
ert.is_same_as(fw_name_binary, *m_fw) and
ert.has_operator(Oper().name());
};
private:
Fu m_fu;
Fw m_fw;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class expression_unary_rule_term
//
/////////////////////////////////////////////////////////////////////////////////////////
template<class Oper, class Fw>
class expression_unary_rule_term: public expression_rule_term_base
{
public:
expression_unary_rule_term(Fw const& fw_):
expression_rule_term_base(),
m_fw(fw_) {};
~expression_unary_rule_term(){};
expression_data const operator()(rule_session * rule_session_p, relation_row_map const& row)const
{
return apply_visitor(typename Oper::operant_type(), Oper(rule_session_p), (*m_fw)(rule_session_p, row));
};
bool eval(rule_session * rule_session_p, relation_row_map const& row)const
{
return apply_visitor(to_bool::operant_type(), to_bool(), (*this)(rule_session_p, row));
};
inline bool is_same_as(xpr_functor_name const f, fi_index_type const& x)const
{
if(f == fw_name_unary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, fi_literal const& x)const
{
if(f == fw_name_unary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, fa const& x)const
{
if(f == fw_name_unary) return m_fw->is_same_as(x);
return false;
};
inline bool is_same_as(xpr_functor_name const f, expression_rule_term_base const& x)const
{
if(f == fw_name_unary) return m_fw->is_same_as(x);
return false;
};
inline bool has_operator(char const* name)const
{
return strcmp(Oper().name(), name) == 0;
};
inline bool is_same_as(expression_rule_term_base const& ert)const
{
return ert.is_same_as(fw_name_unary, *m_fw) and
ert.has_operator(Oper().name());
};
private:
Fw m_fw;
};
/////////////////////////////////////////////////////////////////////////////////////////
// class F_expression
//
// ---Adaptor to use expression_rule_term_ptr_type in consequent term - compute the object part of the inferred
// triple from an expression
/////////////////////////////////////////////////////////////////////////////////////////
struct F_expression {
F_expression(expression_rule_term_ptr_type const& ex_p, std::string const& label):
m_expression_p(ex_p),
m_label(label) {};
inline var get_cback_index()const{return var();};
// this version should never be called!
inline index_type operator()(relation_row_map const&)const
{
char const* msg = "F_expression::operator(relation_row_map) called! This should never be called - expression cannot be in rule antecedent part, only in consequent term!";
std::cout << msg << std::endl;
throw rdf::rdf_exception(rdf::unexpected_logic_error, msg);
};
// called to compute consequent term
// define in rule_term.h to ensure inlining due to dependencu on rule_session
inline index_type operator()(rule_session * s, relation_row_map const& row)const;
// used to determine if row produced u in rule_engine::expain_why.
// used by rule_term::merge_row to see if there is a match to newly added u.
inline bool operator()(rule_session * s, relation_row_map const& row, index_type const u)const
{
if(!to_resource_base(u).is_literal()) return false;
expression_data const lu = to_literal(u);
expression_data const l = (*m_expression_p)(s, row);
return lu == l;
};
// used for explain_why - will match depending on row template<>inline unsigned int T_iaa::retract_op(rule_session * rule_session_p, relation_row_map const& relation_row, I_ u, A_ v, A_ w, beta_relation& relation, assertion_tag)const
inline bool is_match_possible(index_type const)const{return true;};
inline relation_row_map::size_type get_lookup_index()const{return beta_relation::NO_LOOKUP_INDEX;};
inline bool has_label(std::string const& label)const{return false;};
inline std::string const& get_label()const{return m_label;};
inline bool check_for_match(rdf::index_type const u)const{return rdf::internal::to_resource_base(u).is_literal();};
inline bool check_for_match(std::string const& s)const{return true;};
inline bool check_for_match(F_expression const& x)const{return true;};
inline F_expression const& get_match_item()const{return *this;};
inline bool is_same_as(F_cst const& x)const{return false;};
inline bool is_same_as(F_join const& x)const{return false;};
inline bool is_same_as(F_var const& x)const{return false;};
inline bool is_same_as(F_expression const& x)const{return m_expression_p->is_same_as(x.m_expression_p);};
private:
expression_rule_term_ptr_type const m_expression_p;
std::string const m_label;
};
inline std::string to_string(F_expression const& f){return f.get_label();};
}; /* internal namespace */
}; /* rule namespace */
#endif /*RULE_EXPRESSION_H_*/