-
Notifications
You must be signed in to change notification settings - Fork 33
Fix for +-rule-down #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Argument presented in the source code was ;; note: We can't assert that X and Y are integers when Z is an integer since ;; Z may be an integer when X and Y are Gaussian integers. But we can ;; make such an assertion if either X or Y is real. If the Screamer ;; type system could distinguish Gaussian integers from other complex ;; numbers we could make such an assertion whenever either X or Y was ;; not a Gaussian integer. The argument above must surely be incorrect. If Z is an integer, and Y is a real say 2.5 then X will surely not be an integer. The argument *does* work if eithe r X or Y are integers. So changed things so that Z being an integer and X OR Y being an INTEGER means that X AND Y are both integers. (Note the assertion is only for X, but this is correct given that the assertion for Y happens in another call to this rule.
This is just the text of the original issue that I opened (sorry about the duplication, haven't used github for this sort of thing before) function -v erroneously restricts arguments to integers in certain casesI'm a bit too busy to delve into this issue more deeply at the moment (maybe I'll poke at the screamer sources later, haven't really had a look at them before), but (-v (a-real-betweenv 1.1 1.2)) emits an error. (This form distils the issue I had in much more complicated code) Mysteriously, the real variable created by a-real-between-v has been restricted to be an integer, causing the exception later on. Further investigation reveals (-v 0 (a-real-betweenv 1.1 1.2)) has the same issue, but the following works correctly (-v 0.0 (a-real-betweenv 1.1 1.2)) This can be used as a workaround for anyone similarly affected. In the case of +v, there is seemingly no such problem. (+v (a-real-betweenv 1.1 1.2)) all work correctly. Perhaps this means a fix may be relatively simple? (Note: I'm using the quicklisp screamer-20111105-git distro in case this matters) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test case that demonstrates the problem would appreciated. (In tests.lisp)
I'm experiencing some problems with restrictions to integers/non-integers with functions /v and *v. Here are some examples:
Another problem is when integer variables have the lower bound 0:
I believe there is a problem with /-rule, which does not include a condition when the lower bound or the upper bound is equal zero. There is a similar problem with ratios (the multiplication of the non-integer variables X and Y restricts Z to be a non-integer):
The lower-bound and upper-bound of Z are the same:
Maybe it would be necessary to revise all the rules (+-rule-up, +-rule-down, /-rule, *-rule-up, *-rule-down) and also the functions +v2, -v2, *v2 and /v2, but it seems to be not an easy task. I'm also wondering if would be possible to include a distinction between integers and ratios (rational) and floats variables. Any ideas? |
Addressed here Separately, for posterity, the above logic is wrong in general, even in the modified case this PR proposes. Even when Z and Y are both integers, multiplication of ratios can reduce to integers, so X might be some fraction whose denominator is a factor of Y (e.g. 1 = 2 * 1/2, as in the above-quoted comment). The "right answer" here is to track Gaussian integers, as the original comment states; ratios naturally convert to such, so the primary blocker seems to be converting integer floats into integers. Would have to investigate to find all the fiddly bits that need to be fixed to allow this. Alternatively, swapneils#9 would fix this automatically, along with some other issues in Screamer's current variable-type system. |
Argument presented in the source code was
;; note: We can't assert that X and Y are integers when Z is an integer since
;; Z may be an integer when X and Y are Gaussian integers. But we can
;; make such an assertion if either X or Y is real. If the Screamer
;; type system could distinguish Gaussian integers from other complex
;; numbers we could make such an assertion whenever either X or Y was
;; not a Gaussian integer.
The argument above must surely be incorrect. If Z is an integer, and Y is a real
say 2.5 then X will surely not be an integer. The argument does work if eithe
r X or Y are integers. So changed things so that Z being an integer and X OR Y being an INTEGER means that X AND Y are both integers. (Note the assertion is only for X, but this is correct given that the assertion for Y happens in another call to this rule.