1

I want to make prolog returning me all possible sublists of given list so I wrote:

subSet(L,S):- append(_,L2,L),append(S,_,L2).

In that way I get result like:

Out = [] ;
Out = [a] ;
Out = [a, b] ;
Out = [a, b, c] ;
Out = [] ;
Out = [b] ;
Out = [b, c] ;
Out = [] ;
Out = [c] ;
Out = [] ;

What I have to do to get rid of repeating empty list?

Adrian Modliszewski
  • 1,114
  • 2
  • 18
  • 31

2 Answers2

2

Note that there is a sublist predicate among the standard list predicates already (which only lists [] once). I'll assume that you're implementing this as an exercise...


An empty list is always a sublist, so this can be specified explicitly. You can then avoid the empty list by using [S|T] instead of S:

subSet(_, []).
subSet(L, [S|T]) :- append(_, L2,L), append([S|T], _, L2).

Example run:

| ?- subSet([a, b, c], Out).

Out = [] ? ;

Out = [a] ? ;

Out = [a,b] ? ;

Out = [a,b,c] ? ;

Out = [b] ? ;

Out = [b,c] ? ;

Out = [c] ? ;
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • Ok, Nice that works, but what kind of diffrence makes if i do [S|T] instead of S ?? I mean I know that stands for Not Empty List here, But is there any other way to do that? – Adrian Modliszewski Mar 13 '12 at 17:13
  • The difference is that `S` can bind to `[]`, while `[S|T]` can not. You could of course easily define a `nonempty([_|_]).` predicate and do `nonempty(S)` I think using `[S|T]` directly is the standard way of doing it. – aioobe Mar 13 '12 at 17:53
  • Updated the answer with a link to a `sublist` predicate btw. – aioobe Mar 13 '12 at 17:55
2

Rule out that you are describing the empty list at all and add it manually once.

list_subseq(_,[]).
list_subseq(L, S) :- S = [_|_], ....

Nevertheless, expressing subsequences is often better done with DCGs. See the first definition in this response. Using append/3 might work, but leads to code that is quite difficult to read.

Community
  • 1
  • 1
false
  • 10,264
  • 13
  • 101
  • 209