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 特別適合遞迴,儘管在我們的例子中,它將是一個謂詞引用自身,而不是一個函式。轉到下一節,看看它是如何以及為什麼完成的。