Использование функций Python из экспертной системы Clips
-
15-09-2020 - |
Вопрос
Используя 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()
Решение
Я получил некоторую помощь в группе поддержки Pyclips.Решение состоит в том, чтобы убедиться, что ваша функция Python возвращает клипы. Symbol Object Object и использование (тестирование ...) для оценки функций в LHS по правилам.Использование сброса () также, кажется, необходимо, чтобы активировать определенные правила.
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()
. Другие советы
Ваша проблема как-то связана с (neq (python-call py_getvar user) 'None')
.Очевидно, клипам не нравится вложенный оператор.Похоже, что попытка обернуть вызов функции в оператор равенства приводит к плохим последствиям.Однако вы все равно никогда не будете утверждать значение, поскольку ваша функция возвращает либо 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()
>>>