My time this week has been spent working on Matt's project. In my last post, I mentioned how there was difficulty teaching the code to adhere to special quantum rules as the quantum objects get swallowed up inside Mul, Add and Pow objects. In order to remedy this, I needed to create a new set of binary operation classes that adhere to these rules with the same op-priority as other quantum objects.
To do this, I put logic inside the binary-ops' __new__ method which called a set of logic rules. These rules return an instance of the correct object if an object should be created or raise an error if the input expression is nonesense. For this to work, binary-op objects must know to what quantum type they evaluate (e.g. to what Hilbert space they belong as well as whether they act as a Ket, Bra, or Operator when evaluated). Thus, I used __slots__ to contain 'hilbert_space' and 'evaluates' attributes; these attributes are set during initialization in the 'rules' class methods. To make this simpler, all Quantum Objects inherit from a QuantumBasic class which contains the op_priority information, __slots__ for 'hilbert_space' and 'evaluates', as well as the __mul__, __add__, __pow__ methods which call the __new__ method of our new binary operations.
I mostly have this logic working such that it can flatten non-commutatively for QMul and commutatively for QAdd. However, I still need to get the .expand() method up and working. That said, there is still much testing that needs to be done before I can get this integrated with my code, which makes me worried as the GSoC pencil down date fast approaches.