1

Say I have a a database with the letters A-G:

elem(a). elem(b). ... elem(g).

and I want to make a predicate that gives me all possible combinations of those 7 letters in a list, you could do:

findall(List, permutation([a,b,c,d,e,f,g],List), X).

and X would be a list with all combo's (you don't even need the database for this).

But, what I want however is to make a list of only 5 elements long, with the 7 available letters. How would I be able to do that?

Rose
  • 109
  • 4

1 Answers1

0

It's permutation which does the work here, not findall. So the answer is "yes, you just need to write a predicate combination such that calling combination([a,b,c,d,e,f,g], List, 5) will produce all 5-element sublists of [a,b,c,d,e,f,g] as separate answers". Some Prolog systems include predicates which would make it quite easy, I don't think SWI-Prolog does.

E.g. http://eclipseclp.org/doc/bips/lib/lists/subset-2.html would allow you to write

combination(SubList, List, Length) :- 
  subset(SubList, List),
  length(SubList, Length).

and then

?- findall(List, combination([a,b,c,d,e,f,g],List,5), X).

Note that SWI-Prolog also provides subset/2, but in a different mode which makes it unusable for this problem (it has +SubSet, meaning it can't produce SubSet, but needs it to be known). (Plus, the above implementation is quite inefficient.) So I'll leave writing combination as an exercise in recursion and arithmetic :)

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Just to be sure, would this be a good `combination`?: `sbset([],[]). sbset([H|L],[H|SL]) :- sbset(L,SL). sbset(L, [_|SL]) :- sbset(L,SL). combination(SubList, List, Length) :- sbset(SubList, List), length(SubList, Length).` – Rose Oct 02 '17 at 17:21
  • I wouldn't consider it good because it's generating all sublists and checking length of each (when used with known `List` and `Length` and variable `SubList`). It works, but you can do better. – Alexey Romanov Oct 02 '17 at 17:27
  • Nevermind, it doesn't even work. I get out of local stack all the time... – Rose Oct 02 '17 at 17:58