You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CLIPS规则中模板变量全匹配校验及规则失效问题排查

CLIPS规则匹配问题修复方案

问题描述

需要实现校验zakaznik模板所有变量与mobily模板完全相等:

  • 匹配时输出Telefon je na sklade: [品牌] [型号]
  • 不匹配时输出Bohuzial zadany telefon nemame na sklade
    但编写规则后,即便变量完全匹配,也仅最后一条telefon_nie_je_na_sklade规则生效。

问题根源

  1. 数据类型不匹配:使用read函数读取输入时默认返回字符串类型,但zakaznik模板的多个槽(如znacka为SYMBOL、interna_pamat为INTEGER、uhlopriecka为FLOAT)需要对应数据类型,直接断言会导致与mobily事实的槽值类型不兼容,无法触发匹配规则。
  2. 规则重复触发风险:未处理zakaznik事实,规则会持续触发,加上CLIPS默认的LEX优先级(后定义规则优先级更高),进一步加剧问题。

修复方案

1. 输入数据类型转换

在读取用户输入后,将字符串转换为模板要求的数据类型:

  • SYMBOL类型槽:用(symbol-value)转换
  • INTEGER类型槽:用(integer)转换
  • FLOAT类型槽:用(float)转换
  • STRING类型槽(如model)无需转换

2. 绑定并移除触发事实

在规则条件中绑定zakaznik事实,动作中移除该事实并停止推理,避免规则重复触发。

修复后的完整代码

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                    ;
;   Sablony pre vstupy                       ;
;                                    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(deftemplate mobily
(slot znacka (type SYMBOL))
(slot model (type STRING) )  
(slot rozlisenie (type SYMBOL) (allowed-values HD FULL_HD Q_HD))  
(slot SD_Karta (type SYMBOL) (allowed-values ano nie))
(slot interna_pamat (type INTEGER) (range 32 512))  
(slot operacny_system (type SYMBOL) (allowed-values iOS android ine))
(slot uhlopriecka (type FLOAT) (range 4.0 7.0))
(slot rozlisenie_fotoaparatu (type INTEGER) (range 4 128))
(slot kapacita_baterie (type INTEGER) (range 5 25)))

(deftemplate zakaznik
(slot znacka (type SYMBOL))
(slot model (type STRING))  
(slot rozlisenie (type SYMBOL) (allowed-values HD FULL_HD Q_HD))  
(slot SD_Karta (type SYMBOL) (allowed-values ano nie))
(slot interna_pamat (type INTEGER) (range 32 512))  
(slot operacny_system (type SYMBOL) (allowed-values iOS android ine))
(slot uhlopriecka (type FLOAT) (range 4.0 7.0))
(slot rozlisenie_fotoaparatu (type INTEGER) (range 4 128))
(slot kapacita_baterie (type INTEGER) (range 5 25)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                                    ;
;   Vstupy                               ;
;                                    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(deffacts mobily_na_sklade
(mobily(znacka Motorola)(model "Defy")(rozlisenie HD)(SD_Karta ano)(interna_pamat 64)(operacny_system android)(uhlopriecka 6.5)(rozlisenie_fotoaparatu 60)(kapacita_baterie 20)) 
(mobily(znacka Samsung)(model "Galaxy")(rozlisenie FULL_HD)(SD_Karta ano)(interna_pamat 128)(operacny_system android)(uhlopriecka 6.5)(rozlisenie_fotoaparatu 32)(kapacita_baterie 25))
(mobily(znacka Iphone)(model "14")(rozlisenie FULL_HD)(SD_Karta nie)(interna_pamat 128)(operacny_system iOS)(uhlopriecka 6.1)(rozlisenie_fotoaparatu 12)(kapacita_baterie 25)) 
(mobily(znacka Iphone)(model "13")(rozlisenie Q_HD)(SD_Karta nie)(interna_pamat 128)(operacny_system iOS)(uhlopriecka 6.1)(rozlisenie_fotoaparatu 12)(kapacita_baterie 20)) 
(mobily(znacka Asus)(model "Zenfone")(rozlisenie HD)(SD_Karta ano)(interna_pamat 32)(operacny_system android)(uhlopriecka 5.9)(rozlisenie_fotoaparatu 64)(kapacita_baterie 14))
(mobily(znacka Samsung)(model "Galaxy")(rozlisenie Q_HD)(SD_Karta nie)(interna_pamat 128)(operacny_system android)(uhlopriecka 6.1)(rozlisenie_fotoaparatu 12)(kapacita_baterie 25))
(mobily(znacka Motorola)(model "Moto")(rozlisenie FULL_HD)(SD_Karta ano)(interna_pamat 32)(operacny_system android)(uhlopriecka 6.3)(rozlisenie_fotoaparatu 13)(kapacita_baterie 15))
(mobily(znacka Xiaomi)(model "Redmi")(rozlisenie HD)(SD_Karta ano)(interna_pamat 64)(operacny_system android)(uhlopriecka 6.5)(rozlisenie_fotoaparatu 108)(kapacita_baterie 16)) 
)

(defrule vypis_uvod
=>
(printout t "Vitajte v programe na vyber telefonu" crlf)
(printout t "Prosim vyberte vase specifikacie: " crlf))

(defrule osobne_hodnoty
=>
(printout t "Zadajte znacku" crlf)
(bind ?znacka (symbol-value (read)))
(printout t "Zadajte model" crlf)
(bind ?model (read))
(printout t "Zadajte ci vas vybrany telefon podporuje SD Karty (ano/nie)" crlf)
(bind ?SD_Karta (symbol-value (read)))
(printout t "Zadajte rozlisenie displeja (HD, FULL_HD, Q_HD)" crlf)
(bind ?rozlisenie (symbol-value (read)))
(printout t "Zadajte velkost internej pamete (32 - 512)" crlf)
(bind ?interna_pamat (integer (read)))
(printout t "Zadajte uhlopriecku (4.0 - 7.0)" crlf)
(bind ?uhlopriecka (float (read)))
(printout t "Zadajte operacny system(iOS, android, ine)" crlf)
(bind ?operacny_system (symbol-value (read)))
(printout t "Zadajte rozlisenie_fotoaparatu (4 - 128)" crlf)
(bind ?rozlisenie_fotoaparatu (integer (read)))
(printout t "Zadajte kapacitu baterie v hodinach (5 - 25)" crlf)
(bind ?kapacita_baterie (integer (read)))

(assert (zakaznik (znacka ?znacka)
                  (model ?model)
                  (rozlisenie ?rozlisenie)
                  (SD_Karta ?SD_Karta)
                  (interna_pamat ?interna_pamat)
                  (operacny_system ?operacny_system)
                  (uhlopriecka ?uhlopriecka)
                  (rozlisenie_fotoaparatu ?rozlisenie_fotoaparatu)
                  (kapacita_baterie ?kapacita_baterie))))

(defrule telefon_je_na_sklade
?z <- (zakaznik (znacka ?znacka)
                (model ?model)
                (rozlisenie ?rozlisenie)
                (SD_Karta ?SD_Karta)
                (interna_pamat ?interna_pamat)
                (operacny_system ?operacny_system)
                (uhlopriecka ?uhlopriecka)
                (rozlisenie_fotoaparatu ?rozlisenie_fotoaparatu)
                (kapacita_baterie ?kapacita_baterie))
(mobily (znacka ?znacka)
        (model ?model)
        (rozlisenie ?rozlisenie)
        (SD_Karta ?SD_Karta)
        (interna_pamat ?interna_pamat)
        (operacny_system ?operacny_system)
        (uhlopriecka ?uhlopriecka)
        (rozlisenie_fotoaparatu ?rozlisenie_fotoaparatu)
        (kapacita_baterie ?kapacita_baterie))
=>
(retract ?z)
(printout t "Telefon je na sklade:" ?znacka ?model crlf)
(halt))

(defrule telefon_nie_je_na_sklade
?z <- (zakaznik (znacka ?znacka)
                (model ?model)
                (rozlisenie ?rozlisenie)
                (SD_Karta ?SD_Karta)
                (interna_pamat ?interna_pamat)
                (operacny_system ?operacny_system)
                (uhlopriecka ?uhlopriecka)
                (rozlisenie_fotoaparatu ?rozlisenie_fotoaparatu)
                (kapacita_baterie ?kapacita_baterie))
(not (mobily (znacka ?znacka)
             (model ?model)
             (rozlisenie ?rozlisenie)
             (SD_Karta ?SD_Karta)
             (interna_pamat ?interna_pamat)
             (operacny_system ?operacny_system)
             (uhlopriecka ?uhlopriecka)
             (rozlisenie_fotoaparatu ?rozlisenie_fotoaparatu)
             (kapacita_baterie ?kapacita_baterie)))
=>
(retract ?z)
(printout t "Bohuzial zadany telefon nemame na sklade" crlf)
(halt))

关键修改点

  • 类型转换:对SYMBOL、INTEGER、FLOAT类型的输入做对应转换,确保zakaznik事实槽值类型与mobily一致。
  • 事实绑定与移除:用?z <-绑定zakaznik事实,动作中(retract ?z)移除该事实,避免规则重复触发。
  • 停止推理:添加(halt)终止推理过程,确保只执行一次匹配结果。

内容的提问来源于stack exchange,提问作者Filip Štepanovský

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 03:35:16