Work Done

Manuel found a way to use MatchPy Symbol with SymPy Symbol(sample code). Implementing rules using SymPy symbols would increase the speed of module since we don’t have to convert the expressions back and forth (sympy-matchpy).

I am removing constraint(cons()) defined for the patterns and started using CustomConstraint in Patterns. I wasn’t able to do this previously since ManyToOneReplacer was only able to handle MatchPy expressions. Now that I can use CustomConstraint, I have divided the constraint into smaller CustomConstraint. Example:

Old way to define constraint:

pattern3 = Pattern(Int(Pow(x_, Wildcard.optional('m', mpyInt('1'))), x_), cons(And(FreeQ(m, x), NonzeroQ(Add(m_, matchpyInteger(1)))), (m, x)))

New way to define constraint:

pattern3 = Pattern(Int(Pow(x_, Wildcard.optional('m', mpyInt('1'))), x_), CustomConstraint(lambda m, x: FreeQ(m, x)), CustomConstraint(lambda m: NonzeroQ(Add(m_, mpyInt(1)))))

Defining the Constraints in this way will help the ManyToOneReplacer to backtrack easily and thereby improving the overall speed of the module. There is a bug in MatchPy related to this, I hope it will be fixed soon.

I have updated the parser to make the above changes. It divides the constraint into different constraints if the head of expression tree is And:

def _divide_constriant(s, symbols):
    # Creates a CustomConstraint of the form `CustomConstraint(lambda a, x: FreeQ(a, x))`
    if s[0] == 'FreeQ':
        return ''
    lambda_symbols = list(set(get_free_symbols(s, symbols, [])))
    return 'CustomConstraint(lambda {}: {})'.format(','.join(lambda_symbols), generate_sympy_from_parsed(s))

def divide_constraint(s, symbols):
    if s[0] == 'And':
        result = [_divide_constriant(i, symbols) for i in s[1:]]
    else:
        result = _divide_constriant(s, symbols)

    r = ['']
    for i in result:
        if i != '':
            r.append(i)

    return ', '.join(r)

Todo

  • Parse all the rules using SymPy Symbol
  • Remove sympy-matchpy converters and matchpy Operations