CLIPS递增变量没有无限循环

时间:2015-04-30 07:10:42

标签: infinite-loop clips expert-system

我非常感谢CLIPS项目的一些帮助。

好的,所以我正在尝试创建一个狗品种顾问。 deftemplate看起来像这样:

(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))

所以我写了两种类型的规则:一种是收回不符合(用户指定)标准的事实,另一种是每次事实符合标准时增加“得分”值。只有少数规则撤消,因此让增量规则工作对我来说很重要。每个插槽的用户输入和标准可以是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))

1 个答案:

答案 0 :(得分: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)))

您还可以跟踪您在事实中得分。添加(多区域评分)到您的品种deftemplate然后您可以这样做:

(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))