Dee
Dee

Reputation: 163

Creating a table of square roots of a given list in Prolog

I am a newbie to Prolog and trying to develop a simple code to get the following output.

?-sqrt_table(7, 4, Result).
Result = [[4, 2.0],[7, 2.64575],[6, 2.44949],[5, 2.23607]] ;
false.

However the output I'm getting is,

?- sqrt_table(4,7,X).
X = [[5, 2.23606797749979], [[6, 2.449489742783178], [[7, 2.6457513110645907], []]]].

I think the issue is in the nested list created by get_sqrt/2. If I can get it flattened down to tuples I think it might work. Your ideas and help are much appreciated.

%main predicate
sqrt_table(N,M,Result):-
        full_list(N,M,Out),
        get_sqrt(Out,[Rest,Result]).

%Creates a range of outputs  within the given upper and lower limits
range(Low,Low,High).
range(Out,Low,High):-
        NewLow is Low+1,NewLow=<High,
        range(Out,NewLow,High).

%Creates a list of the outputs created by range/3
full_list(Low,High,Out):-
        findall(X,range(X,Low,High),Out).


%Calculates the square root of each item in the list and gives a list consisted
%of sublists such that [Input,Squareroot of the input]
get_sqrt([],[]).
get_sqrt([H|T],[[H,Sqrt],SqrtRest]):-
        SqrtOf_H is sqrt(H),
        get_sqrt(T,SqrtRest),
        Sqrt = SqrtOf_H.

Thanks in advance.

Upvotes: 1

Views: 568

Answers (1)

mat
mat

Reputation: 40768

In the head of the second clause ofget_sqrt/2, simply write [[H,Sqrt]|SqrtRest], i.e., use (|)/2 instead of (,)/2.

In fact, it would be even better to use the more readable and more idiomatic [H-Sqrt|HSqrts], i.e., use (-)/2 do denote pairs.

And in second fact, a better way altogether is to simply state the relation for one element at a time, using for example:

integer_isqrt(I, I-Sq) :- Sq is sqrt(I).

and then to use the maplist/3 to relate lists of such elements to one another:

?- maplist(integer_isqrt, [0,1,2,3,4], Ls).
Ls = [0-0.0, 1-1.0, 2-1.4142135623730951, 3-1.7320508075688772, 4-2.0].

P.S.: Using flatten/2 always indicates a problem with your data structures, you should avoid flatten/2 entirely. If you need to remove one level of nesting, use append/2. But in this case, neither is needed.

Upvotes: 2

Related Questions