Question

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

Was it helpful?

Solution 2

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.

OTHER TIPS

This probably will not work as a solution for your homework, but here is one of many ways to do it using constraint logic programming in ECLiPSe CLP Prolog:

:- lib(gfd).
square(S) :-
    sqr(_) #= S.

It means: S is a square if it's an integer and some other value (we don't care what value, so we use "throw-out" variable _) squared equals S.

All modern Prolog systems supports constraint logic programming, and the code will be similar to above.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top