+ size_t nops() const;
+ ex op(size_t i) const;
+ ex map(map_function & f) const;
+ ex evalf(int level = 0) const;
+ ex subs(const exmap & m, unsigned options = 0) const;
+ void archive(archive_node& n) const;
+ void read_archive(const archive_node& n, lst& syms);
+protected:
+ ex derivative(const symbol & s) const;
+ bool match_same_type(const basic & other) const;
+ unsigned calchash() const;
+
+ // new virtual functions in this class
+public:
+ /** Check whether the index forms a dummy index pair with another index
+ * of the same type. */
+ virtual bool is_dummy_pair_same_type(const basic & other) const;
+
+ // non-virtual functions in this class
+public:
+ /** Get value of index. */
+ ex get_value() const {return value;}
+
+ /** Check whether the index is numeric. */
+ bool is_numeric() const {return is_exactly_a<numeric>(value);}
+
+ /** Check whether the index is symbolic. */
+ bool is_symbolic() const {return !is_exactly_a<numeric>(value);}
+
+ /** Get dimension of index space. */
+ ex get_dim() const {return dim;}
+
+ /** Check whether the dimension is numeric. */
+ bool is_dim_numeric() const {return is_exactly_a<numeric>(dim);}
+
+ /** Check whether the dimension is symbolic. */
+ bool is_dim_symbolic() const {return !is_exactly_a<numeric>(dim);}
+
+ /** Make a new index with the same value but a different dimension. */
+ ex replace_dim(const ex & new_dim) const;
+
+ /** Return the minimum of the dimensions of this and another index.
+ * If this is undecidable, throw an exception. */
+ ex minimal_dim(const idx & other) const;
+
+protected:
+ void print_index(const print_context & c, unsigned level) const;
+ void do_print(const print_context & c, unsigned level) const;
+ void do_print_csrc(const print_csrc & c, unsigned level) const;
+ void do_print_latex(const print_latex & c, unsigned level) const;
+ void do_print_tree(const print_tree & c, unsigned level) const;
+
+protected:
+ ex value; /**< Expression that constitutes the index (numeric or symbolic name) */
+ ex dim; /**< Dimension of space (can be symbolic or numeric) */
+};
+GINAC_DECLARE_UNARCHIVER(idx);
+
+
+/** This class holds an index with a variance (co- or contravariant). There
+ * is an associated metric tensor that can be used to raise/lower indices. */
+class varidx : public idx
+{
+ GINAC_DECLARE_REGISTERED_CLASS(varidx, idx)
+
+ // other constructors
+public:
+ /** Construct index with given value, dimension and variance.
+ *
+ * @param v Value of index (numeric or symbolic)
+ * @param dim Dimension of index space (numeric or symbolic)
+ * @param covariant Make covariant index (default is contravariant)
+ * @return newly constructed index */
+ varidx(const ex & v, const ex & dim, bool covariant = false);
+
+ // functions overriding virtual functions from base classes
+public:
+ bool is_dummy_pair_same_type(const basic & other) const;
+ void archive(archive_node& n) const;
+ void read_archive(const archive_node& n, lst& syms);
+protected:
+ bool match_same_type(const basic & other) const;
+
+ // non-virtual functions in this class
+public:
+ /** Check whether the index is covariant. */
+ bool is_covariant() const {return covariant;}
+
+ /** Check whether the index is contravariant (not covariant). */
+ bool is_contravariant() const {return !covariant;}
+
+ /** Make a new index with the same value but the opposite variance. */
+ ex toggle_variance() const;
+
+protected:
+ void do_print(const print_context & c, unsigned level) const;
+ void do_print_tree(const print_tree & c, unsigned level) const;
+
+ // member variables