+// Attach index to expression
+ex attach_index(const ex & base, ex i, bool covariant)
+{
+ // Toggle index variance if necessary
+ if (is_a<varidx>(i)) {
+ const varidx &vi = ex_to<varidx>(i);
+ if (vi.is_covariant() != covariant)
+ i = vi.toggle_variance();
+ } else if (!covariant)
+ throw (std::runtime_error("index '" + get_symbol_name(i) + "' is not a varidx and cannot be contravariant"));
+
+ // Add index to an existing indexed object, or create a new indexed
+ // object if there are no indices yet
+ if (is_a<indexed>(base)) {
+ const ex &b = base.op(0);
+ exvector iv;
+ for (unsigned n=1; n<base.nops(); n++)
+ iv.push_back(base.op(n));
+ iv.push_back(i);
+ return indexed(b, iv);
+ } else
+ return indexed(base, i);
+}
+