天天看點

Logic Programming With Prolog學習筆記(一)

第一章:getting start

1、hello world:

write(“hello world”),nl,write(“welcome to prolog”),nl.

以.号做結束,有一系列目标(goal)組成(一般也稱為查詢query),目标之間用,号隔開,這裡的write和nl其實是内建的io謂詞,總共4個目标按順序執行,nl是開始一個新行,所有目标達成,prolog系統會輸出yes。

2、halt也是bips,用于結束prolog系統,statistics用于系統統計(cpu、記憶體等)。bips都是會産生副作用的謂詞。比如write就是會産生輸出到使用者螢幕副作用的io謂詞。

3、第一個程式,寫入下列代碼并儲存為prog1.pl:

dog(fido).

cat(felix).

animal:-dog(x).

通過consult謂詞,将該程式導入資料庫(本質上,prolog系統就是一個全局資料庫), 分析下代碼:

就是所謂事實(fact),dog和cat就是謂詞,而fido和felix是atom,這裡陳述了兩個事實:fido是一隻狗,felix是一隻貓。animal:-dog(x). 這句就是規則(rule),:-符号可以了解為如果(注:if),x是變量,這裡描述的規則就是:如果x是狗,那麼x就是動物。是以,依據事實和規則,prolog的推理系統可以推論:fido是狗,是以fido是動物:

| ?- animal(fido).

yes

顯然,根據animal規則,felix不是動物,雖然它是:

| ?- animal(felix).

no

4、prolog的注釋 /* this is a comment */

5、查詢,dog(x),查詢所有滿足謂詞dog的x,也就是找出所有的狗狗。

dog(x),cat(x).查詢所有是狗又是貓的“東西”。listing(dog),列出所有定義了謂詞dog的語句。

6、prolog的資料類型:

1)數字,number,623,+3,-.245

包括:以小寫字母開頭的字母、數字、下劃線的組合,單引号括起來的字元序列,+-*/<>=@&#特殊字元組成的序列

read(x)

dog(henry)

likes(dog(henry),y)等

5)清單,如:

[dog,cat,mypred,[a,b,c],hello]

6)其他類型,某些 prolog方言可能會有字元串類型,用于處理字元串。

第二章 語句和謂詞

一個prolog程式就是由一系列語句(clause)組成的,語句可以多行,以引文句号結束。兩種基礎語句:事實和規則。

事實語句,是由atom或者組合term構成(兩者統稱為call terms),如:

chrismas.

likes(john,mary).

規則,形式如下:

head:-t1,t2,…,tk. (k>=1)

head成為規則的頭部,也必須是call term,:-稱為頸部操作符,讀作if,而t1,t2…tk就是語句的body,它們描述了頭部的結論所需要滿足的條件。body是由一個或者多個componet組成,compont就是目标,以逗号隔開,逗号表示and的關系。從另一個角度看,head可以成為目标,body是它的子目标,規則就是為了達到目标head,必須先達到子目标t1,t2…tk。

例子:

large_animal(x):-animal(x),large(x).

go:-write(‘hello world’),nl.

謂詞的遞歸定義,分為直接和間接遞歸,例子:

likes(john,x):-likes(x,y),dog(y). 描述的規則為:john喜歡的是那種至少喜歡一隻狗的人。

loading語句,包括兩個bips:consult/1和reconsult/1,用于産生将檔案中的語句導入資料庫的副作用,兩者的差別是,reconsult會覆寫之前定義的相同謂詞,而consult不會。consult[‘prog1.pl’]可以簡化為[‘prog1.pl’].同樣,reconslt[‘prog1.pl’]可以簡寫為[-‘prog1.pl’]

變量,一開始所有的變量都是未綁定的,當目标被執行時,變量可能被綁定或者解綁定。變量存在作用域,不同語句中的同名變量沒有任何關系。

量詞,

1)全稱量詞,出現在事實或者規則head部分的變量,表示事實或者規則的該變量的所有可能值,這樣的變量成為全稱量詞,如

large_animal(x):-animal(x),large(x). 中的x。

2)存在量詞,不在事實或者規則的head部分中存在,但是在body部分中出現的量詞,僅僅為了表示該變量至少存在一個值,這樣的變量稱為存在量詞。例如:

person(dennis,zane,male,25,programmer).

man(a):-person(a,b,male,c,d).

man謂詞body部分的b,c,d變量就是存在量詞

第三章

1、這一章主要将描述prolog系統是如何滿足目标的執行。

2、prolog系統是按照順序執行目标的,每個目标都是由call term組成,每個目标都與一個相應的謂詞相關聯,謂詞的名稱稱為functor,而參數個數就是元數(arity)。prolog系統是從上到下,依據語句的head部分來比對目标,如果比對,将輸出yes,否則就是no。對于使用者定義的目标,prolog沒有找到任何事實或者規則與之比對的話,那麼就是fail。這不是什麼未知或者不确定,這個其實就是所謂的封閉世界假設(closed world assumption):任何結論如果無法從資料庫中的事實和規則中得到證明,那麼這個結論就是否定的,沒有什麼系統不确定或者未知這樣的中間位置。

3、prolog的比對算法——聯合(unification),

變量可以跟任何term聯合,其中包括了變量,其實就是變量的綁定。例如:

x=1将x與1聯合. dog(x)與dog(ferris),将x與ferris聯合。

看call terms的聯合過程:

Logic Programming With Prolog學習筆記(一)

1)如果兩個call term都是atom,隻有當它們是一樣的時候才可以聯合,比如:

test跟test聯合成功

dennis跟'dennis'聯合成功

apple跟fuck聯合失敗

2)對于組合call term的聯合,要求兩個call term有一樣的functor和arity,并且參數也要成對地聯合成功。

聯合的詳細規則如下:

1)兩個atom當且僅當它們是一樣的時候才是聯合成功的。

2)兩個組合的term聯合成功,當且僅當兩者有一樣的functor和airty,并且參數也要從左到右兩兩成對地聯合成功。

3)兩個number聯合成功,當且僅當它們是一樣的時候,例如7與7聯合成功,而7與6.9就失敗

4)兩個未綁定的變量總是聯合成功的,兩者互相綁定

5)一個未綁定變量和一個不是變量的term也總是聯合成功的,将變量綁定為該term

6)一個綁定的變量可以被認為它所綁定的值。例如

pred(x,x,man)

與pred(landon,dog,a)聯合失敗,因為在第一個參數聯合成功後,x就被認為是landon,那麼在嘗試聯合第二個參數的時候,顯然landon與dog聯合失敗。

7)兩個清單聯合成功,當且僅當它們擁有相同數目的元素,并且元素間從左到右成對地聯合成功。

8)嵌套結構按照這些規則遞歸,其他情況下的聯合都是失敗的。

4、目标的求值,兩張圖描述:

Logic Programming With Prolog學習筆記(一)
Logic Programming With Prolog學習筆記(一)

5、回溯(backtracking),回溯就是一個傳回前一個滿足的目标,尋找其他方式重新滿足該目标的過程。回溯,顧名思義就是退回去,再來過,當輸入;号,就強制prolog系統回溯以尋找更多的比對

6、目标求值的概覽:

Logic Programming With Prolog學習筆記(一)
Logic Programming With Prolog學習筆記(一)

第四章 操作符

1、通過op謂詞,可以将使用者自定義的謂詞轉成某種操作符,例如:

likes(dennis,catty).

我們更希望表達成:

dennis likes catty.

這在預設情況是不行的,通過op謂詞轉化likes謂詞成中綴操作符:

op(150,xfy,likes).

然後就可以這樣使用likes謂詞了:

op謂詞一般形式

op(操作符優先級,(xfy|xf|fy),謂詞名稱)

2、算術運算:通過内建的is/2謂詞來進行算術運算,is/2是一個内建的中綴運算符,例如:

x is 2.

x is 3,y is x+3.

出現在第二個參數的變量必須是已經綁定。+ - * /稱為算術運算符,還有一類稱為算術函數,它們并不是謂詞,例如abs/1 sqrt/1等,完整清單:

+ - * /

x//y 兩個整數的商

-x 一進制操作符

abs(x)

sqrt(x)

sin(x)

cos(x)

max(x,y)

is/2的第一個參數也可以是表達式或者數字,在此情況下,兩個參數都會被計算,如果相等,則succeeds,否則失敗。是以is/2謂詞也可以解釋為,求值看兩個參數是否可以聯合成功。如果第一個參數是變量,就将第二個參數的值綁定在該變量上,如果第一個參數是數值或者算術表達式,就比較兩個參數的值是否相等,相等則聯合成功,如果第一個參數是atom,term.list等,聯合的情況依賴于實作。永遠失敗的is/2:

x is x+1.總是失敗。

操作符的優先級與算術中的一樣,可以通過括号強制優先級。

算術比較操作符:=:=,=\=,>,>=,<,=<

3、等價操作符:

1)算術表達式比較:

e1=:=e2 成功當且僅當兩個表達式求值的結果一緻。

e1=\=e2 成功當且僅當兩個表達式求值的結果不一緻。

2)term相同比較:

term1==term2成功當且僅當trem1跟term2完全相同。

是以:

likes(x,prolog)==likes(x,prolog)相同

likes(y,prolog)==likes(y,prolog)失敗,x與y是不同的變量

3+7==6+4 失敗,兩個表達式不會被求值,顯然不同

term1 \==term2成功當且僅當trem1跟term2不同。

3)term聯合的比較:

=操作符與==類似,不同在于,term1=term2當且僅當term1和term2聯合成功的時候成功,也就是能找到某種方式綁定變量的值,來讓兩者相同。例如

6+x=6+3。成功,x綁定為3

6+4=3+7 仍然失敗

x=0,x=:=0. 成功,将x綁定為0,算術比較成功。

=的相反操作符就是\=

4、邏輯操作符:取反操作符not,表示or的;

例如:

x=0,not x is 0. 傳回no

6<3;7 is 2+5.傳回yes

文章轉自莊周夢蝶  ,原文釋出時間2008-05-28