エージェントの内部状態により振る舞いを変えるエージェントについて説明します.
教科書p.80 "3.6 状況を認識して判断する" の内容に相当します.
人名 | 属性 | 秘書エージェント名 |
---|---|---|
Alice | 社員 | Secretary_A |
Bob | Aliceの上司 | Secretary_B |
Carn | Aliceの同僚 | Secretary_C |
class Secretary extends TAG { // boss(秘書エージェントに対応する人)の予定集. // 要素は[hour:13, item:'会議', with:'Bob']など (13時からBobと会議) def schedules = [] // bossの名前と秘書エージェント名の対応情報 def secretaries =[ [name:'Alice', agent:'Secretary_A'], [name:'Bob', agent:'Secretary_B'], [name:'Carn', agent:'Secretary_C'] ] // 重要度に関する人間関係(Aliceにとって,BobはCarnより重要度が高い) def priority = [Alice: ['Bob', 'Carn'], Bob: ['Alice', 'Carn'], Carn: ['Bob', 'Alice']] // 末尾のTAG.start()内でエージェント名を指定して起動する場合に必要(→2.3(2)節) Secretary(String c) { super("Secretary_$c") } // エージェント名は"Secretary_A"などとなる def loop(msg) { // bossの名前(Alice, Bob, またはCarn) def boss = secretaries.find{it.agent == this.agentname}.name if (msg._p=='do-appointment' && msg.name!=null && msg.hour!=null && msg.item!=null) { def agent = secretaries.find{it.name==msg.name}.agent // nameの担当秘書エージェントを調べる def m = request(agent, [_p:'request-appointment', hour:msg.hour, item:msg.item]) if (m._p == 'accept') { println("予定が受理されました: "+m) } } else if (msg._p=='cancel') { } else if (msg._p=='request-appointment' && msg.hour!=null && msg.item!=null) { def name = secretaries.find{it.agent==msg._f}.name // 秘書エージェントに対応する名前を調べる def schedule = schedules.find{it.hour == msg.hour} // 同じ時間にある先約を調べる if (schedule == null) { // 先約がない schedule = [hour:msg.hour, item:msg.item, with:name] // 新しい予定を作り, schedules.add(schedule) // 予定集に追加する println("予定を受理しました: "+schedule) reply(msg, [_p:'accept', schedule:schedule]) } else { // 先約がある def myPriority = priority.get(boss) if (myPriority.indexOf(schedule.with) < myPriority.indexOf(name)) { // 優先度をチェック println("優先度の高い先約があるので予定を受理しません: "+msg) reply(msg, [_p:'refusal', msg:msg]) } else { def newSchedule = [hour:msg.hour, item:msg.item, with:name] // 優先度の高い予定 println("優先度の高い予定を受理しました:"+newSchedule) schedules.add(newSchedule) reply(msg, [_p:'accept', schedule:newSchedule]) println("優先度の低い先約をキャンセルしました") schedules.remove(schedule) def agent = secretaries.find{it.name==schedule.with}.agent send(agent, [_p:'cancel', schedule:schedule]) } } } else { reply(msg, [_p:'sorry', msg:msg]) } } } TAG.start(new Secretary('A'), new Secretary('B'), new Secretary('C'))
TAG.start(...)
でエージェントを起動しています.[_p:'do-appointment', name:'Alice', hour:'13', item:'会議']
[_p:'do-appointment', name:'Alice', hour:'13', item:'会議']
reply(msg, [_p:'refusal', msg:msg])
をSecretary_Aに実行させる方法を考えてみましょう.Secretary_BとSecretary_Cに,どのようなメッセージをどのような順番で送信すればよいでしょうか?myPriority.indexOf(elem)
は,リストmyPriority
内において要素elem
が格納されているインデックスを返します.def list = ['apple', 'banana', 'melon'] def p = list.indexOf('apple') // p=0になる def q = list.indexOf('banana') // q=1になる