Skip to content

Conversation

JSS95
Copy link
Collaborator

@JSS95 JSS95 commented Mar 30, 2021

References to other Issues or PRs

Brief description of what is fixed or changed

Fix handler for Q.extended_real
Allow is_neq to take assumptions.
Apply the change from #21235 to Q.eq and Q.neq.

In the future, facts will modified so that assuming binary predicates such as x != y or x > y can return the appropriate result.

Other comments

Release Notes

  • core
    • is_neq now takes assumptions
    • Eq and Ne can be refined by predicates such as Q.positive, Q.zero, etc.

JSS95 added 2 commits March 30, 2021 15:13
Add getter parameters to is_lt and other functions

Assumptions for these functions do not work yet
@sympy-bot
Copy link

sympy-bot commented Mar 30, 2021

Hi, I am the SymPy bot (v161). I'm here to help you write a release notes entry. Please read the guide on how to write release notes.

Your release notes are in good order.

Here is what the release notes will look like:

  • core
    • is_neq now takes assumptions (#21203 by @JSS95)

    • Eq and Ne can be refined by predicates such as Q.positive, Q.zero, etc. (#21203 by @JSS95)

This will be added to https://github.com/sympy/sympy/wiki/Release-Notes-for-1.9.

Click here to see the pull request description that was parsed.
<!-- Your title above should be a short description of what
was changed. Do not include the issue number in the title. -->

#### References to other Issues or PRs
<!-- If this pull request fixes an issue, write "Fixes #NNNN" in that exact
format, e.g. "Fixes #1234" (see
https://tinyurl.com/auto-closing for more information). Also, please
write a comment on that issue linking back to this pull request once it is
open. -->


#### Brief description of what is fixed or changed

Fix handler for `Q.extended_real`
Allow `is_neq` to take assumptions.
Apply the change from #21235 to `Q.eq` and `Q.neq`.

In the future, facts will modified so that assuming binary predicates such as `x != y` or `x > y` can return the appropriate result.

#### Other comments

#### Release Notes

<!-- Write the release notes for this release below between the BEGIN and END
statements. The basic format is a bulleted list with the name of the subpackage
and the release note for this PR. For example:

* solvers
  * Added a new solver for logarithmic equations.

* functions
  * Fixed a bug with log of integers.

or if no release note(s) should be included use:

NO ENTRY

See https://github.com/sympy/sympy/wiki/Writing-Release-Notes for more
information on how to write release notes. The bot will check your release
notes automatically to see if they are formatted correctly. -->

<!-- BEGIN RELEASE NOTES -->
* core
  * `is_neq` now takes assumptions
  * `Eq` and `Ne` can be refined by predicates such as `Q.positive`, `Q.zero`, etc.
<!-- END RELEASE NOTES -->

Update

The release notes on the wiki have been updated.

@JSS95
Copy link
Collaborator Author

JSS95 commented Mar 30, 2021

@oscarbenjamin

Inspired by your comment in #21055, I came up with the design to implement refine logic without having duplicate code. The idea is to pass different getter functions as parameter. In obj.__new__, getter function which uses old assumption system (e.g. x.is_zero) is passed for faster evaluation. In ask() and refine(), getter function which uses new assumption system is passed in order to take local assumptions into account.

I tried with that approach here to let ask(Q.eq(x,0), Q.zero(x)) return True. Please review this PR. If this looks OK, I think other refine logic can be changed in this way to remove the duplication.

@oscarbenjamin
Copy link
Collaborator

I have thought about something like this. We do need to be clear about whether it does slow some things down though e.g.:

In [12]: x = S.Zero

In [13]: getter = lambda obj, key: getattr(obj, 'is_%s' % key)

In [14]: %timeit x.is_zero
86.7 ns ± 0.865 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [15]: %timeit getter(x, 'zero')
785 ns ± 60.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Also the approach here requires putting getter everywhere in the logic which makes the code messy.

Another approach I thought about was to make a wrapper class that wraps an object with assumptions and then presents the interface of the old assumptions e.g.:

def func(obj, assumptions=None):
    objq = AssumptionsWrapper(obj, assumptions):
    if objq.is_positive:
        ...

The idea here is that if assumptions are not given then AssumptionsWrapper can just return the object unmodified so that is_positive is exactly as fast as it would be otherwise. If assumptions are given then an AssumptionsWrapper instance is returned with methods like:

def _eval_is_positive(self):
    return ask(Q.positive(self.obj), self.assumptions)

@JSS95
Copy link
Collaborator Author

JSS95 commented Mar 30, 2021

That is an interesting idea. I will open a discussion i mailing list.

@JSS95
Copy link
Collaborator Author

JSS95 commented Mar 31, 2021

@oscarbenjamin
Please check the discussion I opened : https://groups.google.com/u/3/g/sympy/c/0NStDt45U-s

@JSS95 JSS95 changed the title Allow assumptions to be taken for equality query feat: allow assumptions to be taken for equality query Apr 13, 2021
@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 13, 2021

This PR is an improvement of what was introduced in #21235. I will wait for a few days for review and merge this.

@JSS95 JSS95 merged commit bff9444 into sympy:master Apr 15, 2021
@JSS95 JSS95 deleted the rel_assumps branch April 15, 2021 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants