+ /** Construct index with given value and dimension.
+ *
+ * @param v Value of index (numeric or symbolic)
+ * @param dim Dimension of index space (numeric or symbolic)
+ * @return newly constructed index */
+ explicit idx(const ex & v, const ex & dim);
+
+ // functions overriding virtual functions from base classes
+public:
+ bool info(unsigned inf) const override;
+ size_t nops() const override;
+ ex op(size_t i) const override;
+ ex map(map_function & f) const override;
+ ex evalf() const override;
+ ex subs(const exmap & m, unsigned options = 0) const override;
+ void archive(archive_node& n) const override;
+ void read_archive(const archive_node& n, lst& syms) override;
+protected:
+ ex derivative(const symbol & s) const override;
+ bool match_same_type(const basic & other) const override;
+ unsigned calchash() const override;
+
+ // 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;