【问题标题】:CLIPS incrementing variable without endless loopCLIPS递增变量没有无限循环
【发布时间】:2015-04-30 07:10:41
【问题描述】:

非常感谢您对我的 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))

所以我写了两种类型的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))

【问题讨论】:

    标签: infinite-loop clips expert-system


    【解决方案1】:

    如果(输入 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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-16
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      相关资源
      最近更新 更多