Skip to content

Conversation

JSS95
Copy link
Collaborator

@JSS95 JSS95 commented Apr 1, 2021

References to other Issues or PRs

Fixes #21228

Brief description of what is fixed or changed

  1. New assumption keys for both old and new assumption system

.is_positive_infinite and .is_negative_infinite attributes are introduced. Q.positive_infinite and Q.negative_infinite keys are introduced.

  1. New assumptions facts reorganization

Facts are now built in more systematical way, based on primitive predicates such as negative_infinite, negative, zero, positive, positive_infinite, and imagniary.

  1. Bug fix

Incorrect result of Q.infinite is fixed.

Before this change:

>>> print(ask(Q.infinite(oo)))
None

After this change:

>>> ask(Q.infinite(oo))
True

Also, incorrect results of Q.hermitian and Q.antihermitian are fixed. See #21228.

Other comments

Release Notes

  • assumptions

    • Q.positive_infinite and Q.negative_infinite predicates are introduced.
    • Q.infinite now correctly evaluates to True for oo, -oo, and zoo.
    • Q.hermitian(x) now does not imply that x is antihermitian, and vice versa. 0 is now both hermitian and antihermitian.
  • core

    • .is_positive_infinite and .is_negative_infinite attributes are introduced.

@JSS95 JSS95 changed the title Introduce assumption predicates Introduce more assumption predicates Apr 1, 2021
@sympy-bot
Copy link

sympy-bot commented Apr 1, 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:

  • assumptions

    • Q.positive_infinite and Q.negative_infinite predicates are introduced. (#21220 by @JSS95)

    • Q.infinite now correctly evaluates to True for oo, -oo, and zoo. (#21220 by @JSS95)

    • Q.hermitian(x) now does not imply that x is antihermitian, and vice versa. 0 is now both hermitian and antihermitian. (#21220 by @JSS95)

  • core

    • .is_positive_infinite and .is_negative_infinite attributes are introduced. (#21220 by @JSS95)

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

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. -->
Fixes #21228

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

1. New assumption keys for both old and new assumption system

`.is_positive_infinite` and `.is_negative_infinite` attributes are introduced. `Q.positive_infinite` and `Q.negative_infinite` keys are introduced.

2. New assumptions facts reorganization

Facts are now built in more systematical way, based on primitive predicates such as `negative_infinite`, `negative`, `zero`, `positive`, `positive_infinite`, and `imagniary`.

3. Bug fix

Incorrect result of `Q.infinite` is fixed. 

Before this change:
```python
>>> print(ask(Q.infinite(oo)))
None
```

After this change:
```python
>>> ask(Q.infinite(oo))
True
```

Also, incorrect results of `Q.hermitian` and `Q.antihermitian` are fixed. See #21228.

#### 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 -->
* assumptions
  * `Q.positive_infinite` and `Q.negative_infinite` predicates are introduced.
  * `Q.infinite` now correctly evaluates to `True` for `oo`, `-oo`, and `zoo`.
  * `Q.hermitian(x)` now does not imply that `x` is antihermitian, and vice versa. `0` is now both hermitian and antihermitian.

* core
  * `.is_positive_infinite` and `.is_negative_infinite` attributes are introduced.
<!-- END RELEASE NOTES -->

@sympy sympy deleted a comment from sympy-bot Apr 1, 2021
@oscarbenjamin
Copy link
Collaborator

There was some discussion about this before. The difficulty is that the complexity of satask can grow exponentially in the number of predicates.

We need a way to translate these predicates into a smaller number before sending them into satask. I think that the way to do it is to have 5 primitive predicates:

neginf, neg, zero, pos, posinf

Then we have e.g.:

extended_real = neginf | neg | zero | pos | posinf
nonnegative = zero | positive
...

@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 1, 2021

Sounds good. There are a lot of discrepancies and awful errors in old and new assumption system. I think the facts in these two systems need thorough reorganization. At least, every key in old assumption system needs its counterpart in new assumption system.

JSS95 added 2 commits April 2, 2021 21:50
Implement is_positive_infinite and is_negative_infinite
Implement Q.positive_infinite and Q.negative_infinite
Fix Q.infinite
Make assumptions.sathandlers._old_assump_replacer() simpler
Fix Q.hermitian and Q.antihermitian
@JSS95 JSS95 changed the title Introduce more assumption predicates Modify and fix new assumption facts Apr 2, 2021
@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 2, 2021

@oscarbenjamin
negative_infinite and positive_infinite assumptions are introduced. Known facts are reorganized based on the primitive predicates. Plus, Q.infinite, Q.hermitian and Q.antihermitian predicates are fixed.

I sucessfully implemented Q.extended_positive and other extended real predicates, but that made the diff too large so I will open another PR for that after this one.

@oscarbenjamin
Copy link
Collaborator

Known facts are reorganized based on the primitive predicates.

Does this mean that they all get passed into satask though?

Make predicates decomposed into primitive predicates

This makes the facts used by satask simpler. Since the factbase of satask
is simplified, some queries cannot be directly computed by satask() and
thus tests for these queries are removed. However, these queries are
still computed by ask().
@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 3, 2021

@oscarbenjamin
Not anymore. Q.real and other predicates are converted to the composition of primitive predicates when queried, and do not exist in sat factbase. About 30 lines are removed from ask_generated.py.

@oscarbenjamin
Copy link
Collaborator

Changing anything in the core assumptions can impact performance. Can you run benchmarks comparing performance of this PR with master?

JSS95 added 2 commits April 4, 2021 00:48
Add more facts to core/assumptions
Make pure predicates converted to primitives by to_NNF when possible

This makes tests from test_satask re-enabled.
@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 3, 2021

@oscarbenjamin

This change slowed down the performance. I did benchmarking by running tests for test_query.py and test_satask several times over.

In master, test_query took about 10 sec and test_satask took about 0.85 sec.
In this branch, test_query took about 16 sec and test_satask took about 1.2 sec.

I think speed can be improved by letting Q.real and other excluded predicates into get_known_facts_dict(). This dict allows simple inference without using satask (please see the comment lines in ask()) so having more items here may show better result.

@oscarbenjamin
Copy link
Collaborator

Have you tried running the benchmarks:
https://github.com/sympy/sympy_benchmarks

@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 5, 2021

Here is the highlighted benchmark compare result between master and this branch.


All benchmarks:

       before           after         ratio
     [85ff38c1]       [f89e0d20]
     <master>         <oldassump_newassump>

+        74.8±1ms       83.5±0.5ms     1.12  logic.LogicSuite.time_dpll2
+     3.49±0.02μs      3.84±0.03μs     1.10  matrices.TimeMatrixExpression.time_Mul
-      69.3±0.2ms       59.0±0.5ms     0.85  polygon.PolygonEnclosesPoint.time_bench01

It seems that the difference is due to:

  1. Introduction of Q.positive_infinite and Q.negative_infinite.
  2. Converting the predicates to primitive predicates.

I will do another benchmark to exclude the influence of 1.

@JSS95 JSS95 closed this Apr 5, 2021
@JSS95 JSS95 deleted the oldassump_newassump branch April 5, 2021 05:19
@oscarbenjamin
Copy link
Collaborator

I was asking more about the impact that changing the core assumptions would have from adding is_positive/negative_infinite. Both assumptions systems have the potential to slow down from the addition of new predicates.

@JSS95
Copy link
Collaborator Author

JSS95 commented Apr 5, 2021

I will split down the PR and run benchmarks separately. This one is attempting to make too many things to benchmark each change efficiently.

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.

Incorrect assumption for is_hermitian
3 participants