- if (is_a<clifford>(other)) {
- return same_metric(ex_to<clifford>(other).get_metric());
- } else if (is_a<indexed>(other)) {
- return get_metric(other.op(1), other.op(2)).is_equal(other);
- } else
- return false;
+ ex metr;
+ if (is_a<clifford>(other))
+ metr = ex_to<clifford>(other).get_metric();
+ else
+ metr = other;
+
+ if (is_a<indexed>(metr))
+ return metr.op(0).is_equal(get_metric().op(0));
+ else {
+ exvector indices = metr.get_free_indices();
+ return (indices.size() == 2)
+ && simplify_indexed(get_metric(indices[0], indices[1])-metr).is_zero();
+ }
+}
+
+//////////
+// functions overriding virtual functions from base classes
+//////////
+
+ex clifford::op(size_t i) const
+{
+ GINAC_ASSERT(i<nops());
+ if (nops()-i == 1)
+ return representation_label;
+ else
+ return inherited::op(i);
+}
+
+ex & clifford::let_op(size_t i)
+{
+ GINAC_ASSERT(i<nops());
+
+ static ex rl = numeric(representation_label);
+ ensure_if_modifiable();
+ if (nops()-i == 1)
+ return rl;
+ else
+ return inherited::let_op(i);
+}
+
+ex clifford::subs(const exmap & m, unsigned options) const
+{
+ ex subsed = inherited::subs(m, options);
+ if(is_a<clifford>(subsed)) {
+ ex prevmetric = ex_to<clifford>(subsed).metric;
+ ex newmetric = prevmetric.subs(m, options);
+ if(!are_ex_trivially_equal(prevmetric, newmetric)) {
+ clifford c = ex_to<clifford>(subsed);
+ c.metric = newmetric;
+ subsed = c;
+ }
+ }
+ return subsed;