Slightly bending the rules, to use DCG:
elem_repeat_dcg(Lst, LstRepeated) :-
phrase(elem_repeated, Lst, LstRepeated).
% If starts with rep, then just use the remainder
elem_repeated --> [rep], !.
elem_repeated --> elem_repeating.
% Perform the repeat
elem_repeating, [Prev, Prev] --> [Prev], [rep], !.
% Loop through list
elem_repeating, [NotRep] --> [NotRep], !, elem_repeating.
% Accept end of list, if rep is not found
elem_repeating --> [].
Result in swi-prolog:
?- elem_repeat_dcg([1,2,rep,3,4,5], LstRepeated).
LstRepeated = [1,2,2,3,4,5].
?- elem_repeat_dcg([rep,3,4,5], LstRepeated).
LstRepeated = [3,4,5].
?- elem_repeat_dcg([1,2,3,4,5], LstRepeated).
LstRepeated = [1,2,3,4,5].
?- time(elem_repeat_dcg([1,2,rep,3,4,5,6,7,8,9], LstRepeated)).
% 4 inferences, 0.000 CPU in 0.000 seconds (82% CPU, 104430 Lips)
LstRepeated = [1,2,2,3,4,5,6,7,8,9].
And here is a variation of the DCG portion, with the same results:
% If starts with rep, then just use the remainder
elem_repeated --> [rep], !.
elem_repeated, [First] --> [First], elem_repeating(First).
% Perform the repeat
elem_repeating(E), [E] --> [rep], !.
% Loop through list
elem_repeating(_), [E] --> [E], !, elem_repeating(E).
% Accept end of list, if rep is not found
elem_repeating(_) --> [].
Whoever set the question is probably wanting the likes of:
% This is what NOT to do
elem_repeat(Lst, LstRepeated) :-
append([Before, [rep], After], Lst),
append([_, [RepElem]], Before),
append([Before, [RepElem], After], LstRepeated).
... which ruins performance by not just using the tail of the list, after the replacement has been performed - which is what difference lists can do... and DCGs use difference lists behind the scenes.