#ifndef FUNCTIONS_H #define FUNCTIONS_H #include <boost/shared_ptr.hpp> #include <boost/assert.hpp> #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_base_of.hpp> #include <libwccl/ops/operator.h> #include <libwccl/values/value.h> #include <libwccl/sentencecontext.h> namespace Wccl { /** * Abstract base class for WCCL operators that are functions returning a Value */ class FunctionBase : public Operator { protected: typedef boost::shared_ptr<Value> BaseRetValPtr; /** * Applies the function, given the sentence context. */ virtual BaseRetValPtr apply_internal(const SentenceContext& context) const = 0; }; /** * Abstract base class template for functional WCCL operators that are functions * returning a value of given type */ template<class TRet> class Function : public FunctionBase { BOOST_MPL_ASSERT( (boost::is_base_of<Value, TRet>) ); BOOST_MPL_ASSERT_NOT( (boost::is_same<Value, TRet>) ); public: /** * Type returned after application of function (shared pointer to * a variable of the specified return type) */ typedef boost::shared_ptr<TRet> RetValPtr; /** * Applies the function, given the sentence context, returning specific * type of Value (as shared pointer). Uses apply_internal which has to * be specified in derived classes. */ RetValPtr apply(const SentenceContext& context) const { RetValPtr v = boost::dynamic_pointer_cast<TRet>(apply_internal(context)); BOOST_ASSERT(v); return v; } }; /** * Abstract base class template for functional WCCL operators returning * a value of given type, while taking a single argument of selected type. * The argument is actually realised as a functional expression that returns * value of the specified type, per the unary function requirements. */ template<class TArg, class TRet> class UnaryFunction : public Function<TRet> { public: /** * Shared pointer type of expression that returns argument for * our unary function application */ typedef boost::shared_ptr<Function<TArg> > ArgExprPtr; UnaryFunction(const ArgExprPtr& arg_expr) : arg_expr_(arg_expr) { BOOST_ASSERT(arg_expr_); } /** * String representation of the unary function, realised by default * as "operator_name(argument_string)" (using open and close * brackets supplied by open_bracket() and close_bracket()) */ virtual std::string to_string(const Corpus2::Tagset& tagset) const { std::string returnValue(this->operator_name(tagset)); returnValue.append(open_bracket()); returnValue.append(arg_expr_->to_string(tagset)); returnValue.append(close_bracket()); return returnValue; } /** * String representation of the unary function, that does not * require tagset. May be incomplete and/or contain internal info. * Realised by default as "raw_operator_name(raw_argument_string)" * (using open and close brackets supplied by open_bracket() * and close_bracket()) */ virtual std::string to_raw_string() const { std::string returnValue(this->raw_operator_name()); returnValue.append(open_bracket()); returnValue.append(arg_expr_->to_raw_string()); returnValue.append(close_bracket()); return returnValue; } protected: const ArgExprPtr arg_expr_; /** * Opening bracket to use in string representation. * By default it is "(", but some operators use "[" */ virtual const char* open_bracket() { return "("; } /** * Closing bracket to use in string representation. * By default it is ")", but some operators use "]" */ virtual const char* close_bracket() { return ")"; } }; /** * Abstract base class template for functional WCCL operators returning * a value of given type, while taking two arguments of selected types. * The arguments are actually realised as functions that return * value of a specified type, per the binary function requirements. */ template<class TArg1, class TArg2, class TRet> class BinaryFunction : public Function<TRet> { public: /** * Shared pointer type of expression that returns first argument for * our binary function application */ typedef boost::shared_ptr<Function<TArg1> > Arg1ExprPtr; /** * Shared pointer type of expression that returns second argument for * our binary function application */ typedef boost::shared_ptr<Function<TArg2> > Arg2ExprPtr; BinaryFunction(const Arg1ExprPtr& arg1_expr, const Arg2ExprPtr& arg2_expr) : arg1_expr_(arg1_expr), arg2_expr_(arg2_expr) { BOOST_ASSERT(arg1_expr_); BOOST_ASSERT(arg2_expr_); } /** * String representation of the binary function, realised by default * as "operator_name(arg1_string, arg2_string)" */ virtual std::string to_string(const Corpus2::Tagset& tagset) const { std::string returnValue(this->operator_name(tagset)); returnValue.append("("); returnValue.append(arg1_expr_->to_string(tagset)); returnValue.append(", "); returnValue.append(arg2_expr_->to_string(tagset)); returnValue.append(")"); return returnValue; } /** * String representation of the binary function, that does not * require tagset. May be incomplete and/or contain internal info. * Realised by default as "raw_operator_name(raw_arg1_string, raw_arg2_string)" */ virtual std::string to_raw_string() const { std::string returnValue(this->raw_operator_name()); returnValue.append("("); returnValue.append(arg1_expr_->to_raw_string()); returnValue.append(", "); returnValue.append(arg2_expr_->to_raw_string()); returnValue.append(")"); return returnValue; } protected: const Arg1ExprPtr arg1_expr_; const Arg2ExprPtr arg2_expr_; }; } /* end ns Wccl */ #endif // FUNCTIONS_H