Erlang 编程/自治代理
外观
这里我们有一个简单的聊天机器人代理,称为 person/4。我们创建了它的两个实例,称为 Tarzan 和 Jane。他们互相交谈。每个都有一个超时时间。超时时间是等待发起对话的时间长度。Jane 的初始超时时间设置为 10 秒。Tarzan 的初始超时时间设置为 8 秒。由于初始值,Tarzan 会先说话,Jane 会回应。两个超时时间都会重新开始,但保持相同的数值。再次,Tarzan 会先说话,Jane 会回应。现在事情变得有趣了。代理可以判断对话是否重复。如果对话重复,就会发送特殊的訊息来交换相对的超时时间级别。现在 Tarzan 比 Jane 等待的时间更长,Jane 有机会先说话。现在,Jane 会先说两次。然后他们再次交换主动权。由于进程是自治的,我们需要使用一个名为 jungle:quit() 的退出程序来停止它们。注意:超时时间长度的變化是翻倍或减半。超时时间變化类似于以太网冲突的指数二进制回退。外部链接:[1] 指数回退。
-module( jungle ).
-compile(export_all).
%% This program shows how chat-bot agents can exchange initiative(lead) while in conversation.
%% Start with start().
%% End with quit().
start() ->
register( tarzan, spawn( jungle, person, [ tarzan, 8000, "", jane ] ) ),
register( jane, spawn( jungle, person, [ jane, 10000, "", tarzan ] ) ),
"Dialog will start in 5ish seconds, stop program with jungle:quit().".
quit() ->
jane ! exit,
tarzan ! exit.
%% Args for person/4
%% Name: name of agent being created/called
%% T: timeout to continue conversation
%% Last: Last thing said
%% Other: name of other agent in conversation
person( Name, T, Last, Other ) ->
receive
"hi" ->
respond( Name, Other, "hi there \n " ),
person( Name, T, "", Other );
"slower" ->
show( Name, "i was told to wait more " ++ integer_to_list(round(T*2/1000))),
person( Name, T*2, "", Other );
"faster" ->
NT = round( T/2 ),
show( Name, "I was told to wait less " ++ integer_to_list(round(NT/1000))),
person( Name, NT, "", Other );
exit ->
exit(normal);
_AnyWord ->
otherwise_empty_the_queue,
person( Name, T, Last, Other )
after T ->
respond( Name, Other, "hi"),
case Last of
"hi" ->
self() ! "slower",
sleep( 2000), % give the other time to print
Other ! "faster",
person( Name, T, "", Other );
_AnyWord ->
person( Name, T, "hi", Other )
end
end.
%
respond( Name, Other, String ) ->
show( Name, String ),
Other ! String.
%
show( Name, String ) ->
sleep(1000),
io:format( " ~s -- ~s \n ", [ Name, String ] ).
%
sleep(T) ->
receive
after T ->
done
end.
% ===========================================================>%
Sample output:
18> c(jungle).
{ok,jungle}
19> jungle:start().
jane_and_tarzan_will_start_in_5_seconds
tarzan—hi
jane—hi there
tarzan—hi
jane—hi there
jane—I was told to wait less: 5
tarzan—I was told to wait more: 16
jane—hi
tarzan—hi there
jane—hi
tarzan—hi there
tarzan—I was told to wait less: 8
jane—I was told to wait more: 10
tarzan—hi
jane—hi there
tarzan—hi
jane—hi there
jane—I was told to wait less: 5
tarzan—I was told to wait more: 16
jane—hi
tarzan—hi there
20> jungle:quit().
exit