// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2017 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_SYMBOLIC_INDEX_H
#define EIGEN_SYMBOLIC_INDEX_H

namespace Eigen {

/** \namespace Eigen::symbolic
  * \ingroup Core_Module
  *
  * This namespace defines a set of classes and functions to build and evaluate symbolic expressions of scalar type Index.
  * Here is a simple example:
  *
  * \code
  * // First step, defines symbols:
  * struct x_tag {};  static const symbolic::SymbolExpr<x_tag> x;
  * struct y_tag {};  static const symbolic::SymbolExpr<y_tag> y;
  * struct z_tag {};  static const symbolic::SymbolExpr<z_tag> z;
  *
  * // Defines an expression:
  * auto expr = (x+3)/y+z;
  *
  * // And evaluate it: (c++14)
  * std::cout << expr.eval(x=6,y=3,z=-13) << "\n";
  *
  * // In c++98/11, only one symbol per expression is supported for now:
  * auto expr98 = (3-x)/2;
  * std::cout << expr98.eval(x=6) << "\n";
  * \endcode
  *
  * It is currently only used internally to define and manipulate the Eigen::last and Eigen::lastp1 symbols in Eigen::seq and Eigen::seqN.
  *
  */
namespace symbolic {

template<typename Tag> class Symbol;
template<typename Arg0> class NegateExpr;
template<typename Arg1,typename Arg2> class AddExpr;
template<typename Arg1,typename Arg2> class ProductExpr;
template<typename Arg1,typename Arg2> class QuotientExpr;

// A simple wrapper around an integral value to provide the eval method.
// We could also use a free-function symbolic_eval...
template<typename IndexType=Index>
class ValueExpr {
public:
  ValueExpr(IndexType val) : m_value(val) {}
  template<typename T>
  IndexType eval_impl(const T&) const { return m_value; }
protected:
  IndexType m_value;
};

// Specialization for compile-time value,
// It is similar to ValueExpr(N) but this version helps the compiler to generate better code.
template<int N>
class ValueExpr<internal::FixedInt<N> > {
public:
  ValueExpr() {}
  template<typename T>
  EIGEN_CONSTEXPR Index eval_impl(const T&) const { return N; }
};


/** \class BaseExpr
  * \ingroup Core_Module
  * Common base class of any symbolic expressions
  */
template<typename Derived>
class BaseExpr
{
public:
  const Derived& derived() const { return *static_cast<const Derived*>(this); }

  /** Evaluate the expression given the \a values of the symbols.
    *
    * \param values defines the values of the symbols, it can either be a SymbolValue or a std::tuple of SymbolValue
    *               as constructed by SymbolExpr::operator= operator.
    *
    */
  template<typename T>
  Index eval(const T& values) const { return derived().eval_impl(values); }

#if EIGEN_HAS_CXX14
  template<typename... Types>
  Index eval(Types&&... values) const { return derived().eval_impl(std::make_tuple(values...)); }
#endif

  NegateExpr<Derived> operator-() const { return NegateExpr<Derived>(derived()); }

  AddExpr<Derived,ValueExpr<> > operator+(Index b) const
  { return AddExpr<Derived,ValueExpr<> >(derived(),  b); }
  AddExpr<Derived,ValueExpr<> > operator-(Index a) const
  { return AddExpr<Derived,ValueExpr<> >(derived(), -a); }
  ProductExpr<Derived,ValueExpr<> > operator*(Index a) const
  { return ProductExpr<Derived,ValueExpr<> >(derived(),a); }
  QuotientExpr<Derived,ValueExpr<> > operator/(Index a) const
  { return QuotientExpr<Derived,ValueExpr<> >(derived(),a); }

  friend AddExpr<Derived,ValueExpr<> > operator+(Index a, const BaseExpr& b)
  { return AddExpr<Derived,ValueExpr<> >(b.derived(), a); }
  friend AddExpr<NegateExpr<Derived>,ValueExpr<> > operator-(Index a, const BaseExpr& b)
  { return AddExpr<NegateExpr<Derived>,ValueExpr<> >(-b.derived(), a); }
  friend ProductExpr<ValueExpr<>,Derived> operator*(Index a, const BaseExpr& b)
  { return ProductExpr<ValueExpr<>,Derived>(a,b.derived()); }
  friend QuotientExpr<ValueExpr<>,Derived> operator/(Index a, const BaseExpr& b)
  { return QuotientExpr<ValueExpr<>,Derived>(a,b.derived()); }

  template<int N>
  AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>) const
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N>) const
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
  template<int N>
  ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N>) const
  { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N>) const
  { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }

  template<int N>
  friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N>, const BaseExpr& b)
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N>, const BaseExpr& b)
  { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N>, const BaseExpr& b)
  { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
  template<int N>
  friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N>, const BaseExpr& b)
  { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }

#if (!EIGEN_HAS_CXX14)
  template<int N>
  AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)()) const
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > > operator-(internal::FixedInt<N> (*)()) const
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<-N> > >(derived(), ValueExpr<internal::FixedInt<-N> >()); }
  template<int N>
  ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator*(internal::FixedInt<N> (*)()) const
  { return ProductExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator/(internal::FixedInt<N> (*)()) const
  { return QuotientExpr<Derived,ValueExpr<internal::FixedInt<N> > >(derived(),ValueExpr<internal::FixedInt<N> >()); }

  template<int N>
  friend AddExpr<Derived,ValueExpr<internal::FixedInt<N> > > operator+(internal::FixedInt<N> (*)(), const BaseExpr& b)
  { return AddExpr<Derived,ValueExpr<internal::FixedInt<N> > >(b.derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  friend AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > > operator-(internal::FixedInt<N> (*)(), const BaseExpr& b)
  { return AddExpr<NegateExpr<Derived>,ValueExpr<internal::FixedInt<N> > >(-b.derived(), ValueExpr<internal::FixedInt<N> >()); }
  template<int N>
  friend ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator*(internal::FixedInt<N> (*)(), const BaseExpr& b)
  { return ProductExpr<ValueExpr<internal::FixedInt<N> >,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
  template<int N>
  friend QuotientExpr<ValueExpr<internal::FixedInt<N> >,Derived> operator/(internal::FixedInt<N> (*)(), const BaseExpr& b)
  { return QuotientExpr<ValueExpr<internal::FixedInt<N> > ,Derived>(ValueExpr<internal::FixedInt<N> >(),b.derived()); }
#endif


  template<typename OtherDerived>
  AddExpr<Derived,OtherDerived> operator+(const BaseExpr<OtherDerived> &b) const
  { return AddExpr<Derived,OtherDerived>(derived(),  b.derived()); }

  template<typename OtherDerived>
  AddExpr<Derived,NegateExpr<OtherDerived> > operator-(const BaseExpr<OtherDerived> &b) const
  { return AddExpr<Derived,NegateExpr<OtherDerived> >(derived(), -b.derived()); }

  template<typename OtherDerived>
  ProductExpr<Derived,OtherDerived> operator*(const BaseExpr<OtherDerived> &b) const
  { return ProductExpr<Derived,OtherDerived>(derived(), b.derived()); }

  template<typename OtherDerived>
  QuotientExpr<Derived,OtherDerived> operator/(const BaseExpr<OtherDerived> &b) const
  { return QuotientExpr<Derived,OtherDerived>(derived(), b.derived()); }
};

template<typename T>
struct is_symbolic {
  // BaseExpr has no conversion ctor, so we only have to check whether T can be statically cast to its base class BaseExpr<T>.
  enum { value = internal::is_convertible<T,BaseExpr<T> >::value };
};

/** Represents the actual value of a symbol identified by its tag
  *
  * It is the return type of SymbolValue::operator=, and most of the time this is only way it is used.
  */
template<typename Tag>
class SymbolValue
{
public:
  /** Default constructor from the value \a val */
  SymbolValue(Index val) : m_value(val) {}

  /** \returns the stored value of the symbol */
  Index value() const { return m_value; }
protected:
  Index m_value;
};

/** Expression of a symbol uniquely identified by the template parameter type \c tag */
template<typename tag>
class SymbolExpr : public BaseExpr<SymbolExpr<tag> >
{
public:
  /** Alias to the template parameter \c tag */
  typedef tag Tag;

  SymbolExpr() {}

  /** Associate the value \a val to the given symbol \c *this, uniquely identified by its \c Tag.
    *
    * The returned object should be passed to ExprBase::eval() to evaluate a given expression with this specified runtime-time value.
    */
  SymbolValue<Tag> operator=(Index val) const {
    return SymbolValue<Tag>(val);
  }

  Index eval_impl(const SymbolValue<Tag> &values) const { return values.value(); }

#if EIGEN_HAS_CXX14
  // C++14 versions suitable for multiple symbols
  template<typename... Types>
  Index eval_impl(const std::tuple<Types...>& values) const { return std::get<SymbolValue<Tag> >(values).value(); }
#endif
};

template<typename Arg0>
class NegateExpr : public BaseExpr<NegateExpr<Arg0> >
{
public:
  NegateExpr(const Arg0& arg0) : m_arg0(arg0) {}

  template<typename T>
  Index eval_impl(const T& values) const { return -m_arg0.eval_impl(values); }
protected:
  Arg0 m_arg0;
};

template<typename Arg0, typename Arg1>
class AddExpr : public BaseExpr<AddExpr<Arg0,Arg1> >
{
public:
  AddExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}

  template<typename T>
  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) + m_arg1.eval_impl(values); }
protected:
  Arg0 m_arg0;
  Arg1 m_arg1;
};

template<typename Arg0, typename Arg1>
class ProductExpr : public BaseExpr<ProductExpr<Arg0,Arg1> >
{
public:
  ProductExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}

  template<typename T>
  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) * m_arg1.eval_impl(values); }
protected:
  Arg0 m_arg0;
  Arg1 m_arg1;
};

template<typename Arg0, typename Arg1>
class QuotientExpr : public BaseExpr<QuotientExpr<Arg0,Arg1> >
{
public:
  QuotientExpr(const Arg0& arg0, const Arg1& arg1) : m_arg0(arg0), m_arg1(arg1) {}

  template<typename T>
  Index eval_impl(const T& values) const { return m_arg0.eval_impl(values) / m_arg1.eval_impl(values); }
protected:
  Arg0 m_arg0;
  Arg1 m_arg1;
};

} // end namespace symbolic

} // end namespace Eigen

#endif // EIGEN_SYMBOLIC_INDEX_H
