Print all the even elements of a list

I am trying to print all the even elements of a list, For that I am using the following code:

par(X) :- X mod 2 =:= 0.
print_lista([]).
print_lista([P | R]) :- 
    P == par(P),
    write(P),
    print_lista(R).
print_lista([P | R]) :- 
    P \= par(P),
    print_lista(R).

The above code does not work. What am I doing wrong?

The following code works fine. But I can not figure out why the above code does not work.

par(X) :- X mod 2 =:= 0.
print_lista([]).
print_lista([P | R]) :- 
    par(P), !,
    write(P),
    print_lista(R).
print_lista([P | R]) :- 
    print_lista(R).

Another question is regarding the fact that the last code while compiling it shows the following warning, in the line, print_lista([P | R]) :- print_lista(R).:
Warning: …:
Singleton variables: [P]

Thanks,

See the documentation for the (==)/2 operator. If P has been bound to, lets say, the number two, you are saying:

2 == par(2)

which means succeed if the term 2 is equivalent to the term par(2); of course this will never succeed.

You have a similar problem with P \= par(P). You are saying succeed if I cannot unify the term P with the term par(P).

In none of the above cases the predicate par/1 is being called.

As you figured out, what you want is par(P) for the first test and \+ par(P) for the second.
See the documentation for \+.

You get this warning because the variable P is not used in the body of the third clause of print-lista/1. To get rid of the warning indicate that you won’t use this variable by naming it _P (with an underscore)

Thank you very much. Learning Prolog has been challenging.

Yes, you need to change the paradigm, the way of thinking. Try to forget about imperative languages for a time. Some things you may find useful:

  1. do not think of variables as something that you assign a value
    1.1. Instead think of them as a placeholder that dissapears from existence as soon as a value is bound to it (like in mathematical equations).
  2. do not think of predicates as functions, but rather as a name that establishes a relationship between the arguments
  3. When prolog tries to find a clause head to match, it does not call anything, it simply tries to unify the terms of the query (or goal) and the clause head.

I would recommend reading the tutorials at The Power of Prolog from the beginning as they may clarify some basic concepts.

2 Likes

Thank you so much for the advice and recommendations.