I have to write a rule square(S) in Prolog that tests if a number S is the square of an integer returning false (ex. square(3)) or true (ex. square(4)). I used already a rule that generates all integers between 0 and M:
isInteger(X,M) :- between(0,M,X).
Using this generator I have to write the rule square(S). How can I do it? Thanks
To solve it your way, you just need to check if S is the product of your generated integer multiplied by itself. So you could do it like this:
isInteger(X,M) :- between(0,M,X).
square(N) :-
isInteger(X, N),
N is X * X.
I came up with another possible solution, using the sqrt
arithmetical function from SWI-Prolog but I think there must be a more elegant one.
I initially expected it would be as simple as X is sqrt(4), integer(X).
However, this doesn't work (at least not in SWI-Prolog 7.1.4), because X
is unified with the float 2.0
and integer(2.0)
is false (since integer is checking the data type, not the value of the number). But this works:
square_of_integer(N) :-
Int is rationalize(sqrt(N)),
integer(Int).
It depends on first giving a representation of N as a rational (which, in SWI-Prolog, 'are represented by the compound term rdiv(N,M)'). 2 is rationalize(2.0)
, i.e., rationalize evaluates to an integer for round numbers.