例題 3.4 人間とエージェントとの通信を支援する

  • 概要
  • エージェント
  • 起動

  • (1)概要

    例題 3.4 で設計したエージェントを用いて直接落札を使った組織構成を行う。

    (2)エージェント

    ACLエディタ(_interface)
    ここにパフォーマティブ(:perforamtive)や宛先(:to)を入力し、 CnpManagerに対してメッセージを送信する。

    組織構成エージェント(CnpManager)
    他のエージェント(ACLエディタを含む)から受信したメッセージを組織構成プロトコル に適した形式に変換し、指定されたエージェントとの通信を行う。

    DB-access
    例題 3.4 で設計したエージェントにODB-iwateをメンバとする組織を 構成するためのルールを追加したもの。

    ODB-iwate
    例題 3.3 で述べられていたODB-iwateに組織構成に必要なルールを追加したもの。

    (2.1)DB-access.dash

       1  // 例題 3.4
       2  (agent DB-access  /* データベースアクセス仲介エージェントDB-access */
       3    (property  (create :author "太郎@ieice" :date "11/11/1999"))
       4    (initial_facts)
       5    (include :file Dash-Org.rset)  // 組織構成ルールセットの読み込み
        6
       7    (knowledge
       8      (rule receive-whereis  /* 所在地の問い合わせ要求の処理 */
       9        (Msg :performative from-user
      10             :from         _interface
                     :content      (whereis :name ?name)) = ?msg
      11        -->
      12        (make (whereis :name ?name))
      13        (make (onsen :name ?name :type unknown :city unknown))
      14        (remove ?msg))
    
      15      (rule receive-whattype  /* 泉質の問合せ要求の処理 */
      16        (Msg :performative from-user
      17             :from _interface
                     :content (whattype :name ?name)) = ?msg
      18        -->
      19        (make (whattype :name ?name))
      20        (make (onsen :name ?name :type unknown :city unknown))
      21        (remove ?msg))
    
      22      (rule sendto-ODB  /* ODB-iwateへの検索要求の送信 */
      23        (onsen) = ?onsen
     24    (Members :contractor ?ODB-iwate )    
      25        -->
     26    (send :performative request-information :to  ?ODB-iwate    
      27              :content ?onsen)
      28        (remove ?onsen))
    
      29      (rule deny  /* 解釈不能メッセージの処理 */
      30        (Msg :from _interface :content ?c) = ?msg
      31        -->
      32        (send :performative sorry :to _interface :content ?c)
      33        (remove ?msg))
    
      34      (rule answer-for-whereis  /* 所在地の検索結果返信 */
      35        (whereis :name ?name) = ?q
     36    (Members :contractor ?ODB-iwate )
     37    (Msg :performative inform :from ?ODB-iwate    
      38             :content (onsen :name ?name :city ?city)) = ?msg
      39        -->
      40        (send :performative to-user :to _interface
      41              :content (onsen :name ?name :city ?city))
      42        (remove ?q) (remove ?msg))
    
      43      (rule answer-for-whattype  /* 泉質の検索結果の返信 */
      44        (whattype :name ?name) = ?q
     45    (Members :contractor ?ODB-iwate )
     46    (Msg :performative inform :from ?ODB-iwate    
      47             :content (onsen :name ?name :type ?type)) = ?msg
      48        -->
      49        (send :performative to-user :to _interface
      50              :content (onsen :name ?name :type ?type))
      51        (remove ?q) (remove ?msg))
      52      (rule activate /* 組織構成ルールセットをアクティブにする */
      53          (Msg :performative __INIT_C :content (INIT))
      54          -->
      55          (activate Dash-Org))

      56      (rule get-member-name
              /* ODB-iwateのワークプレース上での名前を要求する */
      57        (Msg :performative __INIT_I :content (INIT))
      58        (Members :contractor ())
      59        (Status :cname ?cname :origin ?repository)
      60        -->
     61     (send :performative "request-contractor-name"
     62        :to   ?cname  (← リポジトリでの名前は(Status)から取得可能)
     63        :arrival ?repository  (← DVMが異なるので必要)
     64        :content (question :name ODB-iwate)))  (← 内部では使用していない)

      65      (rule recv-memeber-name  /* ODB-iwateの名前を格納する */  
      66        (Status :cname ?cname :origin ?repository)
     67    (Msg :performative "inform"
              :from    ?cname
              :departure ?repositry  (← リポジトリが1つしかない場合は不要)
     68        :content  ((?name ())) ) = ?msg
    下線部のエージェントリストについては、 [エージェントリストについて] を参照。
      69        (Members :contractor ()) = ?members
    70 --> 71 (modify ?members:contractor ?name) 72 (remove ?msg))
      73    )
     7行目の knowledge からここまで(青枠で囲まれた部分)がルールセット _default となる。
      74    (rule-set Dash-Org /* 組織構成ルールセット */
      75      (property)
      76      (initial_facts)
      77    (rule decompose-check
            /* タスク実現可能性の判断(分割する場合) */
      78        (task-check :id ?id :task (task :name "DB-access"))
      79        ~(bid :id ?id)
      80        -->
      81        (make (bid :id ?id :content (task :name "DB-access")))
      82        (make
      83          (decompose :id   ?id         // 変更不可
     84        :to "ODB-iwate(→ 送信先のエージェント名。
                       null の場合、タスク通知になる。)

     85        :env "null(→ エージェントが存在するRWP名。
                     null の場合、同じリポジトリであると仮定。)

     86        :wait 5000 (→ 入札待ちでタイムアウトするまでの時間 (msec))
     87        :wp "null(→ インスタンシエート先のWP名。
                     null の場合、上位エージェントの指定に従う。)

     88        :task (task :name "温泉DB" :prefecture "岩手県")  )))
                 (→ (2.2) ODB-iwate の92行目と同じように記述する)
      89

      90    (rule award-check  /* 落札内容に関するルール */
      91        (init :id ?id :award ?award) = ?init
      92        (!= ?init:name "null")
      93        (!= ?init:name "FALSE")
      94        ~(award :id ?id)
      95        -->
      96        (make (award :id      ?id  // 変更不可
     97        :name  "温泉DB"
     (→ 該当するタスク(task)ファクトの機能名(:name)を記述する。 (88行目の下線部) )

     98        :content ((URL :url "bar.sample.jp")) )))
     (→ 落札(award)メッセージに追加して送信したい情報を記述する。 )
      99  )
    74行目の rule-set からここまでが、ルールセット Dash-Org となる。
     100  )

    DASHに移行するために追加した記述について

    24,26,
    36〜37,
    45〜46: 
    DASHのワークプレース上では、エージェント名に生成時間が含まれるため ルール内に直接、その名前を記述することはできない。送信元(先)として 使用するためには動的に代入できるようにする必要がある。
    組織構成プロトコルを用いた場合におけるエージェント名の取得方法については 後述する。()

    組織構成を可能にするために追加した記述について

    56〜64:  DB-accessのメンバであるODB-iwateのワークプレース上の名前を 取得するために、リポジトリ上に存在するインスタンシエート元のエージェントに対して、 要求メッセージを送信する。ここに書かれている内容はほとんど必要であるが、現在までの ところ、64行目の :content については、使用していないので記述内容に制限はない。

    65〜72:  56〜64行目のルールによって送信されたメッセージに対する返信メッセージを処理するためのルールである。 リポジトリ上のエージェントからワークプレース上のメンバ名を格納したリストが :content 属性に代入されメッセージが送信されてくる。受信するメッセージの内容については、  [ メンバ名を取得する ] を参照。

    77〜89:  タスク通知や直接落札を受信した後、タスク実現可能性を判断するルール。これまでと異なるのは、 タスクを請け負うにあたってタスク分割(具体的には、(decompose)ファクトの生成) を行う点である。タスク分割を行った場合、 サブタスクについて入札があった/拒否がこないと判断できてから入札の送信/落札待ちの状態に遷移する。  ( → タスク評価 )

    90〜99:  落札(award)メッセージと共にメンバに対して伝えたい情報がある場合に 用いるルール。複数に分割していた場合は、必要な数だけ(award)ファクトを生成する。 メンバ側での利用については制限はなく、OAV形式を含んだリストにする必要はない。  ( → 落札情報の追加 )

    (2.2)ODB-aomori.dash

       1  // 例題3.3 温泉データベース 〜 岩手編 〜
       2  (agent ODB-iwate  /* 温泉データ検索エージェントODB-iwate */
       3    (property
       4      (create :author "太郎@ieice"	:date "11/08/1999")
       5      (java :class javaprog.DB_onsen)) /* ODB-iwateが制御するDBプログラム */
       6
       7    (initial_facts
       8      (_local :dbfile "iwate.txt" :dbstate none))
       9
      10    (include :file Dash-Org.rset)  // 組織構成ルールセットの読み込み
       11
      12    (knowledge
      13      (rule init-db  /* プログラムdb-onsenの初期設定 */
      14        (Msg :performative __INIT_I ) 
      15        (_local :dbstate none :dbfile ?dbfile) = ?lo
      16         -->
      17        (loadBP DB_onsen)
      18        (startBP)
      19        (control init_db (?dbfile))
      20        (modify ?lo:dbstate exec))
      21      (rule retrieve-by-name  /* 温泉名による温泉データ検索処理 */
      22        (Msg :performative request-information
      23             :from ?from :content (onsen :name ?name :type unknown
      24             :city unknown)) = ?msg
      25        (!= ?name unknown) (_local :dbstate exec)
      26        -->
      27        (bind ?type (control retrieveTypeByName (?name)))
      28        (bind ?city (control retrieveCityByName (?name)))
      29        (send :performative inform :to ?from
      30              :content (onsen :name ?name :type ?type :city ?city))
      31        (remove ?msg))
      32      (rule retrieve-by-type  /* 泉質による温泉データ検索処理 */
      33        (Msg :performative request-information
      34             :from ?from :content (onsen :name unknown :type ?type
      35             :city unknown)) = ?msg
      36        (!= ?type unknown) (_local :dbstate exec)
      37        -->
      38        (bind ?name (control retrieveNameByType (?type)))
      39        (bind ?city (control retrieveCityByName (?name)))
      40        (send :performative inform :to ?from
      41              :content (onsen :name ?name :type ?type :city ?city))
      42        (remove ?msg))
      43      (rule retrieve-by-city  /* 所在地による温泉データ検索処理 */
      44        (Msg :performative request-information
      45             :from ?from :content (onsen :name unknown :type unknown
      46             :city ?city)) = ?msg
      47        (!= ?city unknown) (_local :dbstate exec)
      48        -->
      49        (bind ?name (control retrieveNameByCity (?city)))
      50        (bind ?type (control retrieveTypeByName (?name)))
      51        (send :performative inform :to ?from 
      52              :content (onsen :name ?name :type ?type :city ?city))
      53        (remove ?msg))
      54      (rule retrieve-failed  /* 検索失敗処理 */
      55        (Msg :performative request-information :from ?from
      56             :content (onsen :name ?name :type ?type
      57             :city ?city)) = ?msg
      58        -->
      59        (send :performative retrieve-failed :to ?from
      60              :content (onsen :name unknown :type unknown
      61              :city unknown))
      62        (remove ?msg))
      63      (rule input-data  /* 温泉データ追加処理 */ 
      64        (Msg :performative input
      65             :content (onsen :name ?name :type ?type
      66             :city ?city)) = ?msg
      67        (!= ?name unknown) (!= ?type unknown) (!= ?city unknown)
      68        (_local :dbstate exec)
      69        -->
      70        (control input (?name ?type ?city)) (remove ?msg))
      71      (rule delete-data  /* 温泉データ削除処理 */
      72        (Msg :performative delete
      73             :content (onsen :name ?name)) = ?msg
      74        (_local :dbstate exec)
      75        -->
      76        (control delete (?name)) (remove ?msg))
      77      (rule send-sorry  /* 解釈不能メッセージの処理 */
      78        (Msg :performative ?p :from ?from
      79             :content ?content) = ?msg
      80        -->
      81        (send :performative sorry :to ?from :content ?content)
      82        (remove ?msg))
      83      (rule activate /* 組織構成ルールセットをアクティブにする */
      84          (Msg :performative __INIT_C :content (INIT))
      85          -->
      86          (activate Dash-Org))
      87    )
    12行目の knowledge からここまで(青枠で囲まれた部分)がルールセット _default となる。
      88    (rule-set Dash-Org /* 組織構成ルールセット */
      89      (property)
      90      (initial_facts)
      91      (rule task-check /* タスク実現可能性の判断(分割しない場合) */
      92        (task-check :id ?id :task
    
              (task :name "温泉DB" :prefecture "岩手県"))
              タスク通知/直接落札メッセージ側に記述されている内容
      93        ~(bid :id ?id)
      94        -->
      95        (make (bid :id ?id :content
    
              (task :name "温泉DB" :prefecture "岩手県")))))
              入札/動作可能メッセージ側に記述する内容
    88行目の rule-set からここまでが、ルールセット Dash-Org となる。
      96  )
    

    組織構成を可能にするために追加した記述(プログラム内の赤枠で囲んだ箇所)について

    91〜95: タスク実現可能性を判断するためのルール。例題 3.2 との違いは、県名(:prefecture)が 青森県 → 岩手県 になったこと。

    (3)起動

     1. 起動と読み込み
    リポジトリとワークプレースを起動すると(2)で示したエージェントが リポジトリ上に読み込まれる。注意点としては、(2.2)の8行目で記述した「iwate.txt」の 位置に気をつける。起動時のディレクトリによっては、読み込みに失敗する場合がある。

       リポジトリ   

     ODB-iwate 
        
     DB-access 
      
     ワークプレース 

     _interface  (ACLエディタ) 
        
     CnpManager.xxx... 
    全てのエージェント名が既知であり、同じリポジトリ上に存在しているものとする。

     2. メッセージの送信
    次に、 [acl-editor] タブの各空欄に以下のように入力し、 [Send] ボタンを押す。

    :performative
    directed-award
    :to
    CnpManager
    :content
    (request :to DB-access :content (task :name DB-access))
     Send 

     3. 直接落札の送信
    以下のように直接落札(directed-award)メッセージが送信される。

       リポジトリ   

     ODB-iwate 



     DB-access 









     <--[ directed-award ]-- 

     ワークプレース 

     _interface  (ACLエディタ) 
    |
    [ directed-award ]
     CnpManager.xxx... 

     4. タスク実現可能性の判断 (DB-access)
    (2.1)の77〜88行目に記述したルールが発火する。
    この後、読み込んだルールが発火し、ODB-iwate に対して直接落札メッセージが送信される。

       リポジトリ   

     ODB-iwate 

    [ directed-award ]
     DB-access 
      
     ワークプレース 

     _interface  (ACLエディタ) 



     CnpManager.xxx... 

     5. タスク実現可能性の判断 (ODB-iwate)
    (2.2)の91〜95行目に記述したルールが発火する。
    依頼されたタスクは実現可能なので拒否(refusal)メッセージは送信しない。

     6. 落札の送信 (CnpManager → DB-access)
    一定時間経過後、 CnpManager から落札(award)メッセージが送信される。

       リポジトリ   

     ODB-iwate 
        
     DB-access 







     <--[ award ]-- 
     ワークプレース 

     _interface  (ACLエディタ) 
        
     CnpManager.xxx... 

     7. 落札メッセージ送信の前処理
    (2.1)の90〜98行目に記述した落札内容に関するルールが発火する。

     8. インスタンシエート (DB-access)
    エージェントDB-accessがインスタンシエートを行う。

       リポジトリ   

     ODB-iwate 



     DB-access 








     (_createInstance)→

    ←(createdInstance)
     ワークプレース 

     _interface  (ACLエディタ) 
     CnpManager.xxx... 

     DB-access.yyy... 

     9. 落札の送信 (DB-access → ODB-iwate)
    DB-access からODB-iwate に対して落札(award)メッセージが送信される。 このとき、環境モニタの[msg]タブを開くと以下のような表示がされていて、 落札メッセージの内容を確認することができる。

       リポジトリ   

     ODB-iwate 

    [ award ]

     DB-access 
      
     ワークプレース 

     _interface  (ACLエディタ) 
     CnpManager.xxx... 

     DB-access.yyy... 

    DB-accessがODB-iwateに送った落札メッセージの内容
    (Msg
      :performative award
      :from DB-access
      :to ODB-iwate
      :replyWith 6
      :inReplyTo 0
      :departure null
      :arrival null
    
     :wp w1:_localhost
     ( ← インスタンシエート先のワークプレース名。(decompose)ファクトを生成するときは 「null」を指定したので、上位のエージェント(CnpManager)から指定されたワークプレースが自動的に代入されている。)

     :manager DB-access.200212070233416:w1:_localhost
     ( ← マネージャエージェント(DB-access)のワークプレースにおける名前が代入されている。)

     :award ((URL :url bar.sample.jp))
     ( ← 98行目に記述した内容がメッセージに正しく添付されていることが確認できる。)

     :tid 2
     :content (task :name 温泉DB :prefecture 岩手県))
     ( ← サブタスクである(decompose)ファクトに記述した内容(88行目)がそのまま代入される。)

     10. インスタンシエート (ODB-iwate)
    エージェントODB-iwateがインスタンシエートを行う。 ワークプレース上で動作するように記述した(14行目)ベースプロセスが以下のような メッセージを出力する。

       リポジトリ   





     DB-access 
      
     ODB-iwate 










     (_createInstance)→

    ←(createdInstance)
     ワークプレース 

     _interface  (ACLエディタ) 
     CnpManager.xxx... 
     DB-access.yyy... 

     ODB-iwate.zzz... 

    ワークプレース上に生成されたODB-iwateが出力する結果
    Load ./iwate.txt
    金田一温泉  単純泉          二戸市  50
    奥中山温泉  ナトリウム炭酸水素塩泉  一戸町  80
    田山温泉   アルカリ性単純泉     安代町  60
    

     11. 動作可能の送信
    エージェントODB-iwateからDB-accessに対して動作可能(acceptance)メッセージが送信され、 DB-accessからCnpManagerに動作可能メッセージが送信される。最後にCnpManagerが結果を出力する。

       リポジトリ   




     DB-access 

    [ acceptance ]

     ODB-iwate 







     --[ acceptance ]--> 
     ワークプレース 

     _interface  (ACLエディタ) 

     CnpManager.xxx... 

     DB-access.yyy... 
     ODB-iwate.zzz... 

    CnpManagerが出力する結果
    From: [CnpManager] Message: [インスタンシエートに成功しました。

     12. インスタンシエートの完了
    ワークプレースに生成されたエージェントに対して、例題の from-user 等が 送信可能な状態になる。



    Last modified: Fri Jan 24 17:19:21 JST 2003

    前のページに戻る ]   [ インデックスへ ]   [ 次の例題に進む ]