ayla
ayla

Reputation: 3546

How to find the Nth element of a list, and print said element out?

so i have a homework question that asks me to find the third element of a list, as well as the last element of a list and print them out (2 separate programs).

I Thought my Code would work to find the third element, by keeping track of a index, but i recieve a error when i try to run the code:

findthird([], Result).

findthird(List, Result) :- secondFunc(List, 0, Result).

secondFunc([Head|Tail], Count, Result) :- 
    Count < 3, Count is Count+1, secondFunc(Tail, Count, Result).

secondFunc([Head|Tail], Count, [Head|Result]).

Have any ideas for this?

The output i receieve now Is :

| ?- findthird([2,3,4], Result).

Result = [2|_]

yes

I am still having a tough time wrapping my head around Prolog, i just cant seem to understand it.

Any help is appreciated as always,

Thank.

Updated with new attempt code***

Updated ** This is the code that solved my problem:

findthird([], Result).
findthird(List, Result) :- secondFunc(List, 0, Result).

secondFunc([], Count, []).
secondFunc([Head|Tail], Count, Result) :- 
     Count1 is Count+1, Count1 < 3, secondFunc(Tail, Count1, Result).
secondFunc([Head|Tail], Count, Head).

Input:

| ?- findthird([3,4,5], Result).

Output:

Result = 5 ? 

yes

Input:

| ?- findthird([3,4,5,6,7], Result).

Output:

Result = 5 ? 

yes

Upvotes: 0

Views: 3056

Answers (1)

m09
m09

Reputation: 7503

First of all, you have to understand that in Prolog, you don't manipulate return values of function. The reason behind this is that you do not manipulate functions, but predicates. So length(List) never evaluates to a number, but to true or false, as any other predicate. When you write findelement(List, length(List), len... the findelement predicate won't be called with something like [a, b, c] and 3, it will be called with something like [a, b, c] and length([a, b, c]). So already your program cannot work.

That put aside, your program is still very wrong. The basic way a recursion works in prolog or in functional languages (as well as when you use structural induction in maths) is as follows :

  • a clause for initialization

  • a clause for heredity

In your program, you don't have an initialization clause. Meaning that when recursion hits [], no clause can handle it, and the thing fails. The rest is false too, but I think it's especially important to get the recursion principles right first.

To illustrate that without spoiling the problem for you (it's homework after all), I'll take an example : say you wanna test if a sheepfold is safe. The sheepfold is safe if there's no wolf in it. If we represent the sheepfold by a list and the wolf by the atom wolf, we can write the predicate like that :

Initialization : if the sheepfold is empty, it's safe, there's no wolf in it.

safe_sheepfold([]).

Heredity : if the sheepfold is safe with n-1 members, it's safe with n members if the added member is not a wolf :

safe_sheepfold([Animal|Sheepfold]) :-
    Animal =\= wolf,
    safe_sheepfold(Sheepfold).

And that's it. To see how prolog handles the request, compile this and issue a trace. command before running the predicate, as pointed out in your last question, it will help you to understand how things work.

To let you think about that with a more concrete example, here is a classic predicate, factorial (it uses arithmetic too) :

Here is our initialization clause :

factorial(0, 1).

Here is our heredity clause :

factorial(N, F) :-
    N > 0,
    NextN is N - 1,
    factorial(NextN, NextF),
    F is NextF * N.

To keep this simple I didn't make this predicate tail recursive nor used cuts, you'll learn about those things later on!

I hope my rambling will be of some help.

edit post update :

It's almost that ! Now just a few more hints : the result you want is not a list, it's just an element, so try to modify the last clause to just return the element, not a list with the element. And the initialization clause is actually your last clause here (the thing that checks if you're above 3), so you don't need the one with [] ! You're almost there :)

Upvotes: 4

Related Questions