跳轉到內容

Prolog/將它們放在一起

來自華夏公益教科書

本節旨在結合前幾章的知識並對其進行回顧。Prolog 首先被更詳細地解釋,忠於其基本結構,然後展示一個小型程式,該程式結合了前幾章的知識。

Prolog 程式由規則資料庫組成。這些規則被載入到編譯器中。然後使用者可以在資料庫上執行查詢。編譯器將嘗試證明查詢是正確的。

Prolog 中的一切都用邏輯來描述(Prolog 邏輯是經典謂詞邏輯或一階邏輯的變體)。從原子(最小的位)開始,這些是構成 Prolog 程式或查詢的最重要的邏輯符號。

這些由一個或多個小寫字母組成,以字母開頭。常量不是由其他 Prolog 符號組成(它是一個原子),它在 Prolog 世界中除了它本身之外不代表任何東西。將原子視為 Prolog 世界中的物件是一個好方法。它們沒有附加的含義。有效常量的示例

foo
cd_p0345
a
dirk

變數是容器。它們可以表示幾乎任何 Prolog 結構,從常量到謂詞。變數由一個或多個小寫或大寫字母組成,以大寫字母開頭。重要的是要注意,Prolog 中的變數與大多數程式語言中的變數功能不同。您不會為它們分配一個值然後使用它們,當您執行一個查詢以嘗試使查詢為真時,Prolog 會為它們分配各種值。有效變數的示例

B
Parent
Result

謂詞由一個函符(一個或多個小寫字母,以字母開頭)組成,後面可能跟著方括號之間的一些項,用逗號隔開。謂詞根據其項為真或假。有效謂詞的示例

childof(Child, Father)
predicate(dog(x), cat(Y))
architect(a_vandelay)
termless_predicate

函式的構建方式與謂詞相同,但它不是假或真,它可以代表變數可以代表的任何東西。例如,函式 sqrt(A) 將返回 A 代表的任何數字的平方根。

原子句子

[編輯 | 編輯原始碼]

原子句子是 Prolog 程式中最小的部分,可以取真或假。所有謂詞都是原子句子。一些其他 Prolog 語句,例如統一 (=) 也是原子句子。原子句子的示例

childof(george_w_b, george_b)
A = tan(B, C) + D

句子(和連線詞)

[編輯 | 編輯原始碼]

句子是 Prolog 結構,可以取真或假。原子句子當然就是句子。其他句子(即非原子句子)由透過連線詞連線在一起的原子句子組成。Prolog 中最重要的連線詞是,(“和”連線詞)。如果一個句子用逗號將兩個原子句子連線起來,那麼如果(且僅當)這兩個原子句子都為真,則該句子為真。Prolog 中的大多數句子只是一些謂詞,它們之間用逗號隔開,表示所有原子句子都必須為真,才能使該句子為真。注意:其他連線詞雖然很重要,但將在後面介紹。 句子的示例。

childof(a, b), male(a), female(b)
A = B * 3, even(A)
dog(poochie), cat(scratchy), mouse(itchy)

規則是一種特殊的句子型別。它在左邊有一個謂詞,在右邊有一個句子,用:-分隔。它以句號結束。句子是 Prolog 程式中的行。規則指出,如果句子為真,則謂詞為真。如果規則中存在變數,則對於任何使句子為真的變數例項化,謂詞都為真。沒有句子在謂詞之後(因此沒有:-)的規則稱為事實,並且被認為是真實的。Prolog 程式中的每個句子都是一個規則。

規則示例。

mother(A) :- has_child(A), female(A).
car(porsche).
equal(X, X).

項是任何代表物件的 Prolog 結構。常量和函式始終是項,變數可以代表項。

其他 Prolog 概念在詞彙表中解釋。

Prolog 編譯器

[編輯 | 編輯原始碼]

Prolog 編譯器允許使用者在規則資料庫(Prolog 程式)上執行查詢。查詢是特殊的規則型別,在:-之前沒有謂詞。一旦輸入查詢,Prolog 將在給定資料庫中的規則為真的情況下檢查它是否為真。如果查詢包含變數,Prolog 將嘗試找到一個變數例項化,使查詢為真。

這種變數例項化是基於統一過程。如果 Prolog 正在嘗試驗證查詢:- a(X).並在資料庫中遇到規則a(a).,它將把變數 X 與常量 a 統一起來。換句話說,它將把變數 X 例項化為值 a。由於 a(a) 為真,因此 Prolog 將返回 X = a 作為解決方案。統一採用兩個謂詞,並檢視是否可以使用一個來例項化另一個的變數。以下兩個謂詞統一

p(A, y)
p(z, B)
unification: A = z, B = y

這些也是如此

q(A, [y,z,C])
q(x, B)
unification: A = x, B = [y,z,C]

但是,這些不會統一

q(A, A)
q(x, y)

這是因為 A 可以是 x 或 y,但不能同時是兩者。另一方面,這些

q(A, B)
q(x, x)

將統一,因為兩個不同的變數可以繫結到同一個常量。

如果 Prolog 正在嘗試驗證查詢:- b(X).並在資料庫中遇到規則b(A) :- c(A).它將把變數 X 統一到變數 A。這兩個變數都沒有被例項化(即,沒有分配給它們值),但它們相互繫結,它們只能被例項化為相同的值。現在,Prolog 將c(A)新增到其查詢列表中以進行驗證。如果它在資料庫中遇到規則c(c) :- d.,它將(臨時)用 c 例項化 A,並嘗試驗證 d。如果 d 成功,Prolog 將返回X = c 作為原始查詢的解決方案,如果 Prolog 無法在資料庫中找到任何使 d 為真的內容,Prolog 將忘記這條規則,並嘗試以其他方式使c(A) 為真。這就是所謂的回溯

示例程式

[編輯 | 編輯原始碼]

以下程式檢查一列數字的總和是否等於零

sum_is_zero(List) :- 
	sum(List, Sum),			% Sum is the sum of the List
	Sum = 0.			% Sum needs to be 0


sum([], 0).				% the sum of an empty list is always 0 (stop predicate)

sum([FirstNumber|Tail], Sum) :-		% The list is split into its first number and its tail
	sum(Tail, TailSum),		% TailSum is the sum of the tail
	Sum is FirstNumber + TailSum.	% Add the first number to that to get the Sum of the list.

程式中的第一個規則非常簡單。它使用 sum 謂詞對列表進行求和,並檢查它是否等於零。後兩個規則構成了 sum 謂詞。第一個規則是停止謂詞。它簡單地說明空列表的和為 0。第二個規則首先將列表拆分為 FirstNumber(列表中的第一個數字,即“頭部”)和 Tail(列表的其餘部分)。它遞迴地計算尾部的和,並將第一個數字新增到尾部的和中。


一些查詢

?- sum_is_zero([1, -1]).
Yes

?- sum_is_zero([1, 1, -2]).
Yes

?- sum([-1.5, 2.7849, 3.383724], A).
A = 4.66862 ;
No

?- sum([-1.5, 2.7849, 3.383724], 42).
No

(1)以下哪些謂詞對可以統一?如果可以,請給出變數的例項化,如果不可以,請解釋原因。

1 child_of(M, P)
  child_of(martha, doug)
2 dog(A)
  dog(B)
3 f(X, Y, e, Z)
  f(a, b, d, c)
4 r(D, F)
  r(p, c(martha, D))



上一篇:數學、函式和等式 下一篇:剪下和否定

華夏公益教科書