2012-02-12 14 views
0

使用傑斯作爲規則引擎,我們可以斷言一個事實:一些目擊者看到一個人,在某個地方,並與時間有關:我們可以在Jess中統計具有相同值的事實嗎?

(deffacts witnesses 
    (witness Batman Gotham 18) 
    (witness Hulk NYC 19) 
    (witness Batman Gotham 2) 
    (witness Superman Chicago 22) 
    (witness Batman Gotham 10) 
) 

與規則,我想知道,如果幾個證人有在同一個地方看到同一個人,不考慮時間。

在傑斯的文檔,我們得到這個例子計數員工製作的100K salraries多:

(defrule count-highly-paid-employees 
    ?c <- (accumulate (bind ?count 0)      ;; initializer 
    (bind ?count (+ ?count 1))     ;; action 
    ?count          ;; result 
    (employee (salary ?s&:(> ?s 100000)))) ;; CE 
    => 
    (printout t ?c " employees make more than $100000/year." crlf)) 

所以我根據我以前的示例代碼:

(defrule count-witnesses 
    (is-lost ?plost) 
    (witness ?pseen ?place ?time) 
    ?c <- (accumulate (bind ?count 0) 
    (bind ?count (+ ?count 1)) 
    ?count 
    (test()) ; conditional element of accumulate 
    (test (= ?plost ?pseen)) 
    (test (>= ?count 3)) 
    => 
    (assert (place-seen ?place)) 
) 

隨着「(deffacts) '指令和規則,發動機應主張事實

(place-seen Gotham) 

,因爲我們有蝙蝠俠在哥譚看過三次。

我不知道如何使用'accumulate'的條件元素(CE)部分。我可以使用'測試'來保留同一個人和地點的事實嗎?

任何想法如何實現這一目標?

謝謝!


注:「收集」的synthax是

(accumulate <initializer> <action> <result> <conditional element>) 

回答

1

我要離開了東西約?plost,因爲你不解釋是,究竟是什麼;如果需要,您可以將它添加回自己。

(幾乎)做你想要的基本規則如下。你沒有得到的CE部分只是我們想積累的一個模式;在這裏,它匹配的事實與在同一地點實際上是由第一人匹配目睹了同一個人:

(defrule count-witnesses 
    ;; Given that some person ?person was seen in place ?place 
    (witness ?person ?place ?) 
    ;; Count all the sightings of that person in that place 
    ?c <- (accumulate (bind ?count 0) 
        (bind ?count (+ ?count 1)) 
        ?count 
        (witness ?person ?place ?)) 
    ;; Don't fire unless the count is at least 3 
    (test (>= ?c 3)) 
    => 
    (assert (place-seen ?person ?place)) 
) 

現在,這一規則的唯一問題是,它會觸發三次,你deffacts,一次爲蝙蝠俠/哥譚的每一個事實。我們可以通過更改第一種模式來阻止這種情況,以僅匹配某個人在某個特定地點的最早發現:

(defrule count-witnesses 
    ;; Given that some person ?person was seen in place ?place, and there is no other 
    ;; sighting of the same person at the same place at an earlier time 
    (witness ?person ?place ?t1)  
    (not (witness ?person ?place ?t2&:(< ?t2 ?t1))) 
    ;; Count all the sightings of that person in that place 
    ?c <- (accumulate (bind ?count 0) 
        (bind ?count (+ ?count 1)) 
        ?count 
        (witness ?person ?place ?)) 
    ;; Don't fire unless the count is at least 3 
    (test (>= ?c 3)) 
    => 
    (assert (place-seen ?person ?place)) 
) 
相關問題