2015-04-30 31 views
0

我非常感謝我的CLIPS項目的一些幫助。CLIPS遞增變量沒有無限循環

好吧,我試圖創建一個狗品種顧問。在自定義模板看起來是這樣的:

(deftemplate breed 
    (multislot name) 
    (slot size) 
    (slot type-owner) 
    (slot Living_Space) 
    (slot children) 
    (slot grooming) 
    (slot exercise) 
    (slot noisiness) 
    (slot trainability) 
    (slot aggression) 
    (slot playfulness) 
    (slot excitability) 
    (slot score)) 

一個deffacts看起來是這樣的:

(deffacts dog-breeds 
(breed (name Great_Dane) 
     (size 5) 
     (type-owner No) 
     (Living_Space 5) 
     (children 5) 
     (grooming 1) 
     (exercise 4) 
     (noisiness 2) 
     (trainability 1) 
     (aggression 2) 
     (playfulness 2) 
     (excitability 3) 
     (score 0)) 

所以我寫兩種類型defrules:一是收回不符合(用戶指定的)事實標準和其他每次事實符合標準時,類型都會增加「分數」值。只有少數規則可以收回,因此對增量規則起作用是很重要的。用戶輸入和每個插槽的標準可以從1到5.

我的問題是:如何更改以下代碼而不進入無限循環?最後,我想用最高分找出事實並展示它。

(defrule children 
(input 1) 
?children <- (breed (name ?)(size ?)(type-owner ?)(Living_Space ?) (children 1|2)(grooming ?)(exercise ?)(noisiness ?) 
(trainability ?)(aggression ?)(playfulness ?)(excitability ?)(score ?score) 
=> 
(bind ?sc (+ ?score 1)) 
(modify ?children (score ?sc)) 

回答

0

如果的(輸入1)事實上,唯一的目的是增加得分並不再需要分數遞增後,只是縮回這一事實。

(defrule children 
    ?f <- (input 1) 
    ?children <- (breed (children 1|2) (score ?score)) 
    => 
    (retract ?f) 
    (bind ?sc (+ ?score 1)) 
    (modify ?children (score ?sc))) 

請注意,我已從包含?的模式中刪除所有插槽。通配符,因爲這些是不必要的。

如果其他規則需要(輸入1)事實,則可以創建可以縮回的中間事實。

(defrule create-intermediate 
    (input 1) 
    => 
    (assert (increment))) 

(defrule children 
    ?f <- (increment) 
    ?children <- (breed (children 1|2) (score ?score)) 
    => 
    (retract ?f) 
    (bind ?sc (+ ?score 1)) 
    (modify ?children (score ?sc))) 

你也可以跟蹤你在事實中得分。添加一個(多時隙得分)到您的自定義模板的品種,然後你可以這樣做:

(defrule children 
    (input 1) 
    ?children <- (breed (children 1|2) (score ?score) (scored $?scored)) 
    (test (not (member$ children ?scored))) 
    => 
    (bind ?sc (+ ?score 1)) 
    (modify ?children (score ?sc) (scored children ?scored))) 

最後,當插槽改變是不存在的模式對象模式不重新觸發。所以,如果你使用defclasses而不是deftemplates,你可以這樣做:

(defrule children 
    (input 1) 
    ?children <- (object (is-a BREED) (children 1|2)) 
    => 
    (bind ?sc (+ (send ?children get-score) 1)) 
    (send ?children put-score ?sc)) 
+0

感謝,作品像一個魅力! –