Exemplo n.º 1
0
def _distributive(self):
    if self.type in __distributions:
        star = __distributions[self.type]

        extracted = []
        factorList = Counter()

        def _pushToExtracted(child, count):
            assert count == 1
            extracted.append(child)
            factorList.update(keysExcept(child.children,
                                         Expression.isConstant))

        (rest, hasStar) = performIf(self.children, Expression.isType(star),
                                    _pushToExtracted)

        if hasStar:
            # Algorithm for factorization:
            #
            #  1. find the most common factor
            #  2. check if that factor has appeared >1 times. If no, quit.
            #  3. otherwise, scan for all children which contain that factor.
            #  4. remove that factor from those children, and create a new
            #     a*(b+c+d) style expression.

            factorizedOnce = False
            while factorList:
                (commonest, count) = factorList.most_common(1)[0]
                if count == 1:
                    if factorizedOnce:
                        rest.update(extracted)
                        return self.replaceChildren(rest)
                    else:
                        return None
                else:
                    factorizedOnce = True
                    oldExtracted = extracted
                    extracted = []
                    newChildrenList = []
                    for child in oldExtracted:
                        if commonest in child.children:
                            factorList.subtract(
                                keysExcept(child.children,
                                           Expression.isConstant))
                            newChildChildren = Counter(child.children)
                            newChildChildren[commonest] -= 1
                            newChild = child.replaceChildren(newChildChildren)
                            newChildrenList.append(newChild)
                        else:
                            extracted.append(child)
                    newExpression = Expression(
                        star, commonest, Expression(self.type,
                                                    *newChildrenList))
                    extracted.append(newExpression)
                    factorList.update(
                        keysExcept(child.children, Expression.isConstant))
Exemplo n.º 2
0
def _involution(self):
    # (a ^ a) == 0
    if self.type == '^':
        if any(count > 1 for count in list(self.children.values())):
            return Expression(
                self.type,
                *(k for k, c in list(self.children.items()) if c % 2 != 0))
Exemplo n.º 3
0
def _negatedComparison(self):
    # !(a < b)    <=>    b <= a

    if self.type == '!':
        child = self.children[0]
        if child.type in __negatedComparisonMap:
            return Expression(__negatedComparisonMap[child.type],
                              child.children[1], child.children[0])
Exemplo n.º 4
0
 def _evaluteRepetition(child, count):
     grouped.append(Expression(star, child, Constant(count)))
Exemplo n.º 5
0
                            newChildChildren = Counter(child.children)
                            newChildChildren[commonest] -= 1
                            newChild = child.replaceChildren(newChildChildren)
                            newChildrenList.append(newChild)
                        else:
                            extracted.append(child)
                    newExpression = Expression(
                        star, commonest, Expression(self.type,
                                                    *newChildrenList))
                    extracted.append(newExpression)
                    factorList.update(
                        keysExcept(child.children, Expression.isConstant))


Expression.addSimplificationRule(_repetition, 'repetition (a+a+a=3*a)')
Expression.addSimplificationRule(_distributive,
                                 'distributive (a*b+a*c=a*(b+c))')

if __name__ == '__main__':
    import symbolic.simplify.recursive
    from symbolic.expression import Symbol

    Expression.setDebugSimplify(True)

    a = Expression('+', Symbol('a'), Symbol('a'), Symbol('b'), Symbol('a'), Symbol('b'), Symbol('b'), Symbol('a'), Symbol('c')) + \
     Expression('+', Symbol('c'), Symbol('a'), Symbol('c'), Symbol('c'), Symbol('b'), Symbol('a'), Symbol('a'), Symbol('d'))
    assert a.simplify() == Expression(
        '+', Expression('*', Symbol('a'), Constant(7)),
        Expression('*', Symbol('b'), Constant(4)),
        Expression('*', Symbol('c'), Constant(4)), Symbol('d'))
Exemplo n.º 6
0
Expression.addSimplificationRule(_unary, 'fold constant (unary)')
Expression.addSimplificationRule(_binary, 'fold constant (binary)')
Expression.addSimplificationRule(_shortCircuit, 'short circuit')
Expression.addSimplificationRule(_nary, 'fold constant (N-ary)')
Expression.addSimplificationRule(_naryBaseCondition, 'base condition (N-ary)')
Expression.addSimplificationRule(_evaluateIfThenElse,
                                 'constant condition (?:)')

if __name__ == '__main__':
    from symbolic.simplify.recursive import *
    from symbolic.expression import Symbol

    Expression.setDebugSimplify(True)

    a = Constant(3) / Constant(2)
    assert Constant(1.5) == a.simplify()

    a = Expression('+', Constant(1), Constant(5), Constant(12), Constant(44))
    assert Constant(62) == a.simplify()

    a = Expression.if_(Expression.ge(Constant(7), Constant(2)), Constant(11),
                       Constant(55))
    assert Constant(11) == a.simplify()

    a = (Constant(1) ^ Constant(5) - Constant(122) // Constant(4))**Constant(2)
    assert Constant(676) == a.simplify()

    a = Expression('*', Symbol("foo"), Constant(0), Symbol("boo"))
    assert Constant(0) == a.simplify()
Exemplo n.º 7
0
def _idempotent(self):
    # (a & a) == a
    if self.type in ('&', '|', '&&', '||'):
        if any(count > 1 for count in list(self.children.values())):
            return Expression(self.type, *list(self.children.keys()))
Exemplo n.º 8
0
    # (a ^ a) == 0
    if self.type == '^':
        if any(count > 1 for count in list(self.children.values())):
            return Expression(
                self.type,
                *(k for k, c in list(self.children.items()) if c % 2 != 0))


Expression.addSimplificationRule(_flatten,
                                 'commutative semigroup (a*(b*c) == a*b*c)')
Expression.addSimplificationRule(_idempotent, 'idempotent ((a&a) == a)')
Expression.addSimplificationRule(_involution, 'involution ((a^a) == 0)')

if __name__ == '__main__':
    import symbolic.simplify.recursive
    from symbolic.expression import Symbol

    Expression.setDebugSimplify(True)

    a = Symbol('foo') + Symbol('bar') + Symbol(
        'baz') + Symbol('ma') * Symbol('maz') - Symbol('y')
    assert a.simplify() == Expression(
        '+', Symbol('foo'), Symbol('bar'), Symbol('baz'),
        Expression('*', Symbol('ma'), Symbol('maz')), -Symbol('y'))

    a = (Expression('&', Symbol('foo'), Symbol('bar'), Symbol('foo'), Symbol('baz'), Symbol('bar'), Symbol('bar')) & \
      Expression('^', Symbol('foo'), Symbol('bar'), Symbol('foo'), Symbol('baz'), Symbol('bar'), Symbol('bar')))
    assert a.simplify() == Expression(
        '&', Symbol('foo'), Symbol('bar'), Symbol('baz'),
        Expression('^', Symbol('bar'), Symbol('baz')))