LoginSignup
1
0

More than 5 years have passed since last update.

clara-rulesの世界(4)

Last updated at Posted at 2017-07-29

前回

clara-rulesのセッションの中身を外から調べるためのクエリ機能があるので使い方を調べてみた。

  • 基本的にはルールの左辺だけを定義する。

ルールとの役割の違い

  • ルールはセッションに追加された既存のファクトから新しいファクトを導き出すために使う
  • クエリは純粋にセッションの中を調べるために使う
    • デバッグ
    • 計算が終わったセッションから情報を取り出し、別の処理に渡すための中間ステップ

コード例


(ns  clara-rules.join
  (:require [clara.rules :refer [defrule fire-rules insert
                                 mk-session query defquery]]))

(defrecord TypeA [attr-a join-key])

(defrecord TypeB [attr-b join-key])

;;Queries
(defquery find-all-As
  [];;parameters
  [?a <- TypeA];;Matching condition
  )

(defquery find-As-by-attr
  [:?value];; Parameter needs to be a keyword
  [?a <- TypeA (= attr-a ?value)])

(defquery find-join-key-of-As
  []
  [TypeA (= ?jk join-key)])

(defquery find-A-and-B-pair-by-join-key
  [:?value]
  [?a <- TypeA (= join-key ?value)]
  [?b <- TypeB (= join-key ?value)])

(def sess (-> (mk-session)
              (insert (->TypeA "a1" :foo)
                      (->TypeA "a2" :bar)
                      (->TypeA "a3" :baz)
                      (->TypeB "b1" :foo)
                      (->TypeB "b2" :bar)
                      (->TypeB "b3" :baz)
                      (->TypeB "b4" :qux))
              (fire-rules)))

(query sess find-all-As)
;; ({:?a {:attr-a "a1", :join-key :foo}}
;;  {:?a {:attr-a "a2", :join-key :bar}}
;;  {:?a {:attr-a "a3", :join-key :baz}})

(query sess find-As-by-attr :?value "a1")
;; => ({:?a #clara_rules.join.TypeA{:attr-a "a1", :join-key :foo}, :?value "a1"})

(query sess find-join-key-of-As)
;; => ({:?jk :foo} {:?jk :bar} {:?jk :baz})

(query sess find-A-and-B-pair-by-join-key :?value :foo)
;; => ({:?a {:attr-a "a1", :join-key :foo},
;;      :?value :foo,
;;      :?b {:attr-b "b1", :join-key :foo}})

上記コードの注目点

  • defqueryはパラメターを外部受けとることができること以外は、defruleの左辺と同じ様に書ける
    • 変数の束縛etc
  • querydefquery内で束縛された変数を結果のマップのキーとして返す
  • queryはマッチした物をマップのシークエンスとして返す

感想

以前までの例では結果を確認するためにはルールの右辺で副作用を(println)用いる事しかしていなかった。
副作用を用いずに結果を確認する手段が無いものかと触った時から抱いていた疑問が一つ解けたので嬉しい。

次回

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0