2010-07-14 75 views
4

使用PyClips,我試圖建立在從Python解釋器動態檢索數據的剪輯中的規則。爲此,我註冊了the manual中列出的外部功能。使用Python的函數從剪輯專家系統

下面的代碼是該問題的一個玩具示例。我這樣做是因爲我的應用程序擁有大量的數據庫,採用SQL數據庫的形式,我希望使用剪輯進行推理。但是,如果我可以直接將剪輯直接插入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() 

回答

3

我在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() 
1

您的問題與(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)"

這應該工作。在剛剛搞定之前沒有使用過pyclip,但那應該是你想要的。

HTH!

>>> 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() 
>>> 
+0

對不起,但您的解決方案無法正常工作。我犯了同樣的錯誤。請注意,目標是在任意Clips表達式中使用Python函數的結果,因此刪除(neq ...)將不被接受。 – Cerin 2010-07-20 00:54:24

+0

'(neq ...)'返回符號TRUE或FALSE - 儘管將Nil(由get_var返回)與字符串「None」的比較否定的結果總是不爲假,意思是TRUE,而不管全局包含的內容。但是,如果您希望基於輸入到函數的符號爲TRUE或FALSE,只需返回該函數的值即可。 – 2010-07-20 03:01:25

+0

你甚至運行過代碼嗎?您的解決方案返回錯誤。 – Cerin 2010-07-22 00:24:43