I have a task to remove all elements which have the same value as the index from the list. I have this code but it does not work.
remove(_, [], []).
remove(position, [H | T1], [H | T2]) :-
H =:= position,
next_position = position + 1,
remove(next_position, T1, T2).
remove(position, [H | T1], T2) :-
H =\= position,
next_position = position + 1,
remove(next_position, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
The main mistakes were in syntax. Also conditions has to be swiped. Now it changed and program works.
SOLUTION:
remove(_, [], []).
remove(Position, [H | T1], [H | T2]) :-
H =\= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
remove(Position, [H | T1], T2) :-
H =:= Position,
NextPosition is Position + 1,
remove(NextPosition, T1, T2).
:-remove(1,[1, 2, 2, 3, 4, 5, 6, 7, 8],Res),
write(Res).
In addition to the modifications already pointed out by Gusbro, you also need to invert the conditions used to include/exclude elements from the input list:
remove(_, [], []).
remove(Position, [H|T1], [H|T2]) :-
H =\= Position, % include element if it is different from its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
remove(Position, [H|T1], T2) :-
H =:= Position, % exclude element if it is equal to its index
Next_position is Position + 1,
remove(Next_position, T1, T2).
Examples:
% index 1 2 3 4
?- remove(1, [1,2,2,4], Res).
Res = [2] ;
false.
% index 0 1 2 3
?- remove(0, [1,2,2,4], Res).
Res = [1, 2, 4] ;
false.
% index 1 2 3 4 5 6 7 8 9
?- remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8] ;
false.
To avoid spurious choice point:
->
to avoid the need to evaluate a deterministic condition and also its negation.Thus, an improved version of this predicate is as follows:
improved_remove(Start, List, NewList) :-
remove_loop(List, Start, NewList).
remove_loop([], _, []).
remove_loop([H|T1], Position, L) :-
( H =\= Position
-> L = [H|T2]
; L = T2 ),
Next_position is Position + 1,
remove_loop(T1, Next_position, T2).
Examples:
?- improved_remove(1, [1,2,2,4], Res).
Res = [2].
?- improved_remove(0, [1,2,2,4], Res).
Res = [1, 2, 4].
?- improved_remove(1, [1,2,2,3,4,5,6,7,8], Res).
Res = [2, 3, 4, 5, 6, 7, 8].