def assocunify(u, v, s, eq=core.eq): """ Associative Unification See Also: eq_assoccomm """ res = unify(u, v, s) if res is not False: return (res,) # TODO: iterate through all possibilities if isinstance(u, tuple) and isinstance(v, tuple): uop, u = u[0], u[1:] vop, v = v[0], v[1:] s = unify(uop, vop, s) if s is False: raise StopIteration() op = walk(uop, s) sm, lg = (u, v) if len(u) <= len(v) else (v, u) parts = (groupsizes_to_partition(*gsizes) for gsizes in groupsizes(len(lg), len(sm))) ops = (makeops(op, partition(lg, part)) for part in parts) goal = condeseq([(eq, a, b) for a, b in zip(sm, lg2)] for lg2 in ops) return goaleval(goal)(s) return ()
def test_groupsizes(): assert set(groupsizes(4, 2)) == set(((1, 3), (2, 2), (3, 1))) assert set(groupsizes(5, 2)) == set(((1, 4), (2, 3), (3, 2), (4, 1))) assert set(groupsizes(4, 1)) == set([(4,)]) assert set(groupsizes(4, 4)) == set([(1, 1, 1, 1)])
def assocsized(op, tail, n): """ All associative combinations of x in n groups """ gsizess = groupsizes(len(tail), n) partitions = (groupsizes_to_partition(*gsizes) for gsizes in gsizess) return (makeops(op, partition(tail, part)) for part in partitions)