I have currently started with PROLOG and I want to write a predicate which checks if a given object is in this list or not. If the object is in the list the predicate should return the index of the element. If the element is not found it should return 0.
It should work like this: find(3,[1,4,5,3,2,3],N). -> yes. N / 4
find(2,[1,3,4,5,6,7],N). -> yes. N / 0
But I have problems with counting up the index N and maybe someone here can help. I've seen many different ways on how to traverse a list but I found so many different ways and I wasn't able to understand how they work. I would be really happy if someone can provide a solution and explain how it works and why.
This is what I wrote so far:
find(X, [X|TAIL], N) :- N is 1, write(N).
find(X, [], N) :- N is 0, write(N).
find(X, [_|TAIL], N) :- find(X, TAIL, N + 1).
It is working for the basecases:
find(a, [a, b, c, d, e, f, g], N) -> yes. N / 1.
find(j, [a, b, c, d, e, f, g], N) -> yes. N / 0.
But when it is starting with recursion It is not working anymore and I don't understand what's going wrong.
For the recursion case it gives me this: find(b, [a, b, c, d, e, f, g], N) -> no.
I am thankful for every answer and every comment!
Requirements:
- If an element is not in the list it should output
yes. N = 0.
Examples:?- find(a, [], N) -> yes. N = 0.
and?- find(a, [b,c,d], N) -> yes. N = 0.
- If an element is in the list it should output the index of that element (start counting with 1). Examples:
?- find(a, [a, b, c], N) -> yes. N = 1
and?- find(a, [b,c,a,d], N) -> yes. N = 3.
- If there is the element more than one time it should only output the index of the first appearance of the element. Example:
?- find(a, [a,b,c,a], N) -> yes. N = 1.
- It should always only give on answer.
- If possible no libraries should be used.
- The query
?- find(a, [a, b,c], 0)
and?- find(a, [b, a, c], 0)
and every other query where a is in the list should be answered withno
. - The query
?- find(a, [a, b, c, a], 4)
should be answered withno
because the a with index 4 is not the first apperance of a.
find(X, [], 0). find(X,[X|_], 1). find(X, [_|Xs], N) :- find(X, Xs, Rest), N is 1 + Rest.
This code is now working for elements that are in the list, but if I want to find an object that is not in the list, N is becoming 6 and not 0. How can I resolve this issue?find(a, [a,b,c,a,b,c], Index)
? First result1
, on backtracking4
, on backtracking again0
for not found is what my code does, but I don't know if that makes good sense or not.find(a, [a,b,c,a,b,c], Index)
Prolog should give the following answer:Yes. Index = 1
. So it should return the index of the first appearance of the given atom. If the atom is not appearing in the list it should give 0. Thank you for your comment!nth/3
ornth1/3
, but without this0
-case.nth1/3
already exists - swi-prolog.org/pldoc/man?predicate=nth1/3