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.
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.
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.
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