The above implementation of predicates remov/2 and member/2 excessively "use" the meta-logical constructs (!)/0 and not/1, which ruins almost all declarative aspects—forcing us to focus on a vast number of painstaking details. For details, see prolog-cut and logical-purity.
Let's re-implement remov/2 based on iwhen/2 and sort/2, like so:
remov(Xs,Ys) :-
iwhen(ground(Xs), sort(Xs,Ys)).
How does this work?
The builtin predicate sort/2 sorts lists of Prolog terms according to the standard order, eliminating duplicate items in the process.
Note that sort/2 may not preserve logical-purity if the input list contains variables.
iwhen/2 ensures sufficient instantiation when using sort/2.
Sample queries:
?- remov([1,2,3,1,2],Xs).
Xs = [1,2,3].
?- remov(Xs,Ys).
ERROR: Arguments are not sufficiently instantiated