曆史
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 等。
特點
程序與數據
在prolog程序中,是很難分清楚哪些是程序,哪些是數據的。事實上,prolog中的所有東西都有相同的形式,也就是說數據就是程序,程序就是數據。舉一個其他語言的例子:如果想用c語言編寫一個計算某個數學表達式的程序很簡單(比如:a=2+5*4),因為這是一段程序。但是如果想編寫一個計算用戶輸入的表達式的值的程序就很困難了。因為用戶輸入的是一段數據(字符串),如果想讓 c語言處理這個字符串,就需要很多方面的技術。則正是因為在c語言中,程序和數據是分開的。而在prolog就不存在這個問題,你甚至可以很輕松的編寫處理其它prolog程序的程序。
智能數據庫
prolog的原理就是關系數據庫,它是建立在關系數據庫的基礎上的。在以後的學習中你會發現它和SQL數據庫查詢語言有很多相似之處。使用prolog可以很方便的處理數據。
遞歸功能
在其它的語言中,你也許已經接觸過遞歸程序了。遞歸是一種非常簡潔的方式,它能夠有效的解決許多難題。而在prolog中,遞歸的功能得到了充分的體現,你甚至都會感到驚奇,遞歸居然又如此巨大的能力。
示例
Quicksort
/* quicksort2.pl 原始來源:http://en.wikipedia.org/wiki/Prolog */
/* quicksort()中的第二個引數帶有排序好的結果*/
/* 僅為示範,若為gprolog使用者則用内建sort等較佳 */
/* 在gprolog下之編譯例:gplc --min-size quicksort2.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; 此規則保證Smalls集=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) :- 此規則讓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
下面簡潔的排序示例可以體會到為什麼AI領域喜用Prolog:
/* 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]). /* 此規則約束所謂的排序好是指前項元素小于或等于後一項元素 */
:- initialization(q). /* 啟動q處goals */
Russell'sparadox
示範羅素悖論在Prolog下會導緻Stack Overflow:
/* tstpx.pl */
/* 羅素佯謬(羅素悖論)(皇帝新腦 羅傑.彭羅斯 p.120)會導緻不停機(使得gprolog産生 stack overflow) */
/* 在gprolog下之編譯例:gplc --min-size tstpx.pl*/
q:- px(_). /* 找尋任何可使 px() 規則成立的方式 */
px(1) :- + px(1). /* 規定此規則不成立。 i.e. 此規則為假時此規則才為真 (佯謬)*/
:- initialization(q). /* 啟動q處goal */