Skip to content
Snippets Groups Projects
functions.h 5.46 KiB
#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