Coder Social home page Coder Social logo

Alternate way to define constraint about matchpy HOT 7 CLOSED

hpac avatar hpac commented on June 13, 2024
Alternate way to define constraint

from matchpy.

Comments (7)

wheerd avatar wheerd commented on June 13, 2024

Yes, you can create your own subclass of the Constraint class. You can have a look at the documentation to see which methods you need to implement to do that. Fo example:

class FreeQ(Constraint):
    def __init__(self, vars, x):
        self.vars = frozenset(v.name for v in vars)
        self.x = x

    def __call__(self. substitution):
        for v in self.vars:
            if substitution[v].contains(x):
                return False
        return True

    @property
    def variables(self):
        return self.vars

    def with_renamed_vars(self.renaming):
        copy = FreeQ([], self.x)
        copy.vars = frozenset(renaming.get(v, v) for v in self.vars)
        return copy

    def __eq__(self, other):
        return isinstance(other, FreeQ) and other.vars == self.vars and other.x == self.x

    def __hash__(self):
        return hash((self.vars, self.x))

The variables property is used to the many-to-one matcher can optimize when the test the constraint (as soon as all variables have a substitution). This enables earlier backtracking and should speedup the matching.

The with_renamed_vars method creates a copy with renamed variables. This is used to make sure that parts of patterns that are the same except for the variable names can be matched together by the many-to-one matcher. I plan on solving this differently and getting rid of the method in the future.

from matchpy.

arihantparsoya avatar arihantparsoya commented on June 13, 2024

I have implemented class NonzeroQ():

class NonzeroQ(Constraint):
    def __init__(self, expr, vars):
        self.expr = expr
        self.vars = frozenset(v.name for v in vars)

    def __call__(self, substitution):
        subst = {}
        for i in self.vars:
            subst[i] = substitution[i]
        if substitute(self.expr, subst).symbols == {'+'}:
            return False
        return True

    @property
    def variables(self):
        return self.vars

    def with_renamed_vars(self, renaming):
        copy = NonzeroQ()
        copy.vars = frozenset(renaming.get(v, v) for v in self.vars)
        return copy

    def __eq__(self, other):
        return isinstance(other, NonzeroQ) and other.vars == self.vars and other.expr == self.expr

    def __hash__(self):
        return hash(self.vars)

pattern = Pattern(Int(Pow(x_, m_), x), FreeQ((m,), x), NonzeroQ(Add(m_, one), (m,)))

Can you suggest a better implementation of __call__ function?

from matchpy.

wheerd avatar wheerd commented on June 13, 2024

First of all, you don't need to copy the substitution before you substitute.
Secondly, assuming you have implemented some kind of simplications that turn something like Add(1, -1) into 0, you can use all(substitution[v] != 0 for v in self.vars).
Or you use CustomConstraint(lambda m: Add(m, one) != 0).
I don't know how NonzeroQ in Rubi is implemented though.

from matchpy.

arihantparsoya avatar arihantparsoya commented on June 13, 2024

In NonzeroQ , I am trying to substitute substitution variable in sef.expr.
This works fine:

    def __call__(self, substitution):
        if substitute(self.expr, substitution).symbols == ():
            return False
        return True

from matchpy.

arihantparsoya avatar arihantparsoya commented on June 13, 2024

Mathematica implementation on NonzeroQ():

(* ZeroQ[u1,u2,...] returns True if u1, u2, ... are all 0; else it returns False. *)
ZeroQ[u_] := Quiet[PossibleZeroQ[u]]

ZeroQ[u__] := Catch[Scan[Function[If[ZeroQ[#],Null,Throw[False]]],{u}];True]

NonzeroQ[u_] := Not[ZeroQ[u]]

from matchpy.

wheerd avatar wheerd commented on June 13, 2024

Looks like you need your own implementation of PossibleZeroQ to properly check if something is zero. Or you need a advanced simplification algorithm so that you have Add(Div(Mul(a, -1), a), 1) == 0.

from matchpy.

arihantparsoya avatar arihantparsoya commented on June 13, 2024

For Rubi, @Upabjojr already adviced to have sympy to matchpy(and vice versa) converters. Perhaps we can convert matchpy expression into sympy and then do mathematical operations.

from matchpy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.