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
Feature request (^)/2 for rationals in SWI-Prolog. #185
Comments
@jburse Seems that you already have part of the code ready. Can you contribute this enhancement yourself as per a pull request? |
Importantly, SWI-Prolog/packages-clpqr#1 may also be related to this issue! |
Pushed a4bfaf5, which add support for rationals to ^ and **. |
I am reopening this issue because it is currently not fully fixed. I agree with Jan that R^K should yield a rational number if R is a rational number and K is an integer, also if K is negative. For example, in SICStus Prolog, we have: | ?- { X = 3/2, Y = X^(-1) }. X = 3/2, Y = 2/3 ? ; no |
I hope that floats as we know them today go away rather sooner than later! For comparison, here is the query with SWI: ?- { X = 3/2, Y = X^(-1) }. false. This means that SWI behaves different from SICStus for the important domain of CLP(Q). I have at least one program where this difference is critical, so I have filed this as SWI-Prolog/packages-clpqr#2. |
With SICStus, I get: | ?- X is 5^(-2). ! Type error in argument 2 of (is)/2 ! expected a float, but found 5 ! goal: _187 is 5^ -2 This means that doing something correct, namely, yielding: ?- X is 5^(-2). X = 1 rdiv 25. would not conflict with something that SICStus computes. As an aside, it would be slightly odd to now appeal to the ISO standard on this particular issue (of all things!), where it is pretty clear what should be computed, and yet completely ignore the standard on much more fundamental issues. Please also take into account that the standard says nothing about rational numbers at all. With SWI-Prolog, we currently get: ?- X is 5^(-2). X = 0.04. That's quite correct, right? Yes, quite: ?- X is 5^(-2), format("~32f", [X]). 0.04000000000000000083266726846887 Behold the pioneering technology from 70 years ago! |
I get, with SICStus: | ?- { X = 5^(-2) }. X = 1/25 ? ; no and with SWI: ?- { X = 5^(-2) }. false. Consider now a case with SWI that does not intersect in any way with the core standard: ?- X is (1 rdiv 5)^(-1). X = 5.0. Expectation: |
Yes, that would be great, thank you! |
I think it tells me that we should
Right now, negative exponentials are supported as in
This is compatible with e.g.
But, this is broken because
You can actually force it, as in
The second issue is clp(Q), which in part relies on SWi-Prolog's rational support. This reliance seems For now I'll leave it as is, but this should be resolved at some point. |
We can only fix all these if we turn rationals into a proper atomic data type with accompanying syntax. That is probably not very hard, but requires some restructuring in the basic data representation to accommodate an additional basic type. The second simple idea is that all basic mathematical functions that have integer or rational arguments and an integer or rational answer returns this exact answer. So, notably One issue is that I do not want more dependency on the LGPL GMP library ... |
As Richard has argued many times, (ISO) Prolog arithmetic is flawed. Floats are fine for functions that inherently are about real numbers (in the math sense). Otherwise they are a poor match for any high level languages and particularly so for a logic based language. Switching to an approximation should be really the last resort, in particular so because unification is based on strict equivalence. If you want scruffy arithmetic, just cast one or more of the operands to a float using ISO should have demanded unbounded integer and rational number support from the start. Well, possibly this was asking too much back then, but it should have corrected this error long ago. |
Automatic casting never turns a float into a rational, as floats are never converted into integers right now. Only explicit casting does so, where you control the rounding. All this is not rocket science. |
You use the opportunity that Prolog is a dynamically typed language. This |
I think the feature was incorrectly implemented. I get for example
It would be better if we had two pairs ideally like (/)/2 and rdiv/2, with |
I am not sure, maybe (**)/2 and (^)/2 could play this role. We could reserve (**)/2, so that this
And (^)/2 would always try rational numbers:
|
This issue has been mentioned on SWI-Prolog. There might be relevant details there: https://swi-prolog.discourse.group/t/future-of-support-for-rational-numbers/1779/14 |
I found a further argument to give different roles to (**)/2 and (^)/2. For example ECLiPSe Prolog gives this result, since it does not
On the other hand I get:
So from the data type of the argument of (^)/2 it cannot result like 1r100000. Except we would give this role to (**)/2 and |
I like very much that SWI-Prolog provides rationals via the operator rdiv/2. We can do things such as the following:
When using rationals we can use all the other operators (+)/2, (-)/2 and (*)/2 in is/2 unchanged. This lead me to the expectation that (^)/2 can also be used unchanged:
As can be seen this is not the case. My expectation was:
I know that the operator (^)/2 was only recently required the ISO Corr.2. Would it be possibly to extend this operator to also work for exactly rationals?
The text was updated successfully, but these errors were encountered: