I am trying to filter a list of lists in prolog such that [[a,b,c],[],[d],[e,f]] gives [[a,b,c],[e,f]], my filter function should omit the elements of length less than two, The code I tried is as follows,
omitunwanted([],_) :- [].
omitunwanted([List|L1],[H|T]) :-
( length(List,0)->
omitunwanted(L1,[H|T])
; length(List,1)->
omitunwanted(L1,[H|T])
; append(List,[],H),
omitunwanted(L1,T)
).
It returns the output [[a,b,c],[e,f]|_G1622] for the input [[a,b,c],[],[d],[e,f]] . I cant figure out what I am doing wrong
Here is a pure version that even works for those cases where @mat's version produces a clean instantiation_error
.
length_less_than_two_truth([], true).
length_less_than_two_truth([_], true).
length_less_than_two_truth([_,_|_], false).
texclude( _, [], []).
texclude(CT, [E|Es], Fs0) :-
call(CT,E,Truth),
( Truth = true,
Fs0 = Fs
; Truth = false,
Fs0 = [E|Fs]
),
texclude(CT, Es, Fs).
?- texclude(length_less_than_two_truth, [X,[a,b,c]],Ls).
X = [],
Ls = ["abc"] ;
X = [_A],
Ls = ["abc"] ;
X = [_A, _B|_C],
Ls = [[_A,_B|_C], "abc"] ;
false.
using library(double_quotes)
Consider using exclude/3
. Example:
length_less_than_two(Ls) :-
must_be(list, Ls),
length(Ls, L),
L < 2.
Sample query and its result:
?- exclude(length_less_than_two, [[a,b,c],[],[d],[e,f]], Ls).
Ls = [[a, b, c], [e, f]]
In this answer we take the same line as this previous answer .
As a starting point consider the following query:
?- texclude(length_less_than_two_truth, [[a,b,c],[],[d],[e,f]], Xs). Xs = [[a,b,c],[e,f]] % succeeds, but leaves choicepoint behind ; false.
Can we make above query succeed deterministically while preserving logical-purity ? Yes!
We adapt texclude/3
and length_less_than_two_t/2
to utilize first argument indexing:
texclude(P_2,Es,Fs) :-
list_texclude_(Es,Fs,P_2).
list_texclude_([],[],_).
list_texclude_([E|Es],Fs0,P_2) :-
if_(call(P_2,E), Fs0 = Fs, Fs0 = [E|Fs]),
list_texclude_(Es,Fs,P_2).
length_less_than_two_t([],true).
length_less_than_two_t([_|Es],T) :-
=(Es,[],T).
Note that the second clause of length_less_than_two_t/2
is based on (=)/3
.
With this implementation, let's re-run the query the OP gave in the question:
?- texclude(length_less_than_two_t, [[a,b,c],[],[d],[e,f]], Xs). Xs = [[a,b,c],[e,f]]. % succeeds deterministically
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.