jlapeyre / Symata.jl

language for symbolic mathematics
Other
174 stars 15 forks source link

Extend to support mixed commutative/noncommutative args in Times? #11

Open Upabjojr opened 9 years ago

Upabjojr commented 9 years ago

Mathematica defines the Orderless attribute on nodes. This is quite a limitation, you need different nodes for ordinary multiplication (Times) and for matrix multiplication (Dot).

SymPy defines the commutativity of Mul according to its args (the args marked by the commutative=False assumption have to maintain their relative order). This has allowed interesting developments, such as the creation of various module to implement operator-based Quantum Mechanics.

Such an addition would be an extension over Mathematica, requiring to handle mixed subranges/subsets in the pattern matcher. But I think it is worth, after all Julia's * commutativity depends on the types it's called with.

jlapeyre commented 9 years ago

I'll have to spend more time looking at how Python does this. On the face of it, it does not make sense to me. In algebra, commutativity or associativity is a property of a binary operator on a set of elements. You can have various binary operators with different properties on the same set of elements. But, if you use the same symbol for operators on two different sets of elements (ie two different algebras), they are not really the same operator. So commutative and associative are properties of operators. This is the standard way to look at it. That said, I don't believe that data structures always need to follow mathematical structures. Mathematica more or less does not have types. So the operators, or Heads carry the Flat and Orderless properties. In Julia, * is used both for multiplying numbers and for concatenating strings. In the former case it is commutative, in the latter not. Julia has a rich type system and this is natural. But, formally, * represents a different operator in the two cases.

Flat and Orderless means that an operator can be nary with no ambiguity. I don't understand what happens if I have a list of args in a nary * operator and the meaning of the operator and it's properties depend on the symbol. For instance * must mean something between the commutative symbols, something between the non-commutative symbols and another between one of each. I assume this makes sense and is useful for something in Python, but I'll have to learn about it.