如何在CLIPS水果猜测程序中处理非法输入并输出提示?
针对你的CLIPS程序需求的解决方案
一、CLIPS中的匿名通配符(对应Visual Prolog的_)
CLIPS里下划线_就是匿名通配符,和Visual Prolog的_功能完全一致:匹配任意值,但不会将匹配结果绑定到变量,适合不需要捕获值的场景。此外还有两种常用通配符:
?:命名变量,匹配任意值并绑定到变量(比如?color)$?:匹配多字段槽中的任意数量值(包括0个),比如你原代码里的(color $? ?color $?)就是用来匹配多值槽中包含指定颜色的情况
示例用法:
(defrule ejemplo-anonimo (fruta (nombre ?nombre) (semilla _)) => (printout t "Fruta: " ?nombre "(种子类型不限)" crlf) )
二、添加输入不匹配的提示功能
要实现用户输入不在允许值范围内时的提示,需要修改原有输入规则,加入输入验证逻辑,无效输入时重新请求输入,具体步骤如下:
1. 定义允许值的复用事实
先把各字段的允许值定义为事实,避免在每个规则里重复写允许值:
(deffacts valores-permitidos (valor-permitido color naranja amarillo morado rojo verde) (valor-permitido semilla hueso multiple) (valor-permitido tipo-piel aterciopelada lisa rugosa) (valor-permitido crece-en arbol planta) )
2. 修改输入规则,加入验证逻辑
以颜色输入为例,其他字段同理修改:
(defrule in-color (not (color ?)) ; 未输入颜色时触发 => (printout t "Ingrese el color de la fruta: ") (bind ?input (read)) ; 验证输入是否在允许列表中 (if (not (valor-permitido color $? ?input $?)) then (printout t "Error: Color no válido. Opciones permitidas: naranja, amarillo, morado, rojo, verde" crlf) (assert (solicitar-color)) ; 标记需要重新输入 else (assert (color ?input)) ) ) ; 触发重新输入的规则 (defrule reingresar-color (solicitar-color) => (retract (solicitar-color)) (run-rule in-color) )
种子类型输入规则(修改后)
(defrule in-semilla (not (semilla ?)) => (printout t "Ingrese el tipo de semilla de la fruta: ") (bind ?input (read)) (if (not (valor-permitido semilla $? ?input $?)) then (printout t "Error: Tipo de semilla no válido. Opciones permitidas: hueso, multiple" crlf) (assert (solicitar-semilla)) else (assert (semilla ?input)) ) ) (defrule reingresar-semilla (solicitar-semilla) => (retract (solicitar-semilla)) (run-rule in-semilla) )
果皮类型输入规则(修改后)
(defrule in-tipo-piel (not (tipo-piel ?)) => (printout t "Ingrese el tipo de piel de la fruta: ") (bind ?input (read)) (if (not (valor-permitido tipo-piel $? ?input $?)) then (printout t "Error: Tipo de piel no válido. Opciones permitidas: aterciopelada, lisa, rugosa" crlf) (assert (solicitar-tipo-piel)) else (assert (tipo-piel ?input)) ) ) (defrule reingresar-tipo-piel (solicitar-tipo-piel) => (retract (solicitar-tipo-piel)) (run-rule in-tipo-piel) )
生长环境输入规则(修改后)
(defrule in-crece-en (not (crece ?)) => (printout t "Donde crece la fruta (arbol o planta): ") (bind ?input (read)) (if (not (valor-permitido crece-en $? ?input $?)) then (printout t "Error: Valor no válido. Opciones permitidas: arbol, planta" crlf) (assert (solicitar-crece-en)) else (assert (crece ?input)) ) ) (defrule reingresar-crece-en (solicitar-crece-en) => (retract (solicitar-crece-en)) (run-rule in-crece-en) )
3. 添加无匹配水果的提示规则
当用户输入的所有有效属性无对应水果时,输出提示:
(defrule sin-fruta-encontrada (color ?color) (semilla ?semilla) (tipo-piel ?tipo-piel) (crece ?crece-en) (not (fruta (color $? ?color $?) (semilla ?semilla) (tipo-piel $? ?tipo-piel $?) (crece-en ?crece-en))) => (printout t "No se encontró ninguna fruta con las características ingresadas." crlf) )
三、完整修改后的代码
(clear) (deftemplate fruta (slot nombre) (multislot color (allowed-values naranja amarillo morado rojo verde)) (slot semilla (allowed-values hueso multiple)) (multislot tipo-piel (allowed-values aterciopelada lisa rugosa)) (slot crece-en (allowed-values arbol planta)) ) ; 新增:允许值复用事实 (deffacts valores-permitidos (valor-permitido color naranja amarillo morado rojo verde) (valor-permitido semilla hueso multiple) (valor-permitido tipo-piel aterciopelada lisa rugosa) (valor-permitido crece-en arbol planta) ) ; 修改后的颜色输入规则 (defrule in-color (not (color ?)) => (printout t "Ingrese el color de la fruta: ") (bind ?input (read)) (if (not (valor-permitido color $? ?input $?)) then (printout t "Error: Color no válido. Opciones permitidas: naranja, amarillo, morado, rojo, verde" crlf) (assert (solicitar-color)) else (assert (color ?input)) ) ) (defrule reingresar-color (solicitar-color) => (retract (solicitar-color)) (run-rule in-color) ) ; 修改后的种子输入规则 (defrule in-semilla (not (semilla ?)) => (printout t "Ingrese el tipo de semilla de la fruta: ") (bind ?input (read)) (if (not (valor-permitido semilla $? ?input $?)) then (printout t "Error: Tipo de semilla no válido. Opciones permitidas: hueso, multiple" crlf) (assert (solicitar-semilla)) else (assert (semilla ?input)) ) ) (defrule reingresar-semilla (solicitar-semilla) => (retract (solicitar-semilla)) (run-rule in-semilla) ) ; 修改后的果皮输入规则 (defrule in-tipo-piel (not (tipo-piel ?)) => (printout t "Ingrese el tipo de piel de la fruta: ") (bind ?input (read)) (if (not (valor-permitido tipo-piel $? ?input $?)) then (printout t "Error: Tipo de piel no válido. Opciones permitidas: aterciopelada, lisa, rugosa" crlf) (assert (solicitar-tipo-piel)) else (assert (tipo-piel ?input)) ) ) (defrule reingresar-tipo-piel (solicitar-tipo-piel) => (retract (solicitar-tipo-piel)) (run-rule in-tipo-piel) ) ; 修改后的生长环境输入规则 (defrule in-crece-en (not (crece ?)) => (printout t "Donde crece la fruta (arbol o planta): ") (bind ?input (read)) (if (not (valor-permitido crece-en $? ?input $?)) then (printout t "Error: Valor no válido. Opciones permitidas: arbol, planta" crlf) (assert (solicitar-crece-en)) else (assert (crece ?input)) ) ) (defrule reingresar-crece-en (solicitar-crece-en) => (retract (solicitar-crece-en)) (run-rule in-crece-en) ) ; 原有查找水果规则 (defrule buscar-fruta (color ?color) (semilla ?semilla) (tipo-piel ?tipo-piel) (crece ?crece-en) (fruta (nombre ?nombre) (color $? ?color $?) (semilla ?semilla) (tipo-piel $? ?tipo-piel $?) (crece-en ?crece-en)) => (printout t "La fruta a la que se refiere es: " ?nombre crlf) ) ; 新增:无匹配水果提示规则 (defrule sin-fruta-encontrada (color ?color) (semilla ?semilla) (tipo-piel ?tipo-piel) (crece ?crece-en) (not (fruta (color $? ?color $?) (semilla ?semilla) (tipo-piel $? ?tipo-piel $?) (crece-en ?crece-en))) => (printout t "No se encontró ninguna fruta con las características ingresadas." crlf) ) (deffacts frutas (fruta (nombre Melocoton) (color naranja) (semilla hueso) (tipo-piel aterciopelada) (crece-en arbol)) (fruta (nombre Albaricoque) (color amarillo) (semilla hueso) (tipo-piel aterciopelada) (crece-en arbol)) (fruta (nombre Ciruela) (color morado) (semilla hueso) (tipo-piel lisa) (crece-en arbol)) (fruta (nombre Cereza) (color rojo) (semilla hueso) (tipo-piel lisa) (crece-en arbol)) (fruta (nombre Aguacate) (color verde) (semilla hueso) (tipo-piel rugosa) (crece-en arbol)) (fruta (nombre Mandarina) (color naranja verde) (semilla multiple) (tipo-piel rugosa) (crece-en arbol)) (fruta (nombre Limon) (color verde amarillo) (semilla multiple) (tipo-piel rugosa lisa) (crece-en arbol)) (fruta (nombre Melon) (color naranja amarillo) (semilla multiple) (tipo-piel rugosa lisa) (crece-en planta)) (fruta (nombre Sandia) (color verde) (semilla multiple) (tipo-piel lisa) (crece-en planta)) ) (reset) (run)
内容的提问来源于stack exchange,提问作者Manuel Villanueva
相关产品推荐
相关产品推荐

