Search code examples
prologmeta-predicate

Use of Prolog =.. predicate


I'm working on an exercise whereby I'm trying to use the =.. predicate to write a procedure that removes all elements in List for which PredName(X) fails and returns the remaining list as Result:

filter(List, PredName, Result)

In this case with PredName being defined as:

test(N) :- atom(N).

For example:

?- filter([a,b,-6,7,A,-1,0,B], test, L).
L = [a,b,-6,7,-1,0],

I've got the following, but I'm not sure why I keep getting false as a result when testing with the example above:

test(N):-
    atomic(N).
filter([], _, []).
filter2([H|T], PredName, [H|S]):-
    Goal =.. [PredName, H],Goal,filter(T, PredName, S),!.
filter([H|T], PredName, S) :-
    filter2(T, PredName, S).

I got the above code from here.


Solution

  • Did you try to compile the code?

    I get:

    Clauses of filter/3 are not together in the source-file
    

    Why? Because you need to decide how to call the predicate: Either filter2/3 or filter/3. You are currently using both names.

    Also, when you have code like:

    Goal =.. [PredName, H],
    Goal
    

    Simply use call/2 instead. For example, the above can be equivalently written as:

    call(PredName, H)
    

    In summary:

    • decide on the predicate name and stick to it
    • don't use (=..)/2 for such cases
    • do use call/2.