介紹邏輯程式語言 Prolog

類別: IT
標籤: 程式語言

我是一個沉迷於程式語言的人~我喜歡學習新的語言,並在電腦上編譯他們。我的碩士學位選修的是倫敦Birkbeck大學提供的“程式設計正規化和語言”模組,並且Keith Mannock和Trevor Fenner發表了很多優秀的論文。 該模組的目的是讓學生了解各種程式設計範例之間的根本區別,以及這些範例適用於不同的程式設計問題。

這是我愛上Prolog的原因,Prolog是一種在計算語言學和一般人工智慧中大量使用的邏輯程式語言。

在這篇文章中,我將簡要介紹語言及其基本特徵。 閱讀後,你應該能夠在Prolog中編寫簡單的程式,並理解語言的基本原則

安裝

首先,讓我們開始安裝Prolog的工作。 就本文而言,我將使用SWI-Prolog(V7.2.3),請注意,Prolog版本可能有所不同。 MacOS和Windows使用者可以在這裡下載可執行檔案。 在Ubuntu或任何其他基於Debian的發行版上,您可以使用apt-get命令。

sodu apt-get update && \sodu apt-get install swi-prolog

或者,您也可以使用官方docker映象。

docker run -it swipl:stable# or for the most recent version use the latest tagdocker run -it swipl:latest

現在我們設定完配置以後可以進入Prolog。 然而,在獲得技術之前,它背後的動機是什麼?

學習Prolog(或任何其他語言)的動機是什麼

為什麼你懶得學習Prolog呢? 那麼,有幾個原因,但在這一點上,我反而要提到“實用型程式設計師”。

小提示#8“定期投入您的知識組合”:

每年至少學習一種新語言。 不同的語言以不同的方式解決相同的問題。 通過學習幾種不同的方法,可以幫助你開闊思路,避免陷入困境。 此外,而且網際網路上免費提供的大量軟體和資料,現在學習多種語言要容易得多。

話雖如此,試著解決一個數獨謎題,例如在Java或C~或者Prolog中,你可以用簡單的幾行程式碼來完成。

但是,在我們深入到Prolog之前,先來想一下“邏輯程式設計”是什麼?

邏輯程式設計

說出你想要什麼,而不是你想要做什麼。

邏輯程式設計是一個程式設計正規化,它要有數學邏輯的基礎。 與Java或C語言相比,使用Prolog等邏輯程式語言編寫的程式不是由指令序列組成,而是由一系列公理或定義物件之間關係的規則組成。 他們也遵循宣告而不是強制性的方法。 但是,這是什麼意思?

指令式程式設計和宣告式程式設計的區別

讓我們想一下“點一杯咖啡”的比喻,就像我們在程式頁面上一樣。 想象一下,當你走進你最喜歡的咖啡店,你想點咖啡。

必要的流程:
1.進入咖啡店
2.排隊等候時咖啡師詢問你想要點什麼
3.點咖啡
4.好的,我要打包,謝謝
5.支付費用
6.出示您的會員卡以收集積分

7.收好你的小票,走出去

宣告式的方法:
1.打包一大杯拿鐵
所以,不是通過像x或y這樣的步進指令(命令性的),而是告訴系統你需要什麼,並讓它試著想出一個解決方案(宣告式程式設計)。

關於Prolog

Prolog基於Horn子句(一階邏輯的子集),它可能是邏輯程式設計系列中最著名的邏輯程式語言。 這是Alain Colmerauer,Phillipe Roussel(艾克斯 - 馬賽大學)和愛丁堡大學的Robert Kowalski的進行了相當長一段時間得合作專案,。 它的第一個版本在1972年出現,如Smalltalk和C。是“Programmation en logique”(法語為邏輯程式設計)的縮寫。

Prolog在定理證明,專家系統,自然語言處理和人工智慧領域(特別是IBM的Watson2)都有很大的影響力。 這也影響了Erlang程式語言的發展。

語言結構
有一點特別吸引我的是它簡單的執行模型。 Prolog有四個構建塊,邏輯或,邏輯和,項重寫和聯合。通過結合這四個塊,我們可以執行任何我們關心的計算問題。

Prolog和SQL一樣,有兩個主要方面,一個是表示資料,另一個是查詢。邏輯程式設計的基本結構,項和語句,都是從邏輯方法上繼承下來的。有三個基本的陳述:

事實是關於問題領域的基本論斷(例如“蘇格拉底是一個人”)

規則是對領域事實的推論(例如“所有人都是凡人”)

查詢是關於這個領域的問題(例如“蘇格拉底是凡人嗎?”)

事實規則儲存在知識庫中,Prolog編譯器將其轉換成更有效的查詢形式。當我們“提出”一個問題時,Prolog通過事實和規則的“資料庫”進行了詳盡的搜尋,直到找到結果,並在內部使用回溯。

基本事實和查詢

Prolog有一個簡單的語法。 你會很快掌握這幾條規則。 讓我們從早些時候將蘇格拉底的例子轉變成一個實際的Prolog程式,並分析編譯器內部的東西。

man(socrates).

mortal(X) :- man(X).

?- mortal(socrates).

第一行寫為“蘇格拉底是人”,它是一個基本邏輯子句,這是一個簡單的事實。 第二行是一條規則,並且轉化為:“如果X是人,則X是凡人”,或者“所有的人都是凡人”。這個規則用於確定它的輸入X何時是“凡人”。 規則是語言的一個關鍵概念,並允許我們對物件及其關係作一般性陳述。 它們由一個由一個類似十字旋轉門的符號連線的頭部和身體組成:-(發音為“如果”)。 第三行的內容是:“蘇格拉底是否是凡人?” ?- “提出一個Prolog查詢結果”。

如果您仔細閱讀了這三行程式碼,您可能已經觀察到了有區分大小寫的情況。 與大多數其他語言相比,Prolog中的大小寫區分非常重要。 以小寫字元開頭的字串是不可變的,稱為原子,您可以將它們與Ruby中的符號型別進行比較。 以大寫字母或下劃線開始的字串是變數,可以更改它們的值。 在我們的例子中,socrates是一個原子,大寫的X是一個變數。 另外請注意,每個子句後面的句號都是強制性的。

讓我們用先前定義的知識庫向Prolog提出另一個問題。

?- mortal(plato).

當然,Prolog會迴應錯誤的,因為我們的知識庫沒有plato的定義。 那麼下一個問題呢?

?- mortal(X).

也就是說,“誰(X)是凡人的?”。 Prolog會迴應X = socrates,並將Socrates繫結到變數X.你是否注意到了命令式和宣告式風格之間的巨大差異?

與指令式程式設計的相比較,我們沒有向程式提供任何指令來定義變數。我們剛才問程式一個問題,它自動繫結一個值給我們的變數X!這個將變數與專案相匹配的過程稱為統一,這也恰恰是邏輯程式設計的優勢所在。

聯合

賦值語句是大多數指令式程式設計語言的基礎。在Java或Ruby中,表示式x = 10意味著將值10分配給變數x。兩種語言的變數都是可變的,這意味著x = 20會將值20重新賦值給變數,並且之前的值會丟失。在Prolog和其他宣告性語言中,變數只有在第一次被繫結和聯合之後才是“可變的”。因此,我們使用聯合這個術語:聯合或成為整體的一個過程。我們通常可以在用於啟用型別推斷的命令式語言中來找到聯合的應用的例子。

介紹邏輯程式語言 Prolog原文請看這裡