簡體   English   中英

Djinn是如何工作的?

[英]How does Djinn work?

好的,所以我意識到我可能會在余生中后悔,但...... Djinn實際上是如何工作的?

文檔說它使用的算法是“LJ的擴展”,並指出了一篇關於LJT的長篇令人困惑的論文。 就我所知,這是一個非常復雜的高度形式化規則系統,用於確定哪些邏輯陳述是真是假。 但是,這甚至沒有開始解釋如何將類型簽名轉換為可執行表達式。 據推測,所有復雜的形式推理都是以某種方式涉及的 ,但這種情況至關重要。


這有點像我在BASIC寫一個Pascal解釋器的時候。 (不要笑!我只有十二歲......)我花了好幾個小時試圖解決它,最后我不得不放棄。 我只是無法弄清楚你是如何從包含整個程序的巨型字符串中得到的,以及你可以與已知程序片段進行比較以確定實際操作的內容。

答案當然是你需要寫一個叫做“解析器”的東西。 一旦你理解了它是什么以及它做了什么,突然一切都變得明顯 哦,編碼它仍然不是一件容易的事,但這個想法很簡單。 你只需要編寫實際的代碼。 如果我在十二歲時就知道解析器,那么也許我不會花兩個小時只是盯着一個空白的屏幕。

我懷疑Djinn正在做的事情從根本上說很簡單,但我遺漏了一些重要的細節,這些細節解釋了所有這些復雜的邏輯體操如何與Haskell源代碼相關...

Djinn是一個定理證明者。 看來你的問題是:定理證明與編程有什么關系?

強類型編程與邏輯關系非常密切。 特別是,ML傳統中的傳統功能語言與直覺主義命題邏輯密切相關。

口號是“程序是證明,程序證明的是它的類型”。
一般來說,你可以想到

 foo :: Foo

fooFoo公式的證明。 例如類型

 a -> b  

對應於從功能ab ,所以如果你有一個證明a和的證明a -> b你的證明b 因此,功能完全符合邏輯中的含義。 同樣

(a,b)

對應於連接(邏輯和)。 所以邏輯重言式a -> b -> a & b對應於Haskell類型a -> b -> (a,b)並且有證據:

\a b -> (a,b)

這是“和引入規則”而fst :: (a,b) -> asnd :: (a,b) -> b對應於2“和消除規則”

類似地, a OR b對應於Haskell類型Either ab

Haskell CurryWilliam Alvin Howard之后,這種對應關系有時被稱為“Curry-Howard Isomorphism”或“ Curry-Howard Correspondence ”。

Haskell中的非整體性使這個故事變得復雜。

Djinn“只是”一個定理證明者。

如果你有興趣嘗試寫一個克隆,谷歌結果的“簡單的定理證明”的第一頁有這個文件,該文件描述了寫LK一個定理證明出現在SML編寫。

編輯:至於“定理如何證明可能?” 答案是,在某種意義上說並不難。 這只是一個搜索問題:

考慮重述的問題:我們有一套命題,我們知道如何證明S,以及我們想要證明P的命題。我們做什么? 首先,我們問:我們是否已經在S中證明了P? 如果是這樣,我們可以使用它,如果不是,我們可以在P上進行模式匹配

case P of
   (a -> b) -> add a to S, and prove b (-> introduction)
   (a ^ b)  -> prove a, then prove b (and introduction)
   (a v b)  -> try to prove a, if that doesn't work prove b (or introduction)

如果沒有這些工作

for each conjunction `a ^ b` in S, add a and b to S (and elimination)
for each disjunction `a v b` in S, try proving `(a -> P) ^ (b -> P)` (or elimination)
for each implication `a -> P` is S, try proving `a` (-> elimination)

真正的定理證明有一些聰明,但想法是一樣的。 “決策程序”的研究領域探討了為某些保證有效的公式找到證據的策略。 另一方面,“戰術”着眼於如何優化訂購證明搜索。

至於:“如何將證據翻譯成Haskell?”

正式系統中的每個推理規則對應於一些簡單的Haskell構造,因此如果你有一個推理規則樹,你可以構造一個相應的程序 - 畢竟Haskell是一種證明語言。

含義介紹:

\s -> ?

或者介紹

Left
Right

和介紹

\a b -> (a,b)

並消除

fst
snd

等等

奧古斯丁在他的回答中說,他們在Djinn實施這一點的方式對於SO答案來說有點單調乏味。 我敢打賭,你可以自己想一想如何實現它。

在最一般的術語中,根據庫里 - 霍華德的同構,類型和命題之間存在對應關系,也存在價值和證據。 Djinn使用這種信件。

更具體一點,比如你想要找到類型為(a, b) -> (b, a)的Haskell項(a, b) -> (b, a) 首先,您將類型轉換為邏輯中的語句(Djinn使用命題邏輯,即沒有量詞)。 邏輯語句(A and B) is true implies (B and A) is true 下一步是證明這一點。 對於命題邏輯,總是可以機械地證明或反駁陳述。 如果我們可以反駁它,那么這意味着在(終止)Haskell中不會有相應的術語。 如果我們可以證明它,那么就有一個類型的Haskell術語,而且,Haskell術語與證明具有完全相同的結構。

最后的陳述必須是合格的。 您可以選擇使用不同的公理和推理規則來證明該陳述。 如果你選擇一個建設性的邏輯,證明和Haskell術語之間只有一個對應關系。 “正常”,即經典邏輯具有像A or (not A)這樣的公式。 這將對應於Haskell類型Either a (a -> Void) ,但是沒有這種類型的Haskell術語,所以我們不能使用經典邏輯。 任何命題陳述都可以在建設性命題邏輯中得到證實或證明,但這種做法與經典邏輯相比更為復雜。

因此,回顧一下,Djinn通過將類型轉換為邏輯中的命題來工作,然后它使用建構邏輯的決策過程來證明命題(如果可能的話),最后證明被轉換回Haskell術語。

(在這里說明這是如何工作太痛苦了,但是在白板上給我10分鍾,你會很清楚。)

作為最后的評論你要思考:如果你有Scheme的call/cc可以實現Either a (a -> Void) 選擇一個更具體的類型,比如Either a (a -> Int)並弄清楚如何。

也許我正在看這一切都錯了。 也許所有這些形式邏輯的東西只是一種分心。 不是盯着LJT或其他什么的演繹規則,也許我應該做的就是看Haskell。

Haskell中有6種可能的表達形式? 每個人對它使用的變量都有不同的類型限制,對吧? 所以,也許我只是為函數類型中的每個參數生成一個新變量,並開始查看我可以構造的表達式。

這甚至不像你必須在蠻力搜索中生成所有可能的表達式。 如果你的參數都沒有函數類型,那么嘗試函數應用程序是沒有意義的。 如果所有參數都是多態類型變量,則case表達式不會對您有所幫助。 等等。 可用的類型告訴您哪種表達式可能有效。

如果您允許代碼調用現有的頂級函數,事情會變得更有趣。 除了多態類型的有趣范圍問題之外,還有一個問題,即確定哪些函數對您有用或哪些無效。

很明顯,我將不得不離開並思考一下......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM