
Better with green cuts then. And test cases are always mandatory.
deleted(X, [H|L1], [H|L2]) :- X\=H, !, deleted(X,L1,L2).
deleted(X, [X|L1], L2) :- !, deleted(X,L1,L2).
deleted(_, [], []).
:- begin_tests(deleted).
test(empty) :- deleted(1,[],[]).
test(not_exists) :- deleted(1,[2,3,4,5,6],R), R = [2,3,4,5,6].
test(exists_once) :- deleted(1,[2,1,4,5,6],R), R = [2,4,5,6].
test(exists_once_end) :- deleted(1,[2,3,4,5,1],R), R = [2,3,4,5].
test(exists_multi) :- deleted(1,[2,1,4,1,6],R), R = [2,4,6].
test(exists_only) :- deleted(1,[1,1,1,1,1],R), R = [].
:- end_tests(deleted).
rt :- run_tests(deleted).
?- rt.
% PL-Unit: deleted ...... done
% All 6 tests passed
true.
Sadly this doesn't run in "reverse"
?- deleted(1,X,[2,3]).
blows the stack sky-high ... instead returning an infinite series of possible X
, like [1,2,3]
etc.
What does one need to change to make it behave? (I think it's not directly evident and may demand another approach).
Addendum: Green cuts removed
Yep, it still works (although having cuts is essential to keep the machine from getting bogged down in keeping avenues open that we know (as programmers who prove theorems in our head as we write code) are useless:
deleted(X, [H|L1], [H|L2]) :- X\=H, deleted(X,L1,L2).
deleted(X, [X|L1], L2) :- deleted(X,L1,L2).
deleted(_, [], []).
:- begin_tests(deleted_nondeterministic).
test(empty, all(RR = [[]])) :- deleted(1,[],RR).
test(not_exists, all(RR = [[2,3,4,5,6]])) :- deleted(1,[2,3,4,5,6],RR).
test(exists_once, all(RR = [[2,4,5,6]])) :- deleted(1,[2,1,4,5,6],RR).
test(exists_once_end, all(RR = [[2,3,4,5]])) :- deleted(1,[2,3,4,5,1],RR).
test(exists_multi, all(RR = [[2,4,6]])) :- deleted(1,[2,1,4,1,6],RR).
test(exists_only, all(RR = [[]])) :- deleted(1,[1,1,1,1,1],RR).
:- end_tests(deleted_nondeterministic).
rt :- run_tests(deleted_nondeterministic).