As I noted on StackOverflow, if you allow the kbin to return empty
sets, those could represent identities (assuming your operation has
one).  Then you would get the matches {a:0, b: 1 + 2 + 3} and {a: 1 +
2 + 3, b: 0}.  Depending on what you use this for, it may be desirable
to include those.

Aaron Meurer

On Tue, Oct 30, 2012 at 4:25 PM, Matthew Rocklin <[email protected]> wrote:
> Chris' code now enables unification to produce all possible matches
>
> In [1]: run ../unify/unify_sympy.py
> In [2]: expr = Add(1, 2, 3, evaluate=False)
> In [3]: a, b = map(Wild, 'ab')
> In [4]: pattern = Add(a, b, evaluate=False)
>
> In [5]: for x in unify(expr, pattern, {}): print x
> {a_: 1, b_: 2 + 3}
> {a_: 2, b_: 1 + 3}
> {a_: 3, b_: 1 + 2}
> {a_: 1 + 2, b_: 3}
> {a_: 2 + 3, b_: 1}
> {a_: 1 + 3, b_: 2}
>
> Of course, this quickly leads to computational blowup. Fortunately you can
> ask very efficiently for just the first, second, etc...
>
> Note that, as Aaron pointed out, this doesn't handle mathematical matching.
> Here is an example which matches a very particular structure.
>
> In [8]: from sympy.abc import x
> In [9]: expr = Add(1, 2*x, 3, evaluate=False)
> In [10]: pattern = Add(a, 2*b, evaluate=False)
> In [11]: for x in unify(expr, pattern, {}): print x
> {a_: 1 + 3, b_: x}
>
> Of course, we don't need to match exact structure. Wilds can currently match
> any node.
>
> In [6]: pattern = Add(a, b, evaluate=False)
>
> In [7]: for x in unify(expr, pattern, {}): print x
> {a_: 1, b_: 2*x + 3}
> {a_: 2*x, b_: 1 + 3}
> {a_: 3, b_: 2*x + 1}
> {a_: 2*x + 1, b_: 3}
> {a_: 2*x + 3, b_: 1}
> {a_: 1 + 3, b_: 2*x}
>
> On Tue, Oct 30, 2012 at 5:13 PM, Matthew Rocklin <[email protected]> wrote:
>>
>> Yes, that works quite well. Thanks Chris!
>>
>>
>> On Tue, Oct 30, 2012 at 4:27 PM, Chris Smith <[email protected]> wrote:
>>>
>>> What is said works, I believe...see the docstring
>>>
>>> def kbin(l, k, ordered=True):
>>>     """
>>>     Return sequence ``l`` partitioned into ``k`` bins.
>>>     If ordered is True then the order of the items in the
>>>     flattened partition will be the same as the order of the
>>>     items in ``l``; if False, all permutations of the items will
>>>     be given; if None, only unique permutations for a given
>>>     partition will be given.
>>>
>>>     Examples
>>>     ========
>>>
>>>     >>> from sympy.utilities.iterables import kbin
>>>     >>> for p in kbin(range(3), 2):
>>>     ...     print p
>>>     ...
>>>     [[0], [1, 2]]
>>>     [[0, 1], [2]]
>>>     >>> for p in kbin(range(3), 2, ordered=False):
>>>     ...     print p
>>>     ...
>>>     [(0,), (1, 2)]
>>>     [(0,), (2, 1)]
>>>     [(1,), (0, 2)]
>>>     [(1,), (2, 0)]
>>>     [(2,), (0, 1)]
>>>     [(2,), (1, 0)]
>>>     [(0, 1), (2,)]
>>>     [(0, 2), (1,)]
>>>     [(1, 0), (2,)]
>>>     [(1, 2), (0,)]
>>>     [(2, 0), (1,)]
>>>     [(2, 1), (0,)]
>>>     >>> for p in kbin(range(3), 2, ordered=None):
>>>     ...     print p
>>>     ...
>>>     [[0], [1, 2]]
>>>     [[1], [2, 0]]
>>>     [[2], [0, 1]]
>>>     [[0, 1], [2]]
>>>     [[1, 2], [0]]
>>>     [[2, 0], [1]]
>>>
>>>     """
>>>     from sympy.utilities.iterables import partitions, permutations
>>>     def rotations(seq):
>>>         for i in range(len(seq)):
>>>             yield seq
>>>             seq.append(seq.pop(0))
>>>     if ordered is None:
>>>         func = rotations
>>>     else:
>>>         func = permutations
>>>     for p in partitions(len(l), k):
>>>         if sum(p.values()) != k:
>>>             continue
>>>         for pe in permutations(p.keys()):
>>>             rv = []
>>>             i = 0
>>>             for part in pe:
>>>                 for do in range(p[part]):
>>>                     j = i + part
>>>                     rv.append(l[i: j])
>>>                     i = j
>>>             if ordered:
>>>                 yield rv
>>>             else:
>>>                 template = [len(i) for i in rv]
>>>                 for pp in func(l):
>>>                     rvp = []
>>>                     ii = 0
>>>                     for t in template:
>>>                         jj = ii + t
>>>                         rvp.append(pp[ii: jj])
>>>                         ii = jj
>>>                     yield rvp
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "sympy" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected].
>>> For more options, visit this group at
>>> http://groups.google.com/group/sympy?hl=en.
>>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sympy?hl=en.

-- 
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to