title: 動物システム(2)

動物システム(2)
========================================

プロダクションシステムの説明をするときの定番の
例である動物システムを作ってみる．典型的な
プロダクションシステムをそのまま，Jenaに移植
するという方針で作ったものの例は[こちら](./animal1.mm)．
こちらでは，フレームシステムもどきを作ってみる．
(セマンティックウェブのオントロジーを使った
実装は[こちら](./animal3.mm)．)

    # 動物システム+フレームシステムもどき
    #
    #@include <file:rdfs.rules> .
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix : <http://test.org/> .
    
    -> ( :FClass rdfs:subClassOf rdfs:Class ) .
    -> ( :Frame  rdfs:subClassOf :FClass ) .
    -> ( :Inst   rdfs:subClassOf :FClass ) .
    -> ( :slot   rdf:type        rdf:Property) .
    -> ( :slot   rdfs:domain     :FClass ) .
    -> ( :slot   rdfs:range      rdfs:Resource ) .
    
    -> ( :is-a  rdfs:subPropertyOf :slot ) .
    -> ( :is-a  rdfs:domain        :Frame ) .
    -> ( :is-a  rdfs:range         :Frame ) .
    -> ( :inst  rdfs:subPropertyOf :slot ) .
    -> ( :inst  rdfs:domain        :Frame ) .
    -> ( :inst  rdfs:range         :Inst ) .
    # is-a関係は推移的
    (?x :is-a ?y), (?y :is-a ?z) -> (?x :is-a ?z) .
    # is-a関係とrdfs:subClassOfは実は同じ関係ということにしておく
    (?x :is-a ?y) -> (?x rdfs:subClassOf ?y) .
    (?x rdfs:subClassOf ?y) -> (?x :is-a ?y) .
    # inst関係とrdf:typeは実は同じ関係ということにしておく
    (?x :inst ?y) -> (?x rdf:type ?y) .
    (?x rdf:type ?y) -> (?x :inst ?y) .
    # スロットの情報は継承されるというルール．
    (?x :is-a ?y), (?y ?p ?z), (?p rdf:type :slot), noValue(?x ?p) -> (?x ?p ?z) .
    (?x :inst ?y), (?y ?p ?z), (?p rdf:type :slot), noValue(?x ?p) -> (?x ?p ?z) .
    
    #クラスの階層構造
    -> ( :動物     :is-a :Frame ) .
    -> ( :哺乳動物 :is-a :動物 ) .
    -> ( :肉食動物 :is-a :哺乳動物 ) .
    -> ( :トラ     :is-a :肉食動物 ) .
    -> ( :チータ   :is-a :肉食動物 ) .
    -> ( :有蹄動物 :is-a :哺乳動物 ) .
    -> ( :キリン   :is-a :有蹄動物 ) .
    -> ( :鳥       :is-a :動物 ) .
    -> ( :ペンギン :is-a :鳥 ) .
    
    -> ( :体毛     rdf:type :slot ) .
    -> ( :授乳     rdf:type :slot ) .
    -> ( :飛ぶ     rdf:type :slot ) .
    -> ( :羽       rdf:type :slot ) .
    -> ( :肉食     rdf:type :slot ) .
    -> ( :鋭い歯   rdf:type :slot ) .
    -> ( :鋭い爪   rdf:type :slot ) .
    -> ( :蹄       rdf:type :slot ) .
    -> ( :黄褐色   rdf:type :slot ) .
    -> ( :黒い縞   rdf:type :slot ) .
    -> ( :黒い斑点 rdf:type :slot ) .
    
    -> ( :哺乳動物 :体毛     'true' ) .
    -> ( :哺乳動物 :授乳     'true' ) .
    -> ( :鳥       :飛ぶ     'true' ) .
    -> ( :鳥       :産卵     'true' ) .
    -> ( :鳥       :羽       'true' ) .
    -> ( :ペンギン :飛ぶ     'false' ) .
    -> ( :肉食動物 :肉食     'true' ) .
    -> ( :肉食動物 :鋭い歯   'true' ) .
    -> ( :肉食動物 :鋭い牙   'true' ) .
    -> ( :有蹄動物 :蹄       'true' ) .
    -> ( :トラ     :黄褐色   'true' ) .
    -> ( :トラ     :黒い縞   'true' ) .
    -> ( :チータ   :黄褐色   'true' ) .
    -> ( :チータ   :黒い斑点 'true' ) .
    -> ( :キリン   :黄褐色   'true' ) .
    -> ( :キリン   :黒い斑点 'true' ) .
    
    #-----
    
    #ペンちゃんはペンギンです．
    -> ( :ペンちゃん :inst :ペンギン ) .
    -> ( :ペンちゃん rdfs:comment '岩手の釜石市で飼われているキングペンギン' ) .
    #のんはトラです．
    -> ( :のん :inst :トラ ) .
    -> ( :のん rdfs:comment '朝日山動物園のトラ(メス)' ) .

質問の例(1)ペンちゃんは飛べますか？

    PREFIX : <http://test.org/>
    SELECT *
    WHERE {:ペンちゃん :飛ぶ ?z}

質問の例(2)のんの情報を全て表示？

    PREFIX : <http://test.org/>
    SELECT *
    WHERE {:のん ?y ?z}

一応RDFスキーマを使って作成しましたが，
このぐらいだと，ぜんぜん使わないほうが
良いかも．

裏話
----------------------------------------

厳密な話，「体毛を持つならば哺乳類である」という
ことが言えても「哺乳類であれば体毛を持つ」とは
言えない．しかし上の例では，フレームシステムに
合うように拡大解釈して「哺乳類であれば体毛を持つ」
としてある．しかも，プロダクションシステムの
動物システムとは，ぜんぜん等価なシステムにはなって
いない．(動物に関するちょっとした質問に答えられる
システムになっているという点では同じと言えるが…)

