0

In evaluating math expressions with SWI-Prolog I need to evaluate -1 raised to an exponential. When the exponential is an integer the result is as expected but when the exponential is a non-integer the result is undefined.

Is it possible to evaluate a -1 to a non-integer with SWI-Prolog?

e.g. (-1)^0.5

A preferred answer should not take more then several lines to accomplish. The use of a package is acceptable. The use of calling into another language would be acceptable but less preferred.

Supplement

With SWI-Prolog when using either ^/2 or **/2 with a base of -1 and a fraction as the exponent results in undefined

?- V is **(-1.0,-0.5).
ERROR: Arithmetic: evaluation error: `undefined'
ERROR: In:
ERROR:    [8] _3688 is -1.0** -0.5
ERROR:    [7] <user>

?- V is **(-1.0,0.5).
ERROR: Arithmetic: evaluation error: `undefined'
ERROR: In:
ERROR:    [8] _43410 is -1.0**0.5
ERROR:    [7] <user>

?- V is ^(-1.0,-0.5).
ERROR: Arithmetic: evaluation error: `undefined'
ERROR: In:
ERROR:    [8] _6100 is -1.0^ -0.5
ERROR:    [7] <user>

?- V is ^(-1.0,0.5).
ERROR: Arithmetic: evaluation error: `undefined'
ERROR: In:
ERROR:    [8] _7294 is -1.0^0.5
ERROR:    [7] <user>

However when using either ^/2 or **/2 with a base of -1 and an integer as the exponent results in a valid value.

?- V is ^(-1.0,-3.0).
V = -1.0.

?- V is ^(-1.0,-2.0).
V = 1.0.

?- V is ^(-1.0,-1.0).
V = -1.0.

?- V is ^(-1.0,0.0).
V = 1.0.

?- V is ^(-1.0,1.0).
V = -1.0.

?- V is ^(-1.0,2.0).
V = 1.0.

?- V is ^(-1.0,3.0).
V = -1.0.

?- V is **(-1.0,-3.0).
V = -1.0.

?- V is **(-1.0,-2.0).
V = 1.0.

?- V is **(-1.0,-1.0).
V = -1.0.

?- V is **(-1.0,0.0).
V = 1.0.

?- V is **(-1.0,1.0).
V = -1.0.

?- V is **(-1.0,2.0).
V = 1.0.

?- V is **(-1.0,3.0).
V = -1.0.

I am aware that SWI-Prolog math is based on GNU multiple precision arithmetic library (GMP), which as noted on Wikipedia does not support complex numbers.

I am also aware that a plot of -1^X is a continuous function of both real and imaginary parts. Currently I am only interested in the real part.

false
  • 10,264
  • 13
  • 101
  • 209
Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • 1
    Undefined is the correct answer, for -1^0.5 has no solution in R but C. And C is not supported. – false May 17 '17 at 11:39
  • @false I don't think SWI-Prolog should return `ERROR: Arithmetic: evaluation error: 'undefined'` but instead return `complex not supported`. When I first saw the error I thought I was dividing by zero somewhere in my code. Only after researching for an hour did I find the root cause being that complex numbers are not supported. – Guy Coder May 17 '17 at 12:21
  • 1
    @GuyCoder "undefined" is a legitimate error for this case. The operation is truly "undefined" within the domain supported by the operations. I do agree that an error message such as "complex not support" could be more helpful, but one could comb through all of the real time messages and probably improve on some of them if one wished. So is the question here how one could easily handle imaginary results by representing them as some kind of term? Or you just want a way to get the real part? It's not clear to me exactly what you're after. You've explored a couple of branches in your question... – lurker May 17 '17 at 16:17
  • @GuyCoder: This particular question seems to be quite naturally covered by the LIA-model. However, if you are interested in further investigations in particular w.r.t. the reliability of results, I recommend you look at [unums](http://www.complang.tuwien.ac.at/ulrich/unums/). – false May 17 '17 at 16:29
  • @lurker `So is the question here how one could easily handle imaginary results by representing them as some kind of term? Or you just want a way to get the real part?` For now and for this question I need just the real part, but in the future (not part of this question) I will need the imaginary part. More specifically but not mentioned in the question I need to know if a math expression results in an `odd` or `even` value for use with the rule `-1^x`. When `x` is odd the term can be rewritten as `-1` and when `x` is even the term can be rewritten as `1`. – Guy Coder May 17 '17 at 20:17
  • When you refer to `x` in the expression `(-1)^x` as being odd or even, then `x` is clearly an integer in that context. But you are interested in `x` being fractional (or real), right? So the even/odd discussion doesn't come into play in that case. The values of `(-1)^x` for any real value of `x` are all somewhere on the unit circle in the real-imaginary plane. – lurker May 17 '17 at 21:02
  • Of interest: [SWI Prolog Error and Warning Messages](https://www.cse.unsw.edu.au/~billw/SWIprolog-error-mgs.html) - Gives ikely cause(s) – Guy Coder Jul 29 '17 at 11:19

1 Answers1

1

Noticing that the plot of (-1)^x is a periodic function similar to cos function with a frequency shift, start with

cos((10 * x) / pi)

To adjust the frequency of the function, plot the function with a translation on the X-axis by 10 then adjust the cos function to match, e.g.

cos((9.9 * x) / pi)

Then keep translating further out and adjusting. After a few iterations of adjusting this function is close to what is needed even for x of 10,000.

cos((9.8696 * x) / pi)

?- V is cos((9.8696*(10000.0))/pi).
V = 0.9999018741279994.

Supplement

To make the adjustments easier to do, the functions were plotted using Wolfram Alpha. Note that due to differences between SWI-Prolog and Wolfram Alpha, the adjustment factors are slightly different. For Wolfram Alpha the factor is 9.86955 while with SWI-Prolog it is 9.8696

Guy Coder
  • 24,501
  • 8
  • 71
  • 136