/* A small (gnu) prolog example on emotional modeling */ /* Timo Honkela, UIAH Media Lab, Nov 11, 1999 */ /* Based on the scheme presented at http://www.brunel.ac.uk/~hsstbbp/emotlec6.htm */ /* Added: - setting linguistic approximations of fuzzy values */ /* - giving a summary of the situation */ /* Setting parameter values through linguistic approximations */ /* pleasantness */ set_p_fuzzy(Phrase) :- linguistic_approximation(Phrase, Value), set_p(Value). /* activation */ set_a_fuzzy(Phrase) :- linguistic_approximation(Phrase, Value), set_a(Value). /* Ask about the situation and give the result as a list */ what(List) :- findall(valuepair(X, Y), state(X, Y), List). /* Print the results of 'what' nicely */ what :- what(List), write('\nThe person is: \n'), print_what(List). print_what([]). print_what([valuepair(X, Y)|Rest]) :- print_one(X, Y), print_what(Rest). print_one(State, Value) :- linguistic_approximation(InternalPhrase, Value), translate_fuzzy_phrase(InternalPhrase, ExternalPhrase), write('- '), write(ExternalPhrase), write(' '), write(State), write('\n'). /* Phrases to be printed */ translate_fuzzy_phrase(very_high, 'very'). translate_fuzzy_phrase(quite_high, 'quite'). translate_fuzzy_phrase(a_little_high, 'a little'). translate_fuzzy_phrase(very_low, 'very low in'). translate_fuzzy_phrase(quite_low, 'quite low in'). translate_fuzzy_phrase(a_little_low, 'a little low in'). /* Linguistic approximations of fuzzy values */ linguistic_approximation(very_high, 1.0) :- !. linguistic_approximation(very_high, X) :- X > 0.85, !. linguistic_approximation(quite_high, 0.7) :- !. linguistic_approximation(quite_high, X) :- X > 0.5, !. linguistic_approximation(a_little_high, 0.3) :- !. linguistic_approximation(a_little_high, X) :- X > 0.15, !. linguistic_approximation(very_low, -1.0) :- !. linguistic_approximation(very_low, X) :- X < -0.85, !. linguistic_approximation(quite_low, -0.7) :- !. linguistic_approximation(quite_low, X) :- X < -0.5, !. linguistic_approximation(a_little_low, -0.3) :- !. linguistic_approximation(a_little_low, X) :- X < -0.15, !. /* The user sets the level of pleasantness of the agent */ set_p(Value) :- Value > 1.0, write('Please give values between -1 and 1\n'), !, fail. set_p(Value) :- Value < -1.0, write('Please give values between -1 and 1\n'), !, fail. set_p(Value) :- retract(pleasantness(_)), !, /* if old value exists, retracted */ asserta(pleasantness(Value)). /* new value is set */ set_p(Value) :- asserta(pleasantness(Value)). /* The user sets the level of activation of the agent */ set_a(Value) :- Value > 1.0, write('Please give values between -1 and 1\n'), !, fail. set_a(Value) :- Value < -1.0, write('Please give values between -1 and 1\n'), !, fail. set_a(Value) :- retract(activation(_)), !, asserta(activation(Value)). set_a(Value) :- asserta(activation(Value)). /* State is computed. */ /* The calculations are approximate, i.e., not following in detail the "emotion circle" */ state(stimulated, Z) :- pleasantness(P), activation(A), absolutevalue(P, AbsP), A > (AbsP / 2), Z is A - (AbsP / 2). state(euphoric, Z) :- pleasantness(P), activation(A), A > 0, P > 0, Z is (A + P) / 2.0. state(happy, Z) :- pleasantness(P), activation(A), absolutevalue(A, AbsA), P > (AbsA / 2), Z is P - (AbsA / 2). state(serene, Z) :- pleasantness(P), activation(A), A < 0, P > 0, Z is (P - A) / 2.0. state(passive, Z) :- pleasantness(P), activation(A), absolutevalue(P, AbsP), A < -1 * (AbsP / 2), Z is (-1 * A) - (AbsP / 2). state(bored, Z) :- pleasantness(P), activation(A), A < 0, P < 0, Z is ((-1 * P) - A) / 2.0. state(sad, Z) :- pleasantness(P), activation(A), absolutevalue(A, AbsA), P < -1 * (AbsA / 2), Z is (-1 * P) - (AbsA / 2). state(anxious, Z) :- pleasantness(P), activation(A), A > 0, P < 0, Z is (A - P) / 2.0. /* calculate the absolute value */ /* e.g. if X = -2.3 then AbsX becomes 2.3 */ absolutevalue(X, AbsX) :- X < 0, AbsX is -1 * X, !. absolutevalue(X, X).