Использование функций Python из экспертной системы Clips
Используя PyClips, я пытаюсь создать правила в клипах, которые динамически извлекают данные из интерпретатора 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 ответа
Я получил некоторую помощь от группы поддержки PyClips. Решение состоит в том, чтобы ваша функция Python возвращала объект clips.Symbol и использовала (test ...) для оценки функций в LHS правил. Использование 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()
Ваша проблема как-то связана с (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()
>>>