[英]How does Djinn work?
好的,所以我意識到我可能會在余生中后悔,但...... Djinn實際上是如何工作的?
文檔說它使用的算法是“LJ的擴展”,並指出了一篇關於LJT的長篇令人困惑的論文。 就我所知,這是一個非常復雜的高度形式化規則系統,用於確定哪些邏輯陳述是真是假。 但是,這甚至沒有開始解釋如何將類型簽名轉換為可執行表達式。 據推測,所有復雜的形式推理都是以某種方式涉及的 ,但這種情況至關重要。
這有點像我在BASIC寫一個Pascal解釋器的時候。 (不要笑!我只有十二歲......)我花了好幾個小時試圖解決它,最后我不得不放棄。 我只是無法弄清楚你是如何從包含整個程序的巨型字符串中得到的,以及你可以與已知程序片段進行比較以確定實際操作的內容。
答案當然是你需要寫一個叫做“解析器”的東西。 一旦你理解了它是什么以及它做了什么,突然一切都變得明顯 。 哦,編碼它仍然不是一件容易的事,但這個想法很簡單。 你只需要編寫實際的代碼。 如果我在十二歲時就知道解析器,那么也許我不會花兩個小時只是盯着一個空白的屏幕。
我懷疑Djinn正在做的事情從根本上說很簡單,但我遺漏了一些重要的細節,這些細節解釋了所有這些復雜的邏輯體操如何與Haskell源代碼相關...
Djinn是一個定理證明者。 看來你的問題是:定理證明與編程有什么關系?
強類型編程與邏輯關系非常密切。 特別是,ML傳統中的傳統功能語言與直覺主義命題邏輯密切相關。
口號是“程序是證明,程序證明的是它的類型”。
一般來說,你可以想到
foo :: Foo
foo
是Foo
公式的證明。 例如類型
a -> b
對應於從功能a
到b
,所以如果你有一個證明a
和的證明a -> b
你的證明b
。 因此,功能完全符合邏輯中的含義。 同樣
(a,b)
對應於連接(邏輯和)。 所以邏輯重言式a -> b -> a & b
對應於Haskell類型a -> b -> (a,b)
並且有證據:
\a b -> (a,b)
這是“和引入規則”而fst :: (a,b) -> a
和snd :: (a,b) -> b
對應於2“和消除規則”
類似地, a OR b
對應於Haskell類型Either ab
。
在Haskell Curry和William 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.