5

當我的朋友在學校開始學習Prolog時,我嘲笑他學習一門毫無用處的語言。然而,他向我展示了一些我從未知道的東西;我想知道這種技術來自哪裏。多功能語言中的多線程? (Prolog)

該技術是這樣的:

permutation(List) :- 
    isAMember(X, List), 
    deleteFirstElement(X, List, Substring), 
    % and so on 

在此代碼,isAMember(X, List)是如果X是在List,則返回true的函數。但是,到目前爲止X沒有被定義爲變量 - 因此程序會產生一堆新線程,其中每個可能的值爲X,這使得isAMember(X, List)爲真,並從那裏繼續。

這使我們能夠以最簡單,最優雅的方式創建一個多線程算法,我可以想像這是可能的。

所以我的問題是:這是Prolog特有的,還是所有邏輯和/或功能語言的特徵?另外,我在哪裏可以學到更多令人驚喜的多線程技術 - 這肯定是編程的未來。

+0

我想說編程就是這樣開始的!非確定性圖靈機有這個概念。 – 2010-02-01 03:51:19

+5

序言不是一個功能lanauge。它擅長解決邏輯問題。 – Francis 2010-02-01 03:54:28

回答

9

稱爲「數據記錄」的Prolog子集限於純邏輯要素(無「剪切」),原則上可以並行進行證明搜索。但是你必須小心,因爲完整的Prolog的語義對產生結果的順序非常敏感,並且一些真正的Prolog程序依賴於此。

像Haskell和清潔純函數式語言的情況好一點—它始終是安全評價並行—子表達式,但也有表現許多挑戰。如果你做了極端的並行性(每個子表達式),由於所有的開銷,你不會獲得任何性能增益。此刻的有前途的方法似乎是

  • 線程(併發的Haskell)

  • 數據並行哈斯克爾

  • 「火花」 與parseq運營商。

平行功能的東西已經存在了將近30年,人們仍然試圖使其表現良好。如果您想了解更多信息,請

  • 最近的ACM研討會論文集哈斯克爾(在這之前,Haskell的車間)

  • Arvind的麻省理工學院的工作,誰是一個偉大的先驅在此區(看看他與R.尼基爾書籍放在pH值並行編程)

3

如果我正確地記住了我的Prolog,則不會創建線程,而是會依次嘗試每個可能的X實例,並使用回溯和統一。這是很連續的。

編輯:顯然有一些實驗平行序言,例如,改革序言。但是,就我所知,這在Prolog實現中並不是常見的。

+1

這是特定於實現的。邏輯編程非常容易分離成線程,因爲它不像面向對象/過程編程那樣依賴於全局狀態。 – 2010-02-01 04:13:11

+0

是的你是對的,有一些並行化。更新了我的答案。 – ergosys 2010-02-01 05:45:49

0

isAMember(X, List)不會創建線程,prolog邏輯只是依賴於遞歸和回溯,並且是相當程序化的,除非您明確地創建線程。

對於isAMember(X, List),您正在尋找統一概念。該函數將與所有將該函數評估爲true的值相統一,在這種情況下,將包含在列表中的所有元素。然後繼續用X執行。

一旦執行到達葉,它將回溯到儘可能早的「仍然可以統一」的調用(或者說,我認爲,切入點不記得正確的術語) ,如isAMember(X, List),將X統一到下一個候選人,並恢復執行。

我敢說,如果你在邏輯上不小心,你可以輕鬆地獲得堆棧溢出。

+0

這個*「back-tracking」*聽起來非常像*「模擬多線程」* - 這是該語言的核心部分,還是僅僅是最流行的Prolog實現? – 2010-02-01 04:22:56

+2

使用變量統一的後退是prolog編程的核心。 – ergosys 2010-02-01 05:56:47

0

老實說,你已經證明似乎並沒有什麼不同,從列表理解,可能與一個foreach聯合什麼:

foreach {x | x in List} 
    deleteFirstElement(x, List, Substring) 
    // not sure what deleteFirstElement does, so... 

至於你提到isAMember可以是任何東西,列表理解可能更加複雜,也

foreach {x | x in List if x % 2 == 0} // ie, even elements of List 

按照同樣的思路,你可以做同樣的事情,而不列表理解

new_list = old_list.every { x | x % 2 == 0 } 

這可以很容易地分解成線程。