Here is the code that removes the values with unit test.
remove(X,L1,L2) :-
exclude(remove(X),L1,L2).
remove(X,Element) :-
X = Element.
:- begin_tests(remove).
remove_test(success,0,[1,2,3],[1,2,3]).
remove_test(success,1,[1,2,3],[2,3]).
remove_test(success,1,[1,1,2],[2]).
remove_test(success,1,[1,2,1],[2]).
remove_test(success,1,[2,1,1],[2]).
test(remove_success,[forall(remove_test(success,X,L1,Expected_result))]) :-
remove(X,L1,L2),
assertion( L2 == Expected_result ).
:- end_tests(remove).
The code above can be refactored/simplified a lot more but I left it as is so that it is easier to understand.
EDIT
Now for the reverse, or at least one way of doing it. The description was not specific enough.
Also this uses a different predicate name; remember that one predicate can call another so I don’t see this as an issue.
add_element(X,L1,L2) :-
append([X],L1,L0),
permutation(L0,L2).
:- begin_tests(add_element).
add_element_test(success,0,[1,2],[[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]]).
test(add_element_success,[forall(add_element_test(success,X,L1,Expected_result)),set(L2 == Expected_result )]) :-
add_element(X,L1,L2).
:- end_tests(add_element).