Kastin_Hashmat
Kastin_Hashmat

Reputation: 1

my function in prolog doesn't give the expected output

So basically , I wanted to do an append function in prolog that adds in the first elemnt of the list as a head if it doesn't exist inside of it otherwise it will return the same list

i wrote this :

list_append(F,[],[F]).
list_append(F,[X|XS],[F,X|XS]):- not(member(F,[X|XS])),list_append(F,XS,YS).

but it retuns False instead of a list when the element exists ... any help ? output :

?- list_append(2,[2,2,3],X).
false.

Upvotes: 0

Views: 41

Answers (2)

Nicholas Carey
Nicholas Carey

Reputation: 74287

You're not handling the case where the item is already in the list. Also the check for the empty list is probably not needed. So there are just two cases:

  • if X is a member of Xs, the result is Xs.
  • otherwise... the result is [X|Xs]

Try something like this:

try_prepend( X , Xs ,    Xs  ) :- member(X,Xs), !.
try_prepend( X , Xs , [X|Xs] ) .

Upvotes: 0

brebs
brebs

Reputation: 4418

Impure method:

append_if_not_member(Elem, LstBeforeAppend, LstAfterAppend) :-
    % Usually perform checks here, e.g. could check that Elem is not a list
    append_if_not_member_(Elem, LstBeforeAppend, LstAfterAppend).

append_if_not_member_(Elem, LstBeforeAppend, LstAfterAppend) :-
    memberchk(Elem, LstBeforeAppend),
    % Found answer - don't try alternative
    !,
    % Assign here, so logic is sound if e.g. LstAfterAppend has a value
    LstAfterAppend = LstBeforeAppend.

% Add Elem to list
append_if_not_member_(Elem, LstBeforeAppend, [Elem|LstBeforeAppend]).

Pure method, which loops through the list only once, for performance:

append_if_not_member(Elem, Lst, LstAfterAppend) :-
    append_if_not_member_loop_(Lst, Lst, Elem, LstAfterAppend).


% Reached end of list, so Elem is not already present
append_if_not_member_loop_([], Lst, Elem, [Elem|Lst]).

% If head matches Elem, then can stop looking further
append_if_not_member_loop_([Elem|_], Lst, Elem, Lst).

append_if_not_member_loop_([H|T], Lst, Elem, LstAfterAppend) :-
    % Head is different to Elem
    dif(H, Elem),
    % Continue checking the list
    append_if_not_member_loop_(T, Lst, Elem, LstAfterAppend).

Upvotes: 1

Related Questions