2

I am trying to get a list with all the possible combinations of words that total a number of syllables. For example:

w(cat, noun, 1).
w(boy, noun, 1).
w(pet, noun, 1).
w(eats, verb, 1).

w(woman, noun, 2).
w(nature, noun, 2).
w(apple, noun, 2).
w(watches, verb, 2).

w(family, noun, 3).

has_5_syllables(L) :-
    w(X, _, N0),
    w(Y, _, N1),
    plus(N0, N1, 5),
    append([X], [Y], L).

In this case has_5_syllables returns a combinations of two words:

?- has_5_syllables(X).
X = [woman, family] ;
X = [nature, family] ;
X = [apple, family] ;
...

So the question is, how can I extend the predicate so it returns also combinations of more than 2 words, for example [cat, boy, family], [cat, boy, pet, apple]?

Ideally I would also like to make it generic, so you can pass N as the sum of syllables to the predicate: has_n_syllables(L, N).

skamsie
  • 2,614
  • 5
  • 36
  • 48

1 Answers1

0

We can reuse subset_set/2 from this answer, since the question is similar, then findall/3 can build a list of pairs, from where we can easily get the required solution:

has_n_syllables(L, N) :-
    findall(W-S, w(W,_,S), WSs),
    subset_set(Ps, WSs),
    pairs_keys_values(Ps, L, Vs),
    sumlist(Vs, N).

subset_set/2 doesn't really require its arguments being sets, just lists... the name should be sublist_list, really...

Community
  • 1
  • 1
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • This awesome! Honestly I was expecting a super verbose solution, but even the ```subset_set``` implementation is pretty lite. However I am very new to Prolog and everything seems super ambiguous. Would you mind adding a couple of comments to understand what's going on there? Thanks! – skamsie Mar 19 '16 at 19:04
  • 1
    It's not ambiguous, but an exhaustive search of the solution space. subset_set it's the key to get all possible known combination of words, and since findall also collected the syllabe count, it suffice to separate the words and sum the counters. You can try `?- forall(has_n_syllables(L,N),writeln(L/N).` to visualize the entire solution space. There is a solution for each group of words, printed on backtracking induced by forall. – CapelliC Mar 19 '16 at 20:57