收回后 CLIPS 规则不匹配(不开火)

CLIPS rule unmatch(don't fire) after retract

我有一个包含三个模块的剪辑项目,在第二个模块的末尾,我询问用户是否要撤回先前的答案之一,如果他撤回第二个模块的答案之一,我需要收回第二个模块的所有答案,重新提问。在我收回第二个模块的所有答案后,我希望这条规则被激活

(defrule SECONDMODULE::domanda-esperto
   (declare (salience ?*highest-priority*))
      (livello-utente (livello esperto)) ;;assert in FIRSTMODULE and not retract
      =>
      (something)
      )

但是如果符合 LHS 的事实出现在事实列表中,则此规则永远不会被激活并且它也不会出现在议程中。

抱歉我的英语不好。

编辑。 @Gary 首先我问用户 5 个问题,即:

(defrule starting-rule
 (declare (salience ?*highest-priority*) (auto-focus TRUE))
  => 
 (printout t "***Inizio***" crlf)
 (focus PROFILO)
 (set-strategy random))

(defrule PROFILO::chiedi-se-possiede-auto 
 (not (domanda (nome possiede-auto) (domanda ?) (risposta ?)))
 =>
 (bind ?risposta (si-o-no "L'auto e' tua? "))
 (assert (domanda (nome possiede-auto) (domanda "L'auto e' tua? ") (risposta ?risposta)))
 )

(defrule PROFILO::frequenza-utilizzo-auto
 (not(domanda (nome frequenza-utilizzo-auto) (domanda ?) (risposta ?)))
 =>
 (bind ?risposta (risposte-range "Quante volte a settimana in media utilizzi l'auto? " 0 1-2 3-5 5-7 ))
 (assert (domanda (nome frequenza-utilizzo-auto) (domanda "Quante volte a settimana in media utilizzi l'auto? " ) (risposta ?risposta)))
)

(defrule PROFILO::conoscenza-meccanica-auto
 (not (domanda (nome conoscenza-meccanica-auto) (domanda ?) (risposta ?)))
=>
(bind ?risposta (risposte-range "Quanto ti consideri esperto della meccanica dell'auto?" 0 1 2 3 4 5))
(assert (domanda (nome conoscenza-meccanica-auto) (domanda "Quanto ti consideri esperto della meccanica dell'auto?") (risposta ?risposta)))
)

(defrule PROFILO::kit-riparazione-rapida
 (not (domanda (nome kit-riparazione-rapida) (domanda ?) (risposta ?)))
=>
(bind ?risposta (si-o-no "Possiedi un kit di riparazione rapida?"))
(assert (domanda (nome kit-riparazione-rapida) (domanda "Possiedi un kit di riparazione rapida?") (risposta ?risposta)))
)

(defrule PROFILO::anni-possesso-patente
 (not(domanda (nome anni-possesso-patente) (domanda ?) (risposta ?)))
 =>
 (bind ?risposta (risposte-range "Da quanti anni possiedi la patente? " <1 1-5 >5 ))
 (assert (domanda (nome anni-possesso-patente) (domanda "Da quanti anni possiedi la patente? ") (risposta ?risposta)))
)

在此之后我触发了一个规则,根据用户的回答描述用户的个人资料

(defrule PROFILO::livello-utente 
 ?a<-(domanda (nome possiede-auto) (domanda ?) (risposta ?))
 ?b<-(domanda (nome anni-possesso-patente) (domanda ?) (risposta ?))
 ?c<-(domanda (nome conoscenza-meccanica-auto) (domanda ?) (risposta ?))
 ?d<-(domanda (nome kit-riparazione-rapida) (domanda ?) (risposta ?))
 ?e<-(domanda (nome frequenza-utilizzo-auto) (domanda ?) (risposta ?))
 =>

 (switch (fact-slot-value ?a risposta)
  (case TRUE then (bind ?*punteggio* (+ ?*punteggio* 1)))
 )
 (switch (fact-slot-value ?d risposta)
  (case TRUE then (bind ?*punteggio* (+ ?*punteggio* 1)))
 )
 (switch  (fact-slot-value ?b risposta)
  (case <1 then (bind ?*punteggio* (+ ?*punteggio* 1)))
  (case 1-5 then (bind ?*punteggio* (+ ?*punteggio* 2)))
  (case >5 then (bind ?*punteggio* (+ ?*punteggio* 3)))
 )
 (switch (fact-slot-value ?c risposta)
  (case 1 then (bind ?*punteggio* (+ ?*punteggio* 1)))
  (case 2 then (bind ?*punteggio* (+ ?*punteggio* 2)))
  (case 3 then (bind ?*punteggio* (+ ?*punteggio* 3)))
  (case 4 then (bind ?*punteggio* (+ ?*punteggio* 4)))
  (case 5 then (bind ?*punteggio* (+ ?*punteggio* 5)))
 )
 (switch (fact-slot-value ?e risposta) 
  (case 1-2 then (bind ?*punteggio* (+ ?*punteggio* 1)))
  (case 3-5 then (bind ?*punteggio* (+ ?*punteggio* 2)))
  (case 5-7 then (bind ?*punteggio* (+ ?*punteggio* 3)))
 )
 (bind ?f ?*punteggio*)
 (if (> ?f 9) then (assert (livello-utente (livello esperto))))
 (if (< ?f 6) then (assert (livello-utente (livello principiante))))
 (if (and (> ?f 5) (< ?f 10)) then (assert (livello-utente(livello medio))))

)

之后我进入第二个模块,根据第一个模块中确定的用户配置文件激活这两个规则之一

(defrule DIAGNOSI::domanda-esperto
  (declare (salience ?*highest-priority*))
  (livello-utente (livello esperto))
  =>
  (bind ?risposta (risposte-range "In quale tra le seguenti aree e' presente il problema?" Olio-motore Olio-freni Acqua Carburante Altro))
  (assert (domanda (nome area-problema)  (domanda "In quale tra le seguenti aree e' presente il problema?") (risposta ?risposta)))
  )

(defrule DIAGNOSI::domanda-medio
  (declare (salience ?*highest-priority*))
  (livello-utente (livello medio))
  =>
  (bind ?risposta (si-o-no "Sapresti indicare l'area di provenienza del problema tra le seguenti: Olio motore, Olio freni, Acqua, Carburante, Altro?"))
  (assert (domanda  (nome domanda-area-problema) (domanda "Sapresti indicare l'area di provenienza del problema tra le seguenti: Olio motore, Olio freni, Acqua, Carburante, Altro?") (risposta ?risposta)))
  (if (eq ?risposta TRUE)
    then (bind ?risposta (risposte-range "In quale tra le seguenti aree e' presente il problema?" Olio-motore Olio-freni Acqua Carburante Altro))
          (assert (domanda  (nome area-problema) (domanda "In quale tra le seguenti aree e' presente il problema?") (risposta ?risposta)))
  )

在此之后,我向用户提出了一系列其他问题。之后我问他是否要撤回其中一个,如果他选择两个(domanda-medio,domanda-esperto)中的一个,我必须撤回第二个模块的所有答案。在我撤回第二个模块的所有答案后,如果事实列表中存在与 LHS 匹配的事实 (livello-utente (livello ?))[=14,则这两条规则永远不会被激活并且它也不会出现在议程中=]

@GaryRiley 好的,我不知道为什么但添加了`

(not (diagnosi (nome ?)))`

两条规则有效。