I want to use the predicate subtract
to remove all list items that are not lists.
Sample query showing the expected answer:
?- subtract([1,2,[3],[],4,5,[8]], ..., Xs).
Xs = [[3],[],[8]].
How can I do that? Thanks!
I want to use the predicate subtract
to remove all list items that are not lists.
Sample query showing the expected answer:
?- subtract([1,2,[3],[],4,5,[8]], ..., Xs).
Xs = [[3],[],[8]].
How can I do that? Thanks!
Use meta-predicate tfilter/3
together with the reified test predicate nil_or_cons_t/2
: it's monotonic!
nil_or_cons_t(Xs,T) :-
( nonvar(Xs)
-> ( nil_or_cons(Xs)
-> T = true
; T = false
)
; T = true , nil_or_cons(Xs)
; T = false, freeze(Xs,\+nil_or_cons(Xs))
).
nil_or_cons([]).
nil_or_cons([_|_]).
Sample query:
?- tfilter(nil_or_cons_t, [1,2,[3],[],4,5,[8]], Lss).
Lss = [[3],[],[8]].
This answer is incorrect (too general = "test predicate too simplistic").
Please see my follow up answer for details.
My old answer was clearly incorrect.
Why? It classified terms like [_|non_list]
as lists... Bad!
How come? The non-recursive nil_or_cons_t/2
can be too shallow.
What to do? Use the recursive reified predicate list_t/2
instead!