简体   繁体   中英

Filterlists prolog

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 ? 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM