views:

46

answers:

2

Ok! last Prolog question for a loong time!!

I'm trying to pick a response that is picked at random but all I can seem to do is pick the first one out of my tables of responses (see code)

I'm sure it's done with Prologs "findall" and "random" but how?

pick_response(Sent, R) :-
    response(Sent, R), !.
pick_response(_,R) :-
    punt(R),!.

Thanks

+3  A: 

One way to do it with findall/3 and random/3 is:

% Responses for sentence 'sentence'
response(sentence, first).
response(sentence, second).
response(sentence, third).

% 1. Generate a list of all responses
% 2. Generate a random integer
% 3. Pick the response with the index of the integer from the list
random_response(Sentence, RandomResponse) :-
    findall(Response, response(Sentence, Response), List),
    length(List, Len),
    random(0, Len, RandomNumber),
    nth0(RandomNumber, List, RandomResponse).

Usage:

?- random_response(sentence, RandomResponse).
RandomResponse = third.

?- random_response(sentence, RandomResponse).
RandomResponse = first.

?- random_response(sentence, RandomResponse).
RandomResponse = second.

?- random_response(sentence, RandomResponse).
RandomResponse = second.

?- random_response(sentence, RandomResponse).
RandomResponse = second.

?- random_response(sentence, RandomResponse).
RandomResponse = third.
Kaarel
A: 

Your problem is the cuts. I am assuming that response/2 will generate all possible responses on backtracking and that you want to be able to step through them on back tracking and pick out the one you want. If there is no suitable response then punt/1 will generate a response.

If this is so then the cut in the first clause will stop backtracking in pick_response and response so you will only ever see the first solution. If punt/1 generates solutions o backtracking then you will have the same problem there as well, but if it only ever generates one solution then the second is unnecessary.

This moves the actual picking of a response outside of pick_response which then really becomes generate_response.

Is this what you intended?

rvirding