我非常感谢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))
答案 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))