在Clips专家系统中使用Python函数

4 投票
2 回答
3089 浏览
提问于 2025-04-16 01:17

我正在使用PyClips,想要在Clips中建立一些规则,这些规则可以动态地从Python解释器中获取数据。为此,我按照手册的说明,注册了一个外部函数。

下面的代码是我遇到问题的一个简单示例。我这样做是因为我有一个包含大量数据的应用程序,这些数据存储在SQL数据库中,我希望能用Clips来进行推理。但是,我不想浪费时间把所有这些数据转换成Clips的声明,如果我可以直接把Clips“插入”到Python的命名空间中。

然而,当我尝试创建规则时,出现了错误。我到底哪里做错了呢?

import clips

#user = True

#def py_getvar(k):
#    return globals().get(k)
def py_getvar(k):
    return True if globals.get(k) else clips.Symbol('FALSE')

clips.RegisterPythonFunction(py_getvar)

print clips.Eval("(python-call py_getvar user)") # Outputs "nil"

# If globals().get('user') is not None: assert something
clips.BuildRule("user-rule", "(neq (python-call py_getvar user) nil)", "(assert (user-present))", "the user rule")
#clips.BuildRule("user-rule", "(python-call py_getvar user)", "(assert (user-present))", "the user rule")

clips.Run()
clips.PrintFacts()

2 个回答

1

你的问题和这个代码有关:(neq (python-call py_getvar user) 'None')。看起来,clips不喜欢这种嵌套的写法。把一个函数调用放在等式判断里,会导致一些问题。不过,你其实也不需要去判断这个值,因为你的函数要么返回Nil,要么返回一个值。你应该这样做:

def py_getvar(k):
    return clips.Symbol('TRUE') if globals.get(k) else clips.Symbol('FALSE')

然后把 "(neq (python-call py_getvar user) 'None')" 改成 "(python-call py_getvar user)"

这样应该就可以了。我之前没用过pyclips,刚刚才开始接触,但这样做应该能达到你想要的效果。

希望对你有帮助!

>>> import clips
>>> def py_getvar(k):
...     return clips.Symbol('TRUE') if globals.get(k) else clips.Symbol('FALSE')

...
>>> clips.RegisterPythonFunction(py_getvar)
>>> clips.BuildRule("user-rule", "(python-call py_getvar user)", "(assert (user-
present))", "the user rule")
<Rule 'user-rule': defrule object at 0x00A691D0>
>>> clips.Run()
0
>>> clips.PrintFacts()
>>>
3

我在PyClips的支持小组得到了些帮助。解决办法是确保你的Python函数返回一个clips.Symbol对象,并在规则的左侧使用(test ...)来评估这些函数。此外,使用Reset()似乎也是必要的,这样才能激活某些规则。

import clips
clips.Reset()

user = True

def py_getvar(k):
    return (clips.Symbol('TRUE') if globals().get(k) else clips.Symbol('FALSE'))

clips.RegisterPythonFunction(py_getvar)

# if globals().get('user') is not None: assert something
clips.BuildRule("user-rule", "(test (eq (python-call py_getvar user) TRUE))",
                '(assert (user-present))',
                "the user rule")

clips.Run()
clips.PrintFacts()

撰写回答