Haskell Djinn是如何工作的?
好吧,所以我意识到我可能会后悔一辈子,但是。。。Djinn实际上是如何工作的 文档中说它使用了一种算法,这是“LJ的一个扩展”,并指出了一篇关于LJT的冗长而混乱的论文。据我所知,这是一个由高度形式化的规则组成的庞大复杂系统,用于判断哪些逻辑陈述是正确的或错误的。但这还不能解释如何将类型签名转换为可执行表达式。想必所有复杂的形式推理都涉及到了某种程度上,但这幅图是非常不完整的Haskell Djinn是如何工作的?,haskell,types,logic,Haskell,Types,Logic,好吧,所以我意识到我可能会后悔一辈子,但是。。。Djinn实际上是如何工作的 文档中说它使用了一种算法,这是“LJ的一个扩展”,并指出了一篇关于LJT的冗长而混乱的论文。据我所知,这是一个由高度形式化的规则组成的庞大复杂系统,用于判断哪些逻辑陈述是正确的或错误的。但这还不能解释如何将类型签名转换为可执行表达式。想必所有复杂的形式推理都涉及到了某种程度上,但这幅图是非常不完整的 有点像那次我试着用BASIC写一个Pascal解释器。(别笑!我只有12岁……)我花了几个小时试图弄明白,最后我不得不
有点像那次我试着用BASIC写一个Pascal解释器。(别笑!我只有12岁……)我花了几个小时试图弄明白,最后我不得不放弃。我就是搞不懂你是如何从一个包含整个程序的巨大字符串中得到一些东西的,你可以将这些东西与已知的程序片段进行比较,从而决定实际要做什么 当然,答案是你需要写一个叫做“解析器”的东西。一旦你理解了这是什么,它做了什么,突然间一切都变得显而易见。哦,编写代码仍然不是一件小事,但想法很简单。您只需编写实际的代码。如果我在12岁的时候就知道解析器,那么也许我就不会花两个小时盯着一个空白屏幕
我怀疑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或b
对应于Haskell类型a或b
这种对应关系有时被称为“Curry-Howard同构”或“在和之后”
这个故事因哈斯克尔的非总体性而变得复杂
Djinn“只是”一个定理证明者
如果你有兴趣尝试编写一个克隆,谷歌“简单定理证明器”结果的第一页有一篇文章,描述了为LK编写一个似乎是用SML编写的定理证明器
编辑:
至于“定理如何证明是可能的?”答案是,从某种意义上说,这并不难。这只是一个搜索问题:
假设问题重述如下:我们有一组命题,我们知道如何证明S,还有一个命题,我们想证明p。我们该怎么做?
首先,我们要问:我们是否已经有了S中P的证明?如果是这样,我们可以使用它,如果不是,我们可以在P上进行模式匹配
如果这些都不起作用
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毕竟是一种证明语言
引言:
\s -> ?
或介绍
Left
Right
\a b -> (a,b)
及导言
Left
Right
\a b -> (a,b)
和消除
fst
snd
等
augustss在他的回答中说,他在Djinn中实现这一点的方式对于一个如此简单的回答来说有点乏味。不过,我敢打赌,你可以自己找到实现它的方法。在最一般的术语中,根据Curry Howard同构,类型和命题以及值和证明之间存在对应关系。Djinn使用这种通信
更具体地说,假设您想找到类型为(a,b)->(b,a)
的Haskell术语。首先,将类型转换为逻辑中的语句(Djinn使用命题逻辑,即没有量词)。逻辑语句变为(A和B)为true意味着(B和A)为true
。下一步就是证明这一点。对于命题逻辑来说,机械地证明或反驳一个陈述总是可能的。如果我们能反驳它,那就意味着(终止)Haskell中不可能有相应的项。如果我们能证明它,那么就有一个哈斯凯尔项,而且,哈斯凯尔项的结构与证明完全相同
最后一个语句必须是限定的。您可以选择使用不同的公理集和推理规则来证明该语句。如果你选择一个建设性的逻辑,那么证明和哈斯克尔项之间只有对应关系。“正常”,即经典逻辑的公理是A或(非A)
。这将对应于Haskell类型或者a(a->Void)
,但是没有这种类型的Haskell项,所以我们不能使用经典逻辑。
任何命题陈述都可以用建构主义的方法证明或反驳,这仍然是事实