-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional wildcards to match the identity element of the current node #69
Comments
I like the idea. Would you be interested in working on this? I currently don't have the time. My idea to implement this would be to define some special "neutral element" value that can be used for One could also make this special value the default value for the |
Testing this feature in Wolfram Mathematica (they support it by appending a dot to the wildcard):
So... no match is found in the second case.
Again, Mathematica calls it default value.
This can be easily done with a single-dispatched method. |
I think, this is only a reasonable answer in this case. On another hand (here we got the default value for Times instead):
We shouldn't blindly copy Mathematica. "Neutral element" or "identity element" (or just "identity") makes much more sense. BTW, as Operation's may be non-commutative - probably, we must support "left identy" and "right identy" cases. |
That makes sense within an algebraic context. Consider that MatchPy's scope is a lot wider... you could for example use it to match XML files (the commutative property may be helpful there, not sure about the associative one). default as a name makes more sense in these contexts.
There it become more complicated. Matrix expressions in SymPy need the size of the matrix for the identity matrix... I think this is too complicated and maybe out of scope for a pattern matching library. |
Hmm, why this doesn't fit "algebraic context"? AFAIK, this notion doesn't assume associativity or commutativity. On another hand, the identity notion assume binary operation (which may be not the case)... But then, the default value may be specific for every argument (more generic case for left and right identities).
Maybe, I don't know the MatchPy codebase enough. But lets at least investigate this first. The current MatchPy API fits exactly this case. I.e. we can have non-commutative and even non-associative operators. Thus, we can't assume that left and right identities - are equal. On another hand, two-sided identity will be, probably, the most practically used use-case. Maybe we should restrict this mechanism only for monoids (where there are no such complications - and any identity element is both left and right)? |
MatchPy does not exactly replicate the behavior of Mathematica. The reason is that there are some cases where Mathematica behaves in a way that could be considered inconsistent (Example: https://arxiv.org/pdf/1705.00907.pdf, pp.11–12. See also https://doi.org/10.1007/978-3-030-23250-4_6 and https://doi.org/10.1016/j.jsc.2008.05.001 for a very formal discussion of what exactly Mathematica might be doing). Thus, I would not use Mathematica as a reference for what MatchPy should do in such special cases. I would say that now already, MatchPy behaves reasonably for this special case: from matchpy import *
a = Symbol('a')
b = Symbol('b')
c = Symbol('c')
d = Symbol('d')
one = Symbol('1')
zero = Symbol('0')
x0 = Wildcard.optional("x", zero)
x1 = Wildcard.optional("x", one)
Add = Operation.new('Add', Arity.polyadic, associative=True, commutative=True, one_identity=True)
Mul = Operation.new('Mul', Arity.polyadic, associative=True, commutative=True, one_identity=True)
f = Operation.new('f', Arity.binary)
p = Pattern(f(Add(x0, a), Mul(x1, b)))
>>> list(match(f(a, b), p))
[]
>>> list(match(f(Add(a, c), b), p))
[]
>>> list(match(f(Add(a, c), Mul(b, c)), p))
[{'x': Symbol('c')}]
>>> list(match(f(Add(a, c), Mul(b, d)), p))
[]
>>> list(match(f(Add(a, one), b), p))
[{'x': Symbol('1')}]
>>> list(match(f(a, Mul(b, zero)), p))
[{'x': Symbol('0')}] Regarding the implementation: After thinking about it for a bit, I would not implement this feature by replacing the wildcards in a pattern. It might be unlikely, but this could lead to unexpected results if the user starts using the pattern for something different than matching. Perhaps I can find some time to take a look at the code soon. Regarding the name: We also use more "algebraic" names for what is called Regarding left- and right-identities: I wouldn't support this. I expect that it requires a lot more changes, and I don't think that this feature would be used a lot. The way I see it, it should be possible to simulate left- and right-identities now already by manually specifying different identity elements depending on the position in the pattern (with the exception of identity matrices that require a size, but I would consider that out of scope). |
Maybe we still need the definition of identity elements in MatchPy, but for a different reason: I'm realizing that |
When using the
optional=value
argument in Wildcard, one can specify which value to get in case no matching is found. The value has to be given for every wildcard.In case of addition and multiplication, the usual optional values are the identity elements, zero and one respectively.
It would be nice to have the possibility to have the optional value to return the identity element of the current node, if available.
The text was updated successfully, but these errors were encountered: