def ident_remove(expr): """ Remove identities """ ids = map(isid, expr.args) if sum(ids) == 0: # No identities. Common case return expr elif sum(ids) != len(ids): # there is at least one non-identity return new(expr.__class__, *[arg for arg, x in zip(expr.args, ids) if not x]) else: return new(expr.__class__, expr.args[0])
def conglomerate(expr): """ Conglomerate together identical args x + x -> 2x """ groups = sift(expr.args, key) counts = dict((k, sum(map(count, args))) for k, args in groups.items()) newargs = [combine(cnt, mat) for mat, cnt in counts.items()] if set(newargs) != set(expr.args): return new(type(expr), *newargs) else: return expr
def flatten(expr, new=new): """ Flatten T(a, b, T(c, d), T2(e)) to T(a, b, c, d, T2(e)) """ cls = expr.__class__ args = [] for arg in expr.args: if arg.__class__ == cls: args.extend(arg.args) else: args.append(arg) return new(expr.__class__, *args)
def flatten(expr): """ Flatten T(a, b, T(c, d), T2(e)) to T(a, b, c, d, T2(e)) """ cls = expr.__class__ args = [] for arg in expr.args: if arg.__class__ == cls: args.extend(arg.args) else: args.append(arg) return new(expr.__class__, *args)
def __add__(self, item): return new(self, [*self, item])
def all_rl(expr): if is_leaf(expr): return expr else: args = map(rule, expr.args) return new(type(expr), *args)
def top_down_rl(expr): newexpr = rule(expr) if newexpr.is_Atom: return newexpr return new(newexpr.__class__, *map(top_down_rl, newexpr.args))
def bottom_up_rl(expr): if expr.is_Atom: return rule(expr) else: return rule(new(expr.__class__, *map(bottom_up_rl, expr.args)))
def bottom_up_rl(expr): if is_leaf(expr): return rule(expr) else: return rule(new(type(expr), *map(bottom_up_rl, expr.args)))
def __mul__(self, other): return new(self, zip(self, other))
def __rmul__(self, other): return new(self, zip(other, self))
def __rand__(self, other): return new(self, [*other, *self])
def __and__(self, other): return new(self, [*self, *other])
def top_down_rl(expr): newexpr = rule(expr) if is_leaf(newexpr): return newexpr return new(type(newexpr), *map(top_down_rl, newexpr.args))
def sort_rl(expr): return new(expr.__class__, *sorted(expr.args, key=key))
def __radd__(self, item): return new(self, [item, *self])
def bottom_up_rl(expr): if not isinstance(expr, Basic) or expr.is_Atom: return rule(expr) else: return rule(new(expr.__class__, *map(bottom_up_rl, expr.args)))
def top_down_rl(expr): newexpr = rule(expr) if not isinstance(newexpr, Basic) or newexpr.is_Atom: return newexpr return new(newexpr.__class__, *map(top_down_rl, newexpr.args))