現在我們的遊戲中已經有了一些事實,使用prolog的直譯器調入此程式後,我們就可以對這些事實進行查詢了。本章和下一章中的prolog程式只包括事實,我們要學會如何對這些事實進行查詢。
prolog的查詢工作是靠模式匹配完成的。查詢的模板叫做目標(goal)。如果有某個事實與目標匹配,那麼查詢就成功了,prolog的直譯器會回顯'yes.'。如果沒有匹配的事實,查詢就失敗了,直譯器回顯'no.'。
我們把prolog的模式匹配工作叫做聯合(unification)。當資料庫中只包括事實時,以下三個條件是使聯合成功的必要條件:
1. 目標謂詞名與資料庫中的某個謂詞名相同。
2. 這兩個謂詞的引數數目相同。
3. 所有的引數也相同。
在介紹查詢之前,讓我們回顧一下上一章所編寫的prolog程式。
room(kitchen).
room(office).
room(hall).
room('dining room').
room(cellar).
door(office, hall).
door(kitchen, office).
door(hall, 'dining room').
door(kitchen, cellar).
door('dining room', kitchen).
以上是我們的「尋找nani」中的所有事實。把這段程式調入prolog直譯器中後就可以開始進行查詢了。
我們的第乙個問題是:office在本遊戲中是不是乙個房間。
?-room(office).prolog回答yes,因為它在資料庫中找到了room(office).這個事實。我們繼續問:有沒有attic這個房間。yes.
?-room(attic).prolog回答no,因為它在資料庫中找不到room(attic).這個事實。同樣我們還可以進行如下的詢問。no.
你看prolog懂我們的意思呢,它知道蘋果在廚房裡,並且知道廚房不在蘋果裡。但是下面的詢問就出問題了。
?- door(office, hall).由於我們定義的門是單方向的,結果遇到了麻煩。yes?- door(hall, office).
no
在查詢目標中我們還可以使用prolog的變數。這種變數和其他語言中的不同。叫它邏輯變數更合適一點。變數可以代替目標中的一些引數。
變數給聯合操作帶來了新的意義。以前聯合操作只有在謂詞名和引數都相同時才能成功。但是引入了變數之後,變數可以和任何的條目匹配。
當聯合成功之後,變數的值將和它所匹配的條目的值相同。這叫做變數的繫結(binding)。當帶變數的目標成功的和資料庫中的事實匹配之後,prolog將返回變數繫結的值。
由於變數可能和多個條目匹配,prolog允許你察看其他的繫結值。在每次prolog的回答後輸入「;」,可以讓prolog繼續查詢。下面的例子可以找到所有的房間。「;」是使用者輸入的。
?- room(x).最後的no表示找不到更多的答案了。x = kitchen ;
x = office ;
x = hall ;
x = 'dining room' ;
x = cellar ;
no
下面我們想看看kitchen中都有些什麼。(變數以大寫字母開始)
我們還可以使用兩個變數來查詢所有的物體及其位置。
?- location(thing, place).查詢的工作原理當prolog試圖與某乙個目標匹配時,例如:location/2,它就在資料庫中搜尋所有用location/2定義的子句,當找到一條與目標匹配時,它就為這條子句作上記號。當使用者需要更多的答案時,它就從那條作了記號的子句開始向下查詢。thing = desk
place = office ;
thing = flashlight
place = desk ;
...no
我們來看乙個例子,使用者詢問:location(x,kitchen).。prolog找到資料庫中的第一條location/2子句,並與目標比較。
目標子句#1
location(x, kitchen)
location(desk, office)
匹配失敗,因為第二個引數不同,乙個是kitchen,乙個是office。於是prolog繼續比較第二個子句。
目標子句#2
location(x, kitchen)
這回匹配成功,而變數x的值就被繫結
如果使用者輸入分號(;),prolog就開始尋找其他的答案。首先它必須釋放(backtracking)。在本例中就是第三條子句。
目標子句#3
location(x, kitchen)
location(flashlight, desk)
匹配失敗,直到第六條子句時匹配又成功了 。
目標子句#6
location(x, kitchen)
location(broccoli, kitchen)
結果變數x又被繫結為broccoli,直譯器顯示:
x = broccoli ;再度輸入分號,x又被解放,開始新的搜尋。又找到了:
x = crackers ;這回再沒有新的子句能夠匹配了,於是prolog回答no,表示最後一次搜尋失敗了。
noprolog的目標有四個埠用來控制執行的流程:呼叫(call)、退出(exit)、重試(redo)以及失敗(fail)。一開始使用call埠進入目標,如果匹配成功就到了exit埠,如果失敗就到了fail埠,如果使用者輸入分號,則又從redo埠進入目標。下圖表示了目標和它的四個埠。
每個埠的功能如下:
下面列出了除錯location(x,kitchen).時的情況。括號中的數字表示當前正在考慮的子句。
在prolog的直譯器中輸入,
?- debug.就可以開始除錯你的程式了。
Prolog教程 4 簡單查詢
goal 查詢目標 unification 匹配工作三個必要哦條件1.目標謂詞一致 2.謂詞引數數量一致 3.所有引數相同 查詢繼續 查詢4個埠 1.call 開始查詢 2.exit 成功查詢到結果,並繫結到變數 3.redo 從上次成功查詢處之後繼續查絢,先釋放變數 4.fail 查詢失敗退出 現...
Spring AOP中文教程
僅僅用配置檔案便可把程式的每一部分組裝起來。四個bean定義的次序並不重要。我們現在有了乙個advice,乙個包含了正規表示式pointcut的advisor,乙個主程式類和乙個配置好的介面,通過工廠ctx,這個介面返回自己本身實現的乙個引用。beanimpl和testbeforeadvice都是直...
Beautiful Soup 中文教程
beautiful soup 是乙個處理python html xml的模組,功能相當強勁,最近仔細的看了一下他的幫助文件,終於看明白了一些。準備好好研究一下,順便將beautiful soup的一些用法整理一下,放到這個wiki上面,那個文件確實不咋地。beautiful soup 中文教程 的官...