// 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

// IWYU pragma: private
#include "../InternalHeaderCheck.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";
 *
 * \endcode
 *
 * It is currently only used internally to define and manipulate the
 * Eigen::placeholders::last and Eigen::placeholders::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);
  }

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

  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());
  }

  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(); }

  // 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();
  }
};

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
