Reputation: 1
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
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:
X
is a member of Xs
, the result is Xs
.[X|Xs]
Try something like this:
try_prepend( X , Xs , Xs ) :- member(X,Xs), !.
try_prepend( X , Xs , [X|Xs] ) .
Upvotes: 0
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