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

Android/Kotlin中使用CLIPS4android获取规则执行输出的方法问询

在Android/Kotlin中获取CLIPS4Android的执行输出

嘿,作为CLIPS新手在Android项目里用CLIPS4Android,确实得搞清楚怎么捕获规则执行后的输出。结合你给出的RulesTest类,我给你分享几种实用的方法:

方法1:通过clips.eval()查询结果

CLIPS的eval()方法可以执行CLIPS命令并返回字符串结果,你可以在run()方法执行完规则后,用它来查询facts、agenda或者自定义的查询语句,从而获取输出。

修改你的run()方法如下:

fun run(): String? {
    try {
        // 执行前先查看初始facts(可选)
        Log.d(tag, "初始facts: ${clips.eval("(facts)")}")
        // 运行规则
        clips.run()
        // 执行后查询结果,这里以查询所有facts为例,你可以换成自己需要的CLIPS命令
        val executionResult = clips.eval("(facts)")
        Log.d(tag, "规则执行后facts: $executionResult")
        return executionResult
    } catch (e: CLIPSError) {
        Log.e(tag, "执行CLIPS命令出错: ${e.message}")
        return null
    }
}

这种方法最适合获取CLIPS内置命令的输出,比如查看当前事实库、议程中的规则等。

方法2:重定向CLIPS的标准输出

如果你的CLIPS规则里用了(printout stdout "内容")这样的语句输出信息,默认这些内容会到控制台,但在Android里我们可以通过自定义Router来捕获这些输出。

在你的RulesTest的init块中添加路由配置:

init {
    clips = Environment()
    clips.load(filepath)
    Log.d(tag, "Loading .clp...\n\n")
    
    // 配置自定义路由,捕获stdout输出
    clips.setRouter("stdout", object : Router() {
        override fun print(str: String) {
            // 这里捕获到CLIPS规则中printout的内容
            Log.d(tag, "CLIPS规则输出: $str")
            // 你可以把str存储到成员变量中,比如:
            // this@RulesTest.outputBuffer.append(str)
        }

        override fun println(str: String) {
            print(str + "\n")
        }

        override fun query(str: String): Boolean {
            return false // 不需要交互输入,返回false即可
        }
    })
    
    clips.reset()
}

这样只要CLIPS规则里有printout的输出,都会被这个Router捕获,你可以直接打印到Log或者存到缓冲区供后续使用。

方法3:通过全局变量传递结果

如果你的规则需要返回结构化的处理结果,可以在CLIPS中定义全局变量,规则执行时给全局变量赋值,再在Kotlin中通过eval()获取这个变量的值。

第一步:在CLIPS规则文件中定义全局变量

; 定义全局变量存储结果
(defglobal ?*processingResult* = "")

; 示例规则
(defrule process-product
    (Product (productId ?pid) (quantity ?qty))
    =>
    ; 处理逻辑后给全局变量赋值
    (bind ?*processingResult* (str-cat "处理产品ID: " ?pid " 数量: " ?qty))
)

第二步:在Kotlin中获取全局变量

修改run()方法:

fun run(): String? {
    try {
        clips.run()
        // 获取CLIPS全局变量的值
        val result = clips.eval("?*processingResult*")
        Log.d(tag, "规则处理结果: $result")
        return result
    } catch (e: CLIPSError) {
        Log.e(tag, "获取结果失败: ${e.message}")
        return null
    }
}

这种方法适合传递自定义的业务结果,把规则处理后的信息通过全局变量传递到Kotlin代码中。

结合你的代码的完整示例

这里整合了方法2和方法3的RulesTest类:

class RulesTest(filepath: String?) {
    private val clips: Environment
    private val outputBuffer = StringBuilder() // 存储CLIPS输出的缓冲区

    fun stop() {
        clips.destroy()
    }

    @Throws(CLIPSError::class)
    fun assertItems(products: List<Item>) {
        for (product in products) {
            val insertItem = "(Product " +
                    "(productId ${product.ProductId})" +
                    "(uomid ${product.UOMId})" +
                    "(quantity ${product.Quantity}))"
            Log.d(tag, "插入事实: $insertItem")
            clips.assertString(insertItem)
        }
    }

    fun run(): String? {
        return try {
            clips.run()
            // 获取全局变量结果
            val globalResult = clips.eval("?*processingResult*")
            // 同时可以获取缓冲区的输出
            Log.d(tag, "CLIPS输出汇总: ${outputBuffer.toString()}")
            globalResult
        } catch (e: CLIPSError) {
            Log.e(tag, "执行出错: ${e.message}")
            null
        }
    }

    companion object {
        const val tag = "CLIPSProductRulesTest"
    }

    init {
        clips = Environment()
        clips.load(filepath)
        Log.d(tag, "Loading .clp...\n\n")

        // 设置输出路由
        clips.setRouter("stdout", object : Router() {
            override fun print(str: String) {
                outputBuffer.append(str)
                Log.d(tag, "CLIPS输出: $str")
            }

            override fun println(str: String) {
                print(str + "\n")
            }

            override fun query(str: String): Boolean {
                return false
            }
        })

        clips.reset()
    }
}

根据你的需求选择合适的方法就好啦,如果是看事实变化用方法1,捕获规则里的打印用方法2,传递业务结果用方法3~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:19