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

CLIPS国旗颜色查询程序运行报错求助

CLIPS国旗颜色匹配代码错误修复

问题场景

编写了一段CLIPS代码,需求是接收用户输入的颜色,输出所有国旗包含该颜色集合的国家。原始代码如下:

(deftemplate country
    (slot name)
    (multislot flag_colors))

(deffacts countries
    (country (name "United States of America") (flag_colors red white blue))
    (country (name "Belgium") (flag_colors black yellow red))
    (country (name "Poland") (flag_colors white red))
    (country (name "Monaco") (flag_colors white red))
    (country (name "Sweden") (flag_colors yellow blue))
    (country (name "Panama") (flag_colors red white blue))
    (country (name "Jamaica") (flag_colors black yellow green))
    (country (name "Colombia") (flag_colors yellow blue red))
    (country (name "Italy") (flag_colors green white red))
    (country (name "Ireland") (flag_colors green white orange))
    (country (name "Greece") (flag_colors blue white))
    (country (name "Botswana") (flag_colors blue white black)))

(defrule find-countries-with-colors
   ?c <- (country (name ?name) (flag_colors $?colors))
   ?input-colors <- (input-colors $?userColors)
   (test (subsetp $?userColors $?colors))
   =>
   (printout t "Country: " ?name crlf))

(deffunction subsetp (?sublist ?list)
   (if (or (not (listp ?sublist)) (not (listp ?list)))
       then FALSE
       else
       (foreach ?element ?sublist
          (if (not (member ?element ?list))
              then return FALSE))
       return TRUE))

(defrule get-user-input
   (declare (salience 10))
   =>
   (printout t "Enter colors separated by spaces: ")
   (bind ?colors-string (readline))
   (bind ?colors (explode$ ?colors-string))
   (assert (input-colors (create$ ?colors))))

(defrule no-match-found
   (not (find-countries-with-colors))
   =>
   (printout t "No country found with the specified colors." crlf))

(defrule run
   (declare (salience -10))
   =>
   (run))

运行时出现以下错误:

Defining deftemplate: Country
Defining deffacts: Countries
Defining defrule: find-country-by-colors
[PRNTUTIL2] Syntax Error: Check appropriate syntax for defrule.

ERROR:
(defrule MAIN::find-country-by-colors
?request <- (request (
Defining deffunction: subsetp
[DFFNXPSR2] Deffunctions are not allowed to replace external functions.

ERROR:
(deffunction MAIN::subsetp
(
Defining deffunction: main

[EXPRNPSR3] Missing function declaration for colors.

ERROR:
(deffunction MAIN::main
()
(printout t "Enter colors separated by spaces: ")
(bind ?user-colors (explode$ (readline)))
(assert (request (colors
FALSE

错误分析

  1. 重定义内置函数:CLIPS自带subsetp函数,自定义同名函数会触发[DFFNXPSR2]错误。
  2. 缺少input-colors模板定义:直接断言input-colors事实,但未声明对应的deftemplate,导致语法解析错误。
  3. no-match-found规则逻辑错误:不能用(not (find-countries-with-colors))检查无匹配,该写法不符合CLIPS规则引用语法,需改为检查输入存在但无对应国家的逻辑。
  4. run规则无限递归:规则内调用(run)会反复触发自身,导致程序无法正常执行。

修复后的完整代码

(deftemplate country
    (slot name)
    (multislot flag_colors))

; 新增input-colors模板,用于存储用户输入的颜色
(deftemplate input-colors
    (multislot colors))

(deffacts countries
    (country (name "United States of America") (flag_colors red white blue))
    (country (name "Belgium") (flag_colors black yellow red))
    (country (name "Poland") (flag_colors white red))
    (country (name "Monaco") (flag_colors white red))
    (country (name "Sweden") (flag_colors yellow blue))
    (country (name "Panama") (flag_colors red white blue))
    (country (name "Jamaica") (flag_colors black yellow green))
    (country (name "Colombia") (flag_colors yellow blue red))
    (country (name "Italy") (flag_colors green white red))
    (country (name "Ireland") (flag_colors green white orange))
    (country (name "Greece") (flag_colors blue white))
    (country (name "Botswana") (flag_colors blue white black)))

; 利用CLIPS内置的subsetp函数,无需自定义
(defrule find-countries-with-colors
   ?input <- (input-colors (colors $?userColors))
   ?c <- (country (name ?name) (flag_colors $?colors))
   (test (subsetp $?userColors $?colors))
   =>
   (printout t "Country: " ?name crlf))

(defrule get-user-input
   (declare (salience 10))
   ; 初始事实触发输入请求,避免无限递归
   (initial-fact)
   =>
   (printout t "Enter colors separated by spaces: ")
   (bind ?colors-string (readline))
   (bind ?colors (explode$ ?colors-string))
   (assert (input-colors (colors $?colors))))

; 修正无匹配的检查逻辑:存在输入但无符合条件的国家
(defrule no-match-found
   (input-colors (colors $?userColors))
   (not (country (flag_colors $?colors&:(subsetp $?userColors $?colors))))
   =>
   (printout t "No country found with the specified colors." crlf))

说明

  1. 移除了自定义的subsetp函数,直接使用CLIPS内置的同名函数完成子集判断。
  2. 新增input-colors模板,规范用户输入事实的结构。
  3. 修改get-user-input规则,通过initial-fact触发输入请求,避免递归问题。
  4. 重构no-match-found规则,正确检查存在用户输入但无对应国家的场景。

运行时,CLIPS会自动加载初始事实,触发输入提示,输入颜色(如red white)后,程序会输出所有国旗包含这两种颜色的国家。

内容的提问来源于stack exchange,提问作者DosAi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 08:32:02