# How can I manipulate Clifford Algebra elements symbolically?

**Problem**

Sometimes I would like to run functions from the Expression class on a Clifford algebra element. For example, simplification:

```
qf = DiagonalQuadraticForm(SR,[1,1,1])
Cl.<e1,e2,e3> = CliffordAlgebra(qf)
u, v = var(‘u v’)
((sin(u)^2 + cos(u)^2)*e1).simplify_full()
```

I receive the error:

```
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In [91], line 4
1 #u,v = var('u v')
2 #SR(e1)
3 #e1.simplify_full()
----> 4 ((sin(u)**Integer(2) + cos(u)**Integer(2))*e1).simplify_full()
File /ext/sage/10.2/src/sage/structure/element.pyx:489, in sage.structure.element.Element.__getattr__()
487 AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah'...
488 """
--> 489 return self.getattr_from_category(name)
490
491 cdef getattr_from_category(self, name) noexcept:
File /ext/sage/10.2/src/sage/structure/element.pyx:502, in sage.structure.element.Element.getattr_from_category()
500 else:
501 cls = P._abstract_element_class
--> 502 return getattr_from_other_class(self, cls, name)
503
504 def __dir__(self):
File /ext/sage/10.2/src/sage/cpython/getattr.pyx:357, in sage.cpython.getattr.getattr_from_other_class()
355 dummy_error_message.cls = type(self)
356 dummy_error_message.name = name
--> 357 raise AttributeError(dummy_error_message)
358 cdef PyObject* attr = instance_getattr(cls, name)
359 if attr is NULL:
AttributeError: 'CliffordAlgebra_with_category.element_class' object has no attribute 'simplify_full'
```

The behavior I would like is to treat e1, e2, and e3 as symbols. But SR(e1) throws `TypeError: Unable to convert e1 to a symbolic expression`

.

**Why I think this should work**

An analogous addition of structure preserves simplification operations, namely with vectors: `vector([sin(u)^2 + cos(u)^2,u]).simplify_full()`

returns (1,u).

**Current Workaround**

My current workaround is to extract the coefficients, map them with the operations in question, and then recreate the Clifford algebra term.

```
def lift(fxn):
def fxn_aux(ga_term, *args):
a,b,c,d,e,f,g,h = [fxn(x, *args) for x in ga_term.dense_coefficient_list()]
return a + b*e1 + c*e2 + d*e3 + e*e1*e2 + f*e1*e3 + g*e2*e3 + h*e1*e2*e3
return fxn_aux
simp = lift(Expression.simplify_full)
ga_diff = lift(diff)
u,v = var('u v')
s = cos(u)*e1+sin(u)*cos(v)*e2+sin(u)*sin(v)*e3
show(simp(3 + (cos(u)^2 + sin(u)^2)*e1))
show(ga_diff(s,u))
```

**Question**

Is there a more elegant or canonical way to do this?