Prolog - DCG - random sentence

2019-08-10 03:43发布

问题:

I'm new to Prolog, and I'm trying to write a small program that will give a random sentence from a DCG.

My previous way of thinking was to use findall/3 to make a list of all possible sentences, and then using random_member/2.

It worked for a little while, until the grammar got bigger and I began to get stack errors because of recursion...

I then thought of another way : make a set of all possible terms at a given moment, applying random_member to get the next term, recursively call this same function, until I get the empty list...

But how can I get a set of all possible answers to an incomplete predicate ? And how can I get it in a set ?

For information, my DCG looks like this:

s --> pronoun(X), verb(X), location.
pronoun(1) --> [i].
pronoun(2) --> [you].
verb(1) --> [am].
verb(2) --> [are].
location --> [here].
location --> [there].

My idea of the solution (where List is the list of the already concatenated terms ) :

createRandomSentence(List) :- 
    setof(H, s([List|[H|_]], []), Set),
    random_member(Pick, Set),
    append(List, [Pick], List2)
    <recursive call (haven't figured out this one either yet)>

...

Thanks in advance ! :)

回答1:

Seems a though task to me. I would tackle it with another strategy, namely inserting selectors in DCG where you want discriminate alternatives. Something like

s --> pronoun(X), verb(X), location.
pronoun(1) --> {this}, [i].
pronoun(2) --> [you].
verb(1) --> [am].
verb(2) --> [are].
location --> {this},[here].
location --> [there].

% here choice just between 2
this :- random(0,2,1).

which yields

?- phrase(s,L).
L = [i, am, there] ;
L = [you, are, there].

?- phrase(s,L).
L = [you, are, there].