跳轉到內容

Prolog/規則

來自華夏公益教科書,自由的教科書,為自由的世界

本節討論規則,這是一種用於表示謂詞何時為真的通用方法。

到目前為止,我們還沒有真正進行任何程式設計,只是定義了物件及其屬性。Prolog 程式設計的第一步是使用**規則**。透過規則,我們說明一個謂詞為真,前提是其他謂詞為真。規則看起來像這樣

a :- b, c, d.

這意味著如果 b、c 和 d 為真,則 a 為真。如果我們有以下資料庫,

a :- b, c, d.
b.
c.
d :- e.
e.

,如果我們詢問 Prolog 是否 a 為真,

 ?- a.

Prolog 會將查詢(或目標)a 生成**子目標** b、c 和 d。它可以直接看到 b 和 c 為真,因為它們被宣告為事實,但 d 只有在 e 為真時才為真,這會導致另一個子目標 e。由於 e 也是一個事實,所以 Prolog 會回答 yes。

帶變數的規則

[編輯 | 編輯原始碼]

我們也可以使用包含項的謂詞。

car(corvette) :- haswheels(corvette), haswindows(corvette).

說明一輛有輪子和窗戶的 Corvette 是一輛汽車。這不是一個很有用的陳述,因為我們也可以簡單地宣告一輛 Corvette 是一輛汽車,用

car(corvette).

然而,我們可以在規則中使用變數。這樣,我們可以例如宣告,只要有輪子和窗戶的東西都是一輛汽車

car(A) :- haswheels(A), haswindows(A).
haswheels(corvette).
haswindows(corvette).

第一行說明,為了使 car(A) 為真,haswheels(A) 和 haswindows(A) 必須為真。如果 Prolog 被問到一輛 Corvette 是否是一輛汽車

?- car(corvette).

它會將 A 繫結到 corvette,並得到子目標**haswheels(corvette)**和**haswindows(corvette)**。如果它能證明這兩個目標都為真(它能),那麼 car(corvette) 必須為真。在程式中使用變數時,重要的是要注意,變數在它所在的句子之外沒有任何意義。如果兩個句子使用變數 A,它不是同一個變數。例如

bird(A) :- hasfeathers(A).
dog(A) :- barks(A).

第一行中的 A 只是表明謂詞 bird 的項需要與謂詞 hasfeathers 的項相同,它與第二行中的 A 無關。

現在我們可以回到我們的原始程式並新增一些規則。

human(david).
human(john).
human(suzie).
human(eliza).
man(david).
man(john).
woman(suzie).
woman(eliza).
parent(david, john).
parent(john, eliza).
parent(suzie, eliza).

father(X,Y) :- parent(X,Y), man(X).
mother(X,Y) :- parent(X,Y), woman(X).

我們可以詢問 Prolog Eliza 的父親是誰

?- father(X, eliza).

X = john ;
No

或者列出資料庫中的所有父親及其各自的孩子

?- father(Father, Child).

Father = david
Child = john ;

Father = john
Child = eliza ;

No
?- mother(Mother,Child).

Mother = suzie
Child = eliza ;

No

如果你使用過任何其他程式語言,你可能熟悉遞迴,它指的是函式呼叫自身。Prolog 特別適合遞迴,儘管在我們的例子中,它將是一個謂詞引用自身,而不是一個函式。轉到下一節,看看它是如何以及為什麼完成的。


華夏公益教科書