Prolog 單調敘述邏輯設計語言

當我在大學一年級時,望著以下一段 C 語言程式碼發楞著:


struct { int a; int b; } ab;
int c[] = {1, 2, 3, 4, 5};

當時,我想著:有沒有一種語言或程式的運作方式,我說 a, b 有個關係是 a < b ,又知道 a, b 的值都是在陣列 c 之內的任何一個數字,那麼,假如我改變 a 的值, b 的值就會跟著改變。

當時,在我所讀的學系,沒有人幫我回答這一題。

後來我給自己找到了一個答案: Prolog 。


在邏輯與知識系統的分類上, Prolog 稱為「單調邏輯系統」 (monotonous logical system) ,特性是以封閉世界觀 (closed-world assumption) 來斷定事情。然而,因為封閉世界觀是一種偏頗的判斷方式,以黑白分明、二分法來斷定真偽,因此當我們寫 Prolog 程式時,需要做相當多的工作,依賴許多性質的判斷為真,將多項判斷為真的斷言套圈在同一件事實上,才能夠細緻地確認那是一件符合我們判斷的事實。

Prolog 語言是為了描述敘述邏輯語句。而 Prolog 語言的運作環境,則是能依循著敘述邏輯的語意,確定因為變數與資料結合而產生真值 (True) ,因此我們使用這種可信的資料。或者,因為變數與資料無法結合而產生偽值 (False) ,因此我們因資料不可信,而不使用這種資料。



perm([A, B], Set) :-
member(A, Set),
member(B, Set).

以上這段 Prolog 程式,描述 A, B 二個元素個別是 Set 裡的值。程式執行起來如下圖:

擷取

如上圖,可見到 A, B 分別可能是 {a, b, c} 其中一個值,並且 A, B 兩者可能相同。如果將 A = B 的情況除去,則剩餘其他的情況則是 {a, b, c} 取二個元素的排列。


perm([A, B], Set) :-
member(A, Set),
member(B, Set),
A \= B.

新的程式執行結果如下圖。

擷取.PNG

接著,我想要做 N 個元素集合取 M 個元素排列。


隨便給你一列資料,要檢查這些資料中任何二個元素都不相同,也就是在這一列資料中,沒有重複的元素。


not_redudant([]).
not_redudant([H|T]) :-
not(member(H, T)),
not_redudant(T).

由以上程式檢查非重複的概念,換做思考 N 個元素集合取 M 個元素排列,有些雷同。


perm([], _Set).
perm([H|T], Set) :-
member(H, Set),
perm(T, Set),
not(member(H, T)).


人的腦袋,就像邏輯一樣地活生生。例如,如以上例子,當我們使用如下圖的詢問方式:

擷取.PNG

由於我在 perm/2 中,使用了 not(member(H, T)) 根據值的內容決定元素的重複,所以當我所給的元素集合為 {a, b, b} 此帶有重複元素的資料時,所獲得的排列情況少了一些數量。

為此,我加上二段程式: zip/3 用來給資料元素打上編號或標籤,而 unzip/3 用來除去編號或標籤。程式與執行方式如以下圖片所示。由執行結果可見,所產生帶有重複值的排列較具有意義。

擷取.PNG

廣告

About 黃耀賢 (Yau-Hsien Huang)

熱愛 Erlang ,並且有相關工作經驗。喜歡程式語言。喜歡邏輯。目前用 Python 工作。
本篇發表於 Prolog, Uncategorized。將永久鏈結加入書籤。