I need to write a rule, what finds only numbers in list M and outputs only the numbers in list O.
Query looks like: find(M, O)
I can't figure it out on my own and hope someone can help me.
I need to write a rule, what finds only numbers in list M and outputs only the numbers in list O.
Query looks like: find(M, O)
I can't figure it out on my own and hope someone can help me.
Here is a "classical Prolog" way to do it:
find([], []).
find([H|T], [H|NewT]) :-
number(H),
find(T, NewT).
find([H|T], NewT) :-
\+ number(H),
find(T, NewT).
There are 3 clauses.
1st says that for an empty list the result is an empty list.
2nd says: if the first element (head, H
) of the input list is a number, keep it in the output, and the rest of the output (new tail, NewT
) is find
applied to the rest of the input list (tail, T
).
3rd clause is structurally similar to the second, but says not to keep head if it's not a number.
Here's another approach, using findall/3
which is available in most Prolog implementations. But for a beginner, Sergey's answer is arguably best for beginners to learn how basic recursive list processing works.
find(M, O) :-
findall(X, (member(X, M), number(X)), O).
If you're using swi-prolog, you'll be happy to use the include/3
predicate as so:
find_numbers(M,O) :-
include(number,M,O).