勇闖新世界︰ 《 pyDatalog 》 導引《十》豆鵝狐人之思考篇

如果有人嘗試去跑這個『述詞』

可達狀態(X狀態, P經由, Y狀態) <=
可達狀態(X狀態, P經由一, Z狀態) &
狀態(Z狀態, P借著, Y狀態) &
(X狀態 != Y狀態) & (P經由 == P經由一 + [P借著])

可達狀態(X狀態, P經由, Y狀態) <=
狀態(X狀態, P借著, Y狀態) & (P經由 == [P借著])

,怕會『卡住』了吧!這是為什麼的呢?再怎麼說,『豆鵝狐人』也只有十六個『狀態』,可是那個『例子捷運網』確有二十五個『站名』,又不會『卡住』??事出總該必有因的吧!!將兩張圖對比一下︰

豆鵝胡人

台北捷運

 

乍看似乎沒有什麼不同!若是細瞧『捷運網』是用同色的『捷運線 』將『站名』貫串起來;然而『邏輯網』之農夫『相同行動』卻是『散布』在『狀態』網中。假使考察

【所有路徑述詞定義】

‧ 所有路徑(X站名, Y站名, P路徑甲) <=

所有路徑(X站名, Z站名, P路徑乙) & 【※前段】

連接(Z站名, Y站名) & 【※後段】

(X站名 != Y站名) & 【※避免迴路】

(X站名._not_in(P路徑乙)) & 【※避免迴路】

(Y站名._not_in(P路徑乙)) & 【※避免迴路】

(P路徑甲 == P路徑乙 + [Z站名]) 【※ 經過路徑累計】

 

‧ 所有路徑(X站名, Y站名, P路徑甲) <=

連接(X站名, Y站名) & 【※基本連接事實】

(P路徑甲 == []) 【※基本直通,無經由路徑。】

,那個『可達狀態』的述詞將要如何避開『迴路』的呢?『迴路』造成了『無窮循環』,由於『相同行動』可以出現在『循環路徑』上,要怎樣加上

(X站名._not_in(P路徑乙)) & 【※避免迴路】

(Y站名._not_in(P路徑乙)) & 【※避免迴路】

條件的呢?難道就是 pyDatalog 的『推理引擎』足以避開『捷運網 』之『迴路』情況!卻不能夠免於『邏輯網』的『循環』原因嗎?事實上此事在『HASHTAG』《八下》文本中已經觸及,在此就稍為詳細探討一下,深入了解那兩張網因著『表達』方式引發的差異性 。首先捷運網『連接(□站, ○站) 』述詞並不管是哪一條『捷運線』接連了 □站與 ○站,其實那條『捷運線』已經『隱含』在『站名』之中了。所以知道了經由『□‧○』站,也就知道搭上了哪條線。這件事在『邏輯網』也是一樣的,從『☆ 狀態』到『△ 狀態』就已確定了農夫之『◎◎行動』。其次,當相同『站名』出現在『捷運路徑』上,我們知道發生了『迴路』,應當『給予條件』避開循環 ,就是《圖的範例graph.py 所談之『安全』的實意。如是我們可依『捷運網』之『描述法』,將『邏輯網』改寫重述如下︰

 

pi@raspberrypi ~ $ python3
Python 3.2.3 (default, Mar  1 2013, 11:53:50) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyDatalog import pyDatalog
>>> pyDatalog.create_terms('X狀態, Y狀態, Z狀態, P經由, P經由一, P借著')
>>> pyDatalog.create_terms('行動, 改變')

>>> +改變('豆鵝狐人', '豆‧狐‧')
>>> +改變('豆‧狐‧', '豆鵝狐人')
>>> +改變('豆‧狐‧', '豆‧狐人')
>>> +改變('豆‧狐人', '豆‧狐‧')
>>> +改變('豆‧狐人', '‧‧狐‧')
>>> +改變('‧‧狐‧', '豆‧狐人')
>>> +改變('‧‧狐‧', '渡河失敗')
>>> +改變('‧‧狐‧', '‧鵝狐人')
>>> +改變('‧鵝狐人', '‧‧狐‧')
>>> +改變('‧鵝狐人', '‧鵝‧‧')
>>> +改變('‧鵝狐人', '渡河失敗')
>>> +改變('‧鵝‧‧', '‧鵝狐人')
>>> +改變('‧鵝‧‧', '豆鵝‧人')
>>> +改變('豆鵝‧人', '‧鵝‧‧')
>>> +改變('‧鵝‧‧', '‧鵝‧人')
>>> +改變('‧鵝‧人', '‧鵝‧‧')
>>> +改變('‧鵝‧人', '到達彼岸')
>>> +改變('豆‧狐人', '豆‧‧‧')
>>> +改變('豆‧‧‧', '豆‧狐人')
>>> +改變('豆‧‧‧', '豆鵝‧人')
>>> +改變('豆鵝‧人', '豆‧‧‧')
>>> +改變('豆‧‧‧', '渡河失敗')
>>> +改變('豆鵝狐人', '渡河失敗')
>>> 
>>> pyDatalog.create_terms('問道')
>>> 問道(X狀態, Y狀態, P經由) <= 改變(X狀態, Z狀態) & 問道(Z狀態, Y狀態, P經由一) & (X狀態 != Y狀態) & (X狀態._not_in(P經由一 )) &  (Y狀態._not_in(P經由一)) & (P經由 == [Z狀態] + P經由一)
問道(X狀態,Y狀態,P經由) <= 改變(X狀態,Z狀態)&問道(Z狀態,Y狀態,P經由一)&!=
>>> 問道(X狀態, Y狀態, P經由) <= 改變(X狀態, Y狀態) & (P經由 == [])
問道(X狀態,Y狀態,P經由) <= 改變(X狀態,Y狀態)&==(P經由,'[]')
>>> print(問道('豆鵝狐人', '到達彼岸', P經由))
P經由                                             
------------------------------------------------
('豆‧狐‧', '豆‧狐人', '‧‧狐‧', '‧鵝狐人', '‧鵝‧‧', '‧鵝‧人')
('豆‧狐‧', '豆‧狐人', '豆‧‧‧', '豆鵝‧人', '‧鵝‧‧', '‧鵝‧人')
>>> 
>>> pyDatalog.create_terms('取道')
>>> 取道(X狀態, Y狀態, P經由) <= 取道(X狀態, Z狀態, P經由一) & 改變(Z狀態, Y狀態) & (X狀態 != Y狀態) & (X狀態._not_in(P經由一 )) &  (Y狀態._not_in(P經由一)) & (P經由 == P經由一 + [Z狀態])
取道(X狀態,Y狀態,P經由) <= 取道(X狀態,Z狀態,P經由一)&改變(Z狀態,Y狀態)&!=
>>> 取道(X狀態, Y狀態, P經由) <= 改變(X狀態, Y狀態) & (P經由 == [])
取道(X狀態,Y狀態,P經由) <= 改變(X狀態,Y狀態)&==(P經由,'[]')
>>> print(取道('豆鵝狐人', '到達彼岸', P經由))
P經由                                             
------------------------------------------------
('豆‧狐‧', '豆‧狐人', '‧‧狐‧', '‧鵝狐人', '‧鵝‧‧', '‧鵝‧人')
('豆‧狐‧', '豆‧狐人', '豆‧‧‧', '豆鵝‧人', '‧鵝‧‧', '‧鵝‧人')
>>> 

 

果然得到了『預期結果』!這難道應該意外的嘛!!不過這裡用的『問道』和『取道』兩個述詞,卻有『右項』與『左項』推導之『差別』,我們可以『歸結』說,它們的『結果』總是『相同』的嗎??