簡介
Prolog(Programming in Logic的縮寫)是一種邏輯程式語言。它建立在邏輯學的理論基礎之上, 最初被運用於
自然語言等研究領域。現已廣泛的套用在人工智慧的研究中,可以用來建造專家系統、
自然語言理解、智慧型知識庫等。同時對一些通常的應用程式的編寫也很有幫助,能夠比其他的語言更快速地開發程式,因為它的編程方法更象是使用邏輯的語言來描述程式。
歷史
Prolog語言最早由Aix-Marseille大學的Alain Colmerauer與Phillipe Roussel等人於60年代末研究開發。1972年被公認為是Prolog語言正式誕生的年份,自1972年以後,分支出多種Prolog的方言。最主要的兩種方言為Edinburgh和Aix-Marseille。最早的Prolog
解釋器由Roussel建造,而第一個Prolog
編譯器則是 David Warren編寫的。
Prolog一直在北美和歐洲被廣泛使用。日本政府曾經為了建造智慧型計算機而用Prolog來開發ICOT第五代計算機系統。在早期的機器智慧型研究領域,Prolog曾經是主要的開發工具。
80年代
Borland開發的Turbo Prolog,進一步普及了Prolog的使用。1995年確定了ISOProlog標準。
受Prolog影響的程式語言有很多,較為人所知的有:Mercury、Oz、
Erlang、Strand。
目前比較流行的實現工具包括 SWI-Prolog, Yap 等。
特點
1. prolog程式沒有特定的運行順序,其運行順序是由電腦決定的,而不是編程式的人。
從這個意義上來說,prolog程式不是真正意義上的程式。所謂程式就是按照一定的步驟運行的
計算機指令,而prolog程式的運行步驟不由人來決定。它更像一種描述型的語言,用特定的方法描述一個問題,然後由電腦自動找到這個問題的答案。舉個極端的例子,你只需要把某個數學題目告訴它,它就會自動的找到答案,而不像使用其他的語言一樣,必須人工的編制出某種算法。
2. prolog程式中沒有if、when、case、for這樣的控制流程語句
前面已經說了,程式的運行方式有電腦自己決定,當然就用不到這些控制流程的語句了。通常情況下,程式設計師不需要了解程式的運行過程,只需要注重程式的描述是否全面,不過prolog也提供了一些控制流程的方法,這些方法和其他語言中的方法有很大的區別,希望你在以後的學習當中能夠融會貫通。
3. prolog程式和數據高度統一
在prolog程式中,是很難分清楚哪些是程式,哪些是數據的。事實上,prolog中的所有東西都有相同的形式,也就是說數據就是程式,程式就是數據。舉一個其他語言的例子:如果想用
c語言編寫一個計算某個數學
表達式的程式很簡單(比如:a=2+5*4),因為這是一段程式。但是如果想編寫一個計算用戶輸入的表達式的值的程式就很困難了。因為用戶輸入的是一段數據(字元串),如果想讓c語言處理這個字元串,就需要很多方面的技術。則正是因為在c語言中,程式和數據是分開的。而在prolog就不存在這個問題,你甚至可以很輕鬆的編寫處理其它prolog程式的程式。
4. prolog程式實際上是一個智慧型資料庫
prolog的原理就是關係資料庫,它是建立在關係資料庫的基礎上的。在以後的學習中你會發現它和SQL資料庫查詢語言有很多相似之處。使用prolog可以很方便的處理數據。
5. 強大的遞歸功能
在其它的語言中,你也許已經接觸過遞歸程式了。
遞歸是一種非常簡潔的方式,它能夠有效的解決許多難題。而在prolog中,遞歸的功能得到了充分的體現,你甚至都會感到驚奇,遞歸居然有如此巨大的能力。
語法示例
表示事實:
human(kate).
human(bill).
likes(kate,bill).
——表示kate和bill是人(human),kate喜歡bill;
表示規則:
friend(X,Y):-likes(X,Y),likes(Y,X).
——表示對於兩個對象XY,如果X喜歡Y,且Y喜歡X,那么他們是朋友。
範例
Quicksort
/*quicksort2.pl,原始來源:http://en.wikipedia.org/wiki/Prolog*/
/* quicksort()中的第二個引數帶有排序好的結果 */
/* 僅為示範,若為gprolog使用者則用內建sort等較佳 */
/* 在gprolog下之編譯,例:gplc --min-size quicksort.pl*/
/* 執行 quicksort2 後會出現排序結果 [2,9,18,18,25,33,66,77] */
q:- L=[33,18,2,77,66,18,9,25], last(P,_),(quicksort(L,P,_),write(P),nl)./* 加入last/2會在印P時沒複合項 */
partition([], _,[],[])./* 此行表空集亦視為分割(分割成空集與空集)*/
partition([X|Xs], Pivot, Smalls, Bigs):-/* 原list分成Smalls與Bigs; 此rule保證Smalls集<Pivot且Bigs集>=Pivot */
( X @< Pivot ->
Smalls =[X|Rest],
partition(Xs, Pivot, Rest, Bigs)
; Bigs =[X|Rest],
partition(Xs, Pivot, Smalls, Rest)
).
quicksort([]) -->[]./* 表empty list視為排序好的list */
quicksort([X|Xs])-->/* 此行相當於quicksort([X|Xs],Start,End) :- 此rule讓Start為sorted list */
{ partition(Xs, X, Smaller, Bigger)},/* 由上行最左端元素為 Pivot */
quicksort(Smaller),[X], quicksort(Bigger)./* 此行相當於 quicksort(Smaller,Start,A),
A=[X|B], 注意首字母大寫者皆視為變數(list)
quicksort(Bigger,B,End). */
:-initialization(q)./* 啟動q處goals */
Sort
/* sortcsj.pl 原始參考:Computer Science J. Glenn Brookshear */
/* sortcsj()中的第二個引數帶有排序好的結果 */
/* 僅為示範,若為gprolog使用者則用內建sort等較佳 */
/* 在gprolog下之編譯,例:gplc --min-size sortcsj.pl */
/* 執行 sortcsj 後會出現排序結果 [2,9,18,18,25,33,66,77] */
q:- L=[33,18,2,77,18,66,9,25],(sortcsj(L,P),write(P),nl).
sortcsj(L,S):- permutation(L,S), ordered(S)./* L為原list, S為排序好的list, 此為permutation關係(built-in) */
ordered([])./* 表empty list視為排序好的list */
ordered([_|[]])./* 只有一元素之list視為排序好的list */
ordered([A|[B|T]]):- A =< B, ordered([B|T])./* 此rule約束所謂的排序好是指前項元素小於或等於後一項元素 */
:-initialization(q)./* 啟動q處goals */
Russell's paradox
/* tstpx.pl */
/* 羅素佯謬(羅素悖論)(皇帝新腦 羅傑.彭羅斯 p.120)會導致不停機(使得gprolog產生 stack overflow) */
/* 在gprolog下之編譯,例:gplc --min-size tstpx.pl */
q:- px(_)./* 找尋任何可使 px() rule 成立的方式 */
px(1):-\+ px(1)./* 規定此rule不成立。 i.e. 此rule為假時此rule才為真 (佯謬)*/
:-initialization(q)./* 啟動q處goal */
如何使用Prolog
一般而言,prolog作為數據或者邏輯處理程式而運行,配合其它程式如VC++、JAVA等的界面,由此實現帶UI互動的“智慧型”軟體,當然你所編輯出來的“智慧型”是軟體,而不能說是真正意義的人工智慧。上文說Prolog就是一個智慧型資料庫,其實不然,Prolog主要是對數據進行一種關係描述,比如張三和李四是A關係,李四和王二是B關係,A關係==B關係,那么Prolog則擅長處理這種邏輯上的數據關係,不能和
SQL混為一談,所以說,Prolog的用途是來處理數據之間關係的,而不是存儲數據本質的存在。