Search code examples
prolog

Prolog List Squaring, Modifying element in List


I am trying to write a short Prolog program which takes a list of numbers and returns a list where all numbers have been squared.

Ie: [2,4,5] => [4,16,25]

My code so far:

list_of_squares([X], L) :-
    L is X^2.
list_of_squares([X|XS], [X^2|M]) :-
    list_of_squares(XS, M).

For some reason though Prolog doesn't like me squaring X while adding it to a list... Any thoughts on how I could do this?


Solution

  • You're not that far off, but you make two small mistakes:

    Firstly, you mix element X with list L. Your first clause should be:

    list_of_squares([X], [Y]):-
      Y is X ^ 2.
    

    Secondly, you cannot perform an arithmetic function in list notation. Your second clauses should be as follows:

    list_of_squares([X|Xs], [Y|Ys]):-
      Y is X ^ 2,
      list_of_squares(Xs, Ys).
    

    Thirdly, there is a more fundamental problem. With the first two fixes, your code works, but the base case, i.e. the first clause, is not that well chosen. (A) the code cannot process the empty list. (B) For a singleton list the code is needlessly nondeterministic, because both clauses apply. This is solved by choosing the base case wisely:

    squares([], []).
    squares([X|Xs], [Y|Ys]):-
      Y is X ^ 2,
      squares(Xs, Ys).