Aleg
Aleg

Reputation: 23

Prolog: Element not present in list

I need find element position in list (as the built-in predicate nth, but here the first element has index 1). But, I need also have an output like 'Element is not present' if not. I try a solution not so elegant, assigning a big value to counter.
But it's not the correct solution!!!
I'm afraid it's very easy but I can't find another solution !!!

Can anyone helps me?

search(L):-
      write('searching for: '),read(E),find(L,E,Pos),
      out(L,E,Pos),!.

out(E,Pos):-
          Pos < 10000,
          write('element '),write(E),write(' is in position n. '),write(Pos),!.

out(E,Pos):-
          Pos > 10000,
          write('Element '),write(E),write(' is not present!'),!.

find([X|Xs],E,Pos):-
                 X \= E,
                 find(Xs,E,Pos1),
                 Pos is Pos1 + 1.
find([],_,10000).
find([X],X,1).
find([X|_],X,Pos):-
                Pos is 1,!.

Upvotes: 2

Views: 2944

Answers (4)

Raceimaztion
Raceimaztion

Reputation: 9624

Remember that you're not limited to returning numbers from your find/3 predicate.

You can instead return any other atom, like so:

find([], _, notfound).
find([H|_], H, 1) :- !
find([_|T], H, Pos) :-
        find(T, H, Found),
        (
            integer(Found), !,
            Pos is Found+1
        );(
            Pos = notfound
        ).

However, this style is a little more awkward to write with, though your return value is much more descriptive.

Edited to fix an error.

Upvotes: 1

尾崎隆大
尾崎隆大

Reputation: 158


% NewLine was missing.

out(E,0) :-
        writef('element %t is not present. \n',[E]),!.
out(E,-1) :-
        writef('element %t is no longer present. \n',[E]),!.
out(E,Pos) :-
        writef('element %t is in position %t. \n',[E,Pos]),!.

Upvotes: 0

尾崎隆大
尾崎隆大

Reputation: 158



search(L):-
        write('searching for: '),
        read(E),
        find(L,E,Pos),
        fail.
search(_).

find(L,E,0) :-
        \+(append(_,[E|_],L)),!.
find(L,E,Pos) :-
        append(L0,[E|_],L),
        length(L0,Len0),
        Pos is Len + 1.
find(_,_,-1).

out(E,0) :-
        writef('element %t is not present. ',[E]),!.
out(E,-1) :-
        writef('element %t is no longer present. ',[E]),!.
out(E,Pos) :-
        writef('element %t is in position %t. ',[E,Pos]),!.

Upvotes: 0

Mark Bolusmjak
Mark Bolusmjak

Reputation: 24399

What you want is more something like this:

search(L):-
    write('searching for: '),read(E),
    finde(E).

finde(E) :-
    find(L,E,Pos), % find succeeds 
    out(L,E,Pos),!. % and prints, cut ensures we don't try next clause

finde(E) :- write('Element '),write(E),write(' is not present!'),!. % called if not found

That way you don't need a strange find clause that always succeeds with a large number. Just let it fail.

Upvotes: 2

Related Questions