mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-29 08:14:31 +00:00
samples/Mmakefile:
Add the beer program to list of targets.
samples/*.m:
Convert (C->T;E) to (if C then T else E).
Delete trailing whitespace.
Use predmode syntax instead of separate pred and mode
declarations.
samples/interpreter.m:
Fix up one predicate that had some clauses that used
DCGs and others that used state variables.
Don't use the name 'IO' for something that isn't the I/O state.
samples/diff/*.m:
samples/c_interface/c_calls_mercury/mercury_main.m:
samples/c_interface/short_example.m:
Delete trailing whitespace.
665 lines
20 KiB
Mathematica
665 lines
20 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% File: eliza.m.
|
|
% Main author: bromage.
|
|
%
|
|
% This source file is hereby placed in the public domain. -bromage.
|
|
%
|
|
% Eliza, the famous psychotherapist.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module eliza.
|
|
:- interface.
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module bool.
|
|
:- import_module char.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module pair.
|
|
:- import_module string.
|
|
:- import_module require.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Print the opening banner, initialise the response state, run the main
|
|
% loop.
|
|
%
|
|
main(!IO) :-
|
|
io.write_string("\nHi! I'm Eliza. Please tell me your problem.\n", !IO),
|
|
eliza.initial_state(State),
|
|
eliza.main_loop([], State, !IO),
|
|
io.write_string("\nGoodbye.\n", !IO).
|
|
|
|
:- pred eliza.main_loop(list(string)::in, eliza.state::in, io::di, io::uo)
|
|
is det.
|
|
|
|
eliza.main_loop(Prev, StateIn, !IO) :-
|
|
eliza.read_line(MaybeLine, !IO),
|
|
(
|
|
MaybeLine = yes(Line0),
|
|
eliza.parse(Line0, Line1),
|
|
(
|
|
Line1 = [],
|
|
eliza.main_loop(Prev, StateIn, !IO)
|
|
;
|
|
Line1 = [_ | _],
|
|
( if Line1 = Prev then
|
|
eliza.generate_repeat(StateIn, StateOut, !IO)
|
|
else
|
|
eliza.generate_response(Line1, StateIn, StateOut, !IO)
|
|
),
|
|
eliza.main_loop(Line1, StateOut, !IO)
|
|
)
|
|
;
|
|
MaybeLine = no
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Response state processing functions
|
|
|
|
% The response state consists of two parts: a set of
|
|
% (type - messages) pairs and a list of repeat messages.
|
|
% The response messages are used in response to a context,
|
|
% and the repeat messages are used in response to a repeated
|
|
% input line.
|
|
|
|
:- type response_state == assoc_list(message_type, list(message)).
|
|
:- type repeat_state == list(string).
|
|
|
|
:- type eliza.state ---> state(response_state, repeat_state).
|
|
|
|
% Initialise the state by reading in the initial message
|
|
% database.
|
|
|
|
:- pred eliza.initial_state(eliza.state::out) is det.
|
|
|
|
eliza.initial_state(state(ResMsg,RepMsg)) :-
|
|
repeat_messages(RepMsg),
|
|
response_messages(ResMsg).
|
|
|
|
% Get a repeat message, and then cycle the list so that
|
|
% a new one will come up next time.
|
|
|
|
:- pred eliza.get_repeat(string::out, eliza.state::in, eliza.state::out)
|
|
is det.
|
|
|
|
eliza.get_repeat(MsgOut, state(Res, RepIn), state(Res, RepOut)) :-
|
|
(
|
|
RepIn = [Msg | Rest],
|
|
MsgOut = Msg,
|
|
list.append(Rest, [Msg], RepOut)
|
|
;
|
|
RepIn = [],
|
|
error("Error: No repeat messages.\n")
|
|
).
|
|
|
|
% Get a response message, and then cycle the list so that
|
|
% a new one will come up next time.
|
|
|
|
:- pred eliza.get_response(message_type::in, message::out, eliza.state::in,
|
|
eliza.state::out) is det.
|
|
|
|
eliza.get_response(Type, MsgOut, state(ResIn, Rep), state(ResOut, Rep)) :-
|
|
eliza.get_response2(Type, MsgOut, ResIn, ResOut).
|
|
|
|
:- pred eliza.get_response2(message_type::in, message::out,
|
|
response_state::in, response_state::out) is det.
|
|
|
|
eliza.get_response2(_Type, _MsgOut, [], []) :-
|
|
error("Error: Cannot match message type.\n").
|
|
eliza.get_response2(Type, MsgOut,
|
|
[Type2 - Msgs2 | RestIn],
|
|
[Type2 - Msgs3 | RestOut]) :-
|
|
( if Type = Type2 then
|
|
( if Msgs2 = [MsgOut1 | MsgOutRest] then
|
|
MsgOut = MsgOut1,
|
|
RestOut = RestIn,
|
|
list.append(MsgOutRest, [MsgOut], Msgs3)
|
|
else
|
|
error("Error: Empty response list.\n")
|
|
)
|
|
else
|
|
Msgs2 = Msgs3,
|
|
eliza.get_response2(Type, MsgOut, RestIn, RestOut)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Write a prompt, then read a line.
|
|
|
|
:- pred eliza.read_line(maybe(list(char))::out, io::di, io::uo) is det.
|
|
|
|
eliza.read_line(MaybeLine, !IO) :-
|
|
io.write_string("\n> ", !IO),
|
|
io.flush_output(!IO),
|
|
io.input_stream(Stdin, !IO),
|
|
io.read_line(Stdin, Result, !IO),
|
|
io.write_string("\n", !IO),
|
|
(
|
|
Result = ok(Line1),
|
|
MaybeLine = yes(Line1)
|
|
;
|
|
( Result = eof
|
|
; Result = error(_)
|
|
),
|
|
MaybeLine = no
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% These are the characters that we must strip from a
|
|
% line during parsing.
|
|
|
|
:- pred eliza.is_punct(char::in) is semidet.
|
|
|
|
eliza.is_punct('.').
|
|
eliza.is_punct(',').
|
|
eliza.is_punct('!').
|
|
eliza.is_punct('?').
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Parse the input string into words. This is
|
|
% achieved in three phases:
|
|
%
|
|
% - Strip leading whitespace and intermediate
|
|
% punctuation symbols.
|
|
%
|
|
% - Turn the resulting line into a list of words (each
|
|
% word stored as a list of characters).
|
|
%
|
|
% - Turn each word into a string.
|
|
|
|
:- pred eliza.parse(list(char)::in, list(string)::out) is det.
|
|
|
|
eliza.parse -->
|
|
eliza.strip,
|
|
eliza.form_words,
|
|
eliza.words_to_strings.
|
|
|
|
:- pred eliza.strip(list(char)::in, list(char)::out) is det.
|
|
|
|
eliza.strip([], []).
|
|
eliza.strip([X | Xs], Ys) :-
|
|
( if char.is_whitespace(X) then
|
|
eliza.strip(Xs, Ys)
|
|
else
|
|
eliza.strip2([X | Xs], Ys)
|
|
).
|
|
|
|
:- pred eliza.strip2(list(char)::in, list(char)::out) is det.
|
|
|
|
eliza.strip2([], []).
|
|
eliza.strip2([X | Xs], Ys) :-
|
|
( if eliza.is_punct(X) then
|
|
eliza.strip2([' ' | Xs], Ys)
|
|
else
|
|
eliza.strip2(Xs, Ys1),
|
|
( if char.is_whitespace(X), Ys1 = [] then
|
|
Ys = []
|
|
else
|
|
Ys = [X | Ys1]
|
|
)
|
|
).
|
|
|
|
:- pred eliza.form_words(list(char)::in, list(list(char))::out) is det.
|
|
|
|
eliza.form_words([], []).
|
|
eliza.form_words([X | Xs], Ys) :-
|
|
( if char.is_whitespace(X) then
|
|
eliza.form_words(Xs, Ys)
|
|
else
|
|
eliza.form_word(Xs, [X], Word, Rest),
|
|
eliza.form_words(Rest, Words),
|
|
Ys = [Word | Words]
|
|
).
|
|
|
|
:- pred eliza.form_word(list(char)::in, list(char)::in, list(char)::out,
|
|
list(char)::out) is det.
|
|
|
|
eliza.form_word([], Word1, Word2, []) :-
|
|
list.reverse(Word1, Word2).
|
|
eliza.form_word([X | Xs], WordIn, WordOut, Rest) :-
|
|
( if char.is_whitespace(X) then
|
|
list.reverse(WordIn, WordOut), Rest = Xs
|
|
else
|
|
eliza.form_word(Xs, [X | WordIn], WordOut, Rest)
|
|
).
|
|
|
|
:- pred eliza.words_to_strings(list(list(char))::in, list(string)::out) is det.
|
|
|
|
eliza.words_to_strings([], []).
|
|
eliza.words_to_strings([X | Xs], [Y | Ys]) :-
|
|
string.from_char_list(X, Y),
|
|
eliza.words_to_strings(Xs, Ys).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Generate and display a repeat message
|
|
|
|
:- pred eliza.generate_repeat(eliza.state::in, eliza.state::out,
|
|
io::di, io::uo) is det.
|
|
|
|
eliza.generate_repeat(!State, !IO) :-
|
|
eliza.get_repeat(Msg, !State),
|
|
io.write_string(Msg, !IO),
|
|
io.write_string("\n", !IO).
|
|
|
|
% Generate and display a repeat message
|
|
|
|
:- pred eliza.generate_response(list(string)::in,
|
|
eliza.state::in, eliza.state::out, io::di, io::uo) is det.
|
|
|
|
eliza.generate_response(Words, !State, !IO) :-
|
|
|
|
% Find out what sort of message we are dealing with.
|
|
|
|
eliza.find_handle(Words, MsgType, Rest),
|
|
eliza.get_response(MsgType, Maybe - String, !State),
|
|
io.write_string(String, !IO),
|
|
|
|
% If we must parrot back part of the original message,
|
|
% resolve conjugates, write that string and then add
|
|
% a trailing punctuation mark.
|
|
|
|
(
|
|
Maybe = yes(C),
|
|
eliza.perform_conjugate(Rest, Postfix),
|
|
eliza.write_strings(Postfix, !IO),
|
|
io.write_char(C, !IO)
|
|
;
|
|
Maybe = no
|
|
),
|
|
io.write_string("\n", !IO).
|
|
|
|
% Write a list of strings to the output stream with
|
|
% words thrown in between.
|
|
|
|
:- pred eliza.write_strings(list(string)::in, io::di, io::uo) is det.
|
|
|
|
eliza.write_strings([], !IO).
|
|
eliza.write_strings([X | Xs], !IO) :-
|
|
io.write_char(' ', !IO),
|
|
io.write_string(X, !IO),
|
|
eliza.write_strings(Xs, !IO).
|
|
|
|
:- pred eliza.match_prefix(list(string)::in, list(string)::in,
|
|
list(string)::out) is semidet.
|
|
|
|
eliza.match_prefix([], Ys, Ys).
|
|
eliza.match_prefix([X | Xs], [Y | Ys], Zs) :-
|
|
string.to_upper(Y, X),
|
|
eliza.match_prefix(Xs,Ys,Zs).
|
|
|
|
:- pred eliza.find_handle(list(string)::in, message_type::out,
|
|
list(string)::out) is det.
|
|
|
|
eliza.find_handle(In, MsgType, Out) :-
|
|
response_handles(Handles),
|
|
eliza.find_handle2(In, MsgType, Out, Handles).
|
|
|
|
:- pred eliza.find_handle2(list(string)::in, message_type::out,
|
|
list(string)::out, assoc_list(list(string), message_type)::in) is det.
|
|
|
|
eliza.find_handle2(In, no_key_message, In, []).
|
|
eliza.find_handle2(In, Type, Out, [Prefix - Type2 | Handles]) :-
|
|
( if eliza.find_handle3(In, Prefix, Rest) then
|
|
Out = Rest, Type = Type2
|
|
else
|
|
eliza.find_handle2(In, Type, Out, Handles)
|
|
).
|
|
|
|
:- pred eliza.find_handle3(list(string)::in, list(string)::in,
|
|
list(string)::out) is semidet.
|
|
|
|
eliza.find_handle3([X | Xs], Prefix, Rest) :-
|
|
( if eliza.match_prefix(Prefix, [X | Xs], Rest2) then
|
|
Rest = Rest2
|
|
else
|
|
eliza.find_handle3(Xs, Prefix, Rest)
|
|
).
|
|
|
|
:- pred eliza.perform_conjugate(list(string)::in, list(string)::out) is det.
|
|
|
|
eliza.perform_conjugate([], []).
|
|
eliza.perform_conjugate([X | Xs], [Y | Ys]) :-
|
|
( if ( X = "I", Xs = [] ) then
|
|
Y = "me", Ys = []
|
|
else
|
|
eliza.conjugate_map(Map),
|
|
string.to_upper(X, Xupp),
|
|
( if map.search(Map, Xupp, Result) then
|
|
Y = Result
|
|
else
|
|
Y = X
|
|
),
|
|
eliza.perform_conjugate(Xs, Ys)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type message == pair(maybe(char), string).
|
|
|
|
:- type message_type --->
|
|
can_you ; can_i ; you_are ; i_dont ; i_feel ; why_dont ;
|
|
why_cant ; are_you ; i_cant ; i_am ; you ; yes ; no ;
|
|
computer ; i_want ; question ; name ; because ; sorry ; dream ;
|
|
hello ; maybe ; your ; always ; think ; alike ; friend ; no_key_message.
|
|
|
|
:- pred eliza.conjugate_map(map(string, string)::out) is det.
|
|
|
|
eliza.conjugate_map(MapOut) :-
|
|
one_way_conjugates(AL1),
|
|
two_way_conjugates(AL2),
|
|
assoc_list.reverse_members(AL2, AL3),
|
|
list.append(AL1, AL2, AL12),
|
|
list.append(AL12, AL3, AL123),
|
|
prepare_conj(AL123, ALFinal),
|
|
map.from_assoc_list(ALFinal, MapOut).
|
|
|
|
:- pred prepare_conj(assoc_list(string, string)::in,
|
|
assoc_list(string, string)::out) is det.
|
|
|
|
prepare_conj([], []).
|
|
prepare_conj([X - V | Xs], [Y - V | Ys]) :-
|
|
string.to_upper(X,Y),
|
|
prepare_conj(Xs, Ys).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred response_handles(assoc_list(list(string), message_type)::out) is det.
|
|
|
|
response_handles([
|
|
["CAN","YOU"] - can_you,
|
|
["CAN","I"] - can_i,
|
|
["YOU","ARE"] - you_are,
|
|
["YOU'RE"] - you_are,
|
|
["I","DON'T"] - i_dont,
|
|
["I","FEEL"] - i_feel,
|
|
["WHY","DON'T","YOU"] - why_dont,
|
|
["WHY","CAN'T","I"] - why_cant,
|
|
["ARE","YOU"] - are_you,
|
|
["I","CAN'T"] - i_cant,
|
|
["I","AM"] - i_am,
|
|
["I'M"] - i_am,
|
|
["YES"] - yes,
|
|
["NO"] - no,
|
|
["COMPUTER"] - computer,
|
|
["COMPUTERS"] - computer,
|
|
["I","WANT"] - i_want,
|
|
["WHAT"] - question,
|
|
["HOW"] - question,
|
|
["WHO"] - question,
|
|
["WHERE"] - question,
|
|
["WHEN"] - question,
|
|
["WHY"] - question,
|
|
["NAME"] - name,
|
|
["BECAUSE"] - because,
|
|
["CAUSE"] - because,
|
|
["SORRY"] - sorry,
|
|
["DREAM"] - dream,
|
|
["DREAMS"] - dream,
|
|
["HI"] - hello,
|
|
["HELLO"] - hello,
|
|
["MAYBE"] - maybe,
|
|
["YOUR"] - your,
|
|
["ALWAYS"] - always,
|
|
["THINK"] - think,
|
|
["ALIKE"] - alike,
|
|
["FRIEND"] - friend,
|
|
["FRIENDS"] - friend,
|
|
["YOU"] - you
|
|
]).
|
|
|
|
:- pred one_way_conjugates(assoc_list(string, string)::out) is det.
|
|
|
|
one_way_conjugates([
|
|
"me" - "you"
|
|
]).
|
|
|
|
:- pred two_way_conjugates(assoc_list(string, string)::out) is det.
|
|
|
|
two_way_conjugates([
|
|
"are" - "am",
|
|
"were" - "was",
|
|
"you" - "I",
|
|
"your" - "my",
|
|
"I've" - "you've",
|
|
"I'm" - "you're"
|
|
]).
|
|
|
|
:- pred repeat_messages(repeat_state::out) is det.
|
|
|
|
repeat_messages([
|
|
"Why did you repeat yourself?",
|
|
"Do you expect a different answer by repeating yourself?",
|
|
"Come, come, elucidate your thoughts.",
|
|
"Please don't repeat yourself!"
|
|
]).
|
|
|
|
:- pred response_messages(response_state::out) is det.
|
|
|
|
response_messages(
|
|
[
|
|
can_you - [
|
|
yes('?') - "Don't you believe that I can",
|
|
yes('?') - "Perhaps you would like to be able to",
|
|
yes('?') - "You want me to be able to"
|
|
],
|
|
|
|
can_i - [
|
|
yes('?') - "Perhaps you don't want to",
|
|
yes('?') - "Do you want to be able to"
|
|
],
|
|
|
|
you_are - [
|
|
yes('?') - "What makes you think I am",
|
|
yes('?') - "Does it please you to believe I am",
|
|
yes('?') - "Perhaps you would like to be",
|
|
yes('?') - "Do you sometimes wish you were"
|
|
],
|
|
|
|
i_dont - [
|
|
yes('?') - "Don't you really",
|
|
yes('?') - "Why don't you",
|
|
yes('?') - "Do you wish to be able to",
|
|
no - "Does that trouble you?"
|
|
],
|
|
|
|
i_feel - [
|
|
no - "Tell me more about such feelings.",
|
|
yes('?') - "Do you often feel",
|
|
yes('?') - "Do you enjoy feeling"
|
|
],
|
|
|
|
why_dont - [
|
|
yes('?') - "Do you really believe I don't",
|
|
yes('.') - "Perhaps in good time I will",
|
|
yes('?') - "Do you want me to"
|
|
],
|
|
|
|
why_cant - [
|
|
yes('?') - "Do you think you should be able to",
|
|
yes('?') - "Why can't you"
|
|
],
|
|
|
|
are_you - [
|
|
yes('?') - "Why are you interested in whether or not I am",
|
|
yes('?') - "Would you prefer if I were not",
|
|
yes('?') - "Perhaps in your fantasies I am"
|
|
],
|
|
|
|
i_cant - [
|
|
yes('?') - "How do you know you can't",
|
|
no - "Have you tried?",
|
|
yes('?') - "Perhaps you can now"
|
|
],
|
|
|
|
i_am - [
|
|
yes('?') - "Did you come to me because you are",
|
|
yes('?') - "How long have you been",
|
|
yes('?') - "Do you believe it is normal to be",
|
|
yes('?') - "Do you enjoy being"
|
|
],
|
|
|
|
you - [
|
|
no - "We were discussing you --not me.",
|
|
yes('?') - "Oh,",
|
|
no - "You're not really talking about me, are you?"
|
|
],
|
|
|
|
yes - [
|
|
no - "You seem quite positive.",
|
|
no - "Are you sure?",
|
|
no - "I see.",
|
|
no - "I understand."
|
|
],
|
|
|
|
no - [
|
|
no - "Are you saying no just to be negative?",
|
|
no - "You are being a bit negative.",
|
|
no - "Why not?",
|
|
no - "Are you sure?",
|
|
no - "Why no?"
|
|
],
|
|
|
|
computer - [
|
|
no - "Do computers worry you?",
|
|
no - "Are you talking about me in particular?",
|
|
no - "Are you frightened by machines?",
|
|
no - "Why do you mention computers?",
|
|
no - "What do you think machines have to do with your problems?",
|
|
no - "Don't you think computers can help people?",
|
|
no - "What is it about machines that worries you?"
|
|
],
|
|
|
|
i_want - [
|
|
yes('?') - "Why do you want",
|
|
yes('?') - "What would it mean to you if you got",
|
|
yes('?') - "Suppose you got",
|
|
yes('?') - "What if you never got",
|
|
yes('.') - "I sometimes also want"
|
|
],
|
|
|
|
question - [
|
|
no - "Why do you ask?",
|
|
no - "Does that question interest you?",
|
|
no - "What answer would please you the most?",
|
|
no - "What do you think?",
|
|
no - "Are such questions on your mind often?",
|
|
no - "What is it that you really want to know?",
|
|
no - "Have you asked anyone else?",
|
|
no - "Have you asked such questions before?",
|
|
no - "What else comes to mind when you ask that?"
|
|
],
|
|
|
|
name - [
|
|
no - "Names don't interest me.",
|
|
no - "I don't care about names --please go on."
|
|
],
|
|
|
|
because - [
|
|
no - "Is that the real reason?",
|
|
no - "Don't any other reasons come to mind?",
|
|
no - "Does that reason explain anything else?",
|
|
no - "What other reasons might there be?"
|
|
],
|
|
|
|
sorry - [
|
|
no - "Please don't apologise!",
|
|
no - "Apologies are not necessary.",
|
|
no - "What feelings do you have when you apologise?",
|
|
no - "Don't be so defensive!"
|
|
],
|
|
|
|
dream - [
|
|
no - "What does that dream suggest to you?",
|
|
no - "Do you dream often?",
|
|
no - "What persons appear in your dreams?",
|
|
no - "Are you disturbed by your dreams?"
|
|
],
|
|
|
|
hello - [
|
|
no - "How do you...please state your problem."
|
|
],
|
|
|
|
maybe - [
|
|
no - "You don't seem quite certain.",
|
|
no - "Why the uncertain tone?",
|
|
no - "Can't you be more positive?",
|
|
no - "You aren't sure?",
|
|
no - "Don't you know?"
|
|
],
|
|
|
|
your - [
|
|
yes('?') - "Why are you concerned about my",
|
|
yes('?') - "What about your own"
|
|
],
|
|
|
|
always - [
|
|
no - "Can you think of a specific example?",
|
|
no - "When?",
|
|
no - "What are you thinking of?",
|
|
no - "Really, always?"
|
|
],
|
|
|
|
think - [
|
|
no - "Do you really think so?",
|
|
yes('?') - "But you are not sure you",
|
|
yes('?') - "Do you doubt you"
|
|
],
|
|
|
|
alike - [
|
|
no - "In what way?",
|
|
no - "What resemblance do you see?",
|
|
no - "What does the similarity suggest to you?",
|
|
no - "What other connections do you see?",
|
|
no - "Could there really be some connection?",
|
|
no - "How?"
|
|
],
|
|
|
|
friend - [
|
|
no - "Why do you bring up the topic of friends?",
|
|
no - "Do your friends worry you?",
|
|
no - "Do your friends pick on you?",
|
|
no - "Are you sure you have any friends?",
|
|
no - "Do you impose on your friends?",
|
|
no - "Perhaps your love for friends worries you."
|
|
],
|
|
|
|
no_key_message - [
|
|
no - "I'm not sure I understand you fully.",
|
|
no - "What does that suggest to you?",
|
|
no - "I see.",
|
|
no - "Can you elaborate on that?",
|
|
no - "Say, do you have any psychological problems?"
|
|
]
|
|
]).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module eliza.
|
|
%-----------------------------------------------------------------------------%
|