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