可以使用正确性属性证明/模型检查/验证Haskell函数吗?

时间:2010-11-02 13:12:40

标签: testing haskell functional-programming formal-methods formal-verification

继续讨论:Are there any provable real-world languages?

我不了解你,但我厌倦了编写我无法保证的代码。

在询问了上述问题并得到了非凡的回应之后(全部谢谢!)我决定缩小我对Haskell的可靠,实用的方法的搜索范围。我之所以选择Haskell是因为它实际上很有用(为此编写了many web frameworks,这似乎是一个很好的基准) AND 我认为它足够严格,functionally,它可能是可证明的,或者至少允许测试不变量。

这就是我想要的(并且一直无法找到)

我想要一个可以查看Haskell函数的框架,添加,用psudocode编写:

add(a, b):
    return a + b

- 并检查某些常量是否保持每个执行状态。我更喜欢一些正式的证据,但我会选择像模特检查员这样的东西 在此示例中,不变量将是给定值 a b ,返回值始终为总和 a + b

这是一个简单的例子,但我不认为这样的框架不可能存在。对于可以测试的函数的复杂性肯定会有一个上限(函数的10个字符串输入肯定会花费很长时间!)但这会鼓励更仔细地设计函数,并且与使用其他正式函数没有什么不同方法。想象一下,使用Z或B,当您定义变量/集时,您可以确保为变量提供尽可能小的范围。如果您的INT永远不会超过100,请确保将其初始化为!这些技术和正确的问题分解应该 - 我认为 - 允许对像Haskell这样的纯函数语言进行令人满意的检查。

我还没有 - 使用正式方法或Haskell非常有经验。让我知道我的想法是否合理,或者你认为haskell不合适?如果您建议使用其他语言,请确保通过“has-a-web-framework”测试,并阅读原始question: - )

11 个答案:

答案 0 :(得分:58)

答案 1 :(得分:19)

可能与你要求的最接近的是Haskabelle,这是一个与证明助手Isabelle一起提供的工具,它可以将Haskell文件转换为Isabelle理论并让你证明它们的内容。据我所知,这个工具是在HOL - ML - Haskell项目中开发的,the documentation page包含了有关背后理论的一些信息。

我对这个项目并不十分熟悉,我不太了解它已经做了什么。但我知道Brian Huffman一直在玩这些东西,查看他的论文和谈话,他们应该包含相关内容。

答案 2 :(得分:17)

我不确定你所要求的是否真的会让你开心。 : - )

模型检查通用语言几乎是不可能的,因为模型必须是特定于域的,才能实用。由于哥德尔的不完备性定理,在一个充分表达的逻辑中,只有没有自动查找证明的方法

这意味着您必须自己编写校样,这就提出了这样的努力是否值得花费时间的问题。当然,这种努力创造了一些非常有价值的东西,即确保你的程序是正确的。问题不在于这是否是必须的,而是花费的时间是否太大。关于证明的事情是,虽然您可能“直观地”理解您的程序是正确的,但通常很难难以将此理解正式化作为证明。直观理解的问题在于它极易受到意外错误(错别字和其他愚蠢错误)的影响。这是编写正确程序的基本困境。

因此,关于程序正确性的研究就是为了更容易地形式化证明并自动检查它们的正确性。编程是“易于形式化”的一个组成部分;以易于推理的风格编写程序非常重要。目前,我们有以下频谱:

  • 像C,C ++,Fortran,Python这样的命令式语言:很难在这里形式化任何东西。单元测试和一般推理是获得至少一些保证的唯一方法。静态类型只捕获琐碎的错误(比没有捕获它们好得多!)。

  • 纯粹的函数式语言,如Haskell,ML:表达式系统有助于捕获非平凡的错误和错误。我会说,手工证明正确性对于大约200行的片段是切实可行的。 (例如,我为我的operational package做了证明。)Quickcheck测试是形式化证明的廉价替代品。

  • 依赖类型语言和证明助手,如Agda,Epigram,Coq:通过证明形式化和发现的自动化帮助,可以证明整个程序正确无误。然而,负担仍然很高。

在我看来,编写正确程序的当前好处是纯函数式编程。如果生活依赖于你的程序的正确性,你最好更高一级并使用证明助理。

答案 3 :(得分:5)

听起来你想要ESC / Haskell:http://research.microsoft.com/en-us/um/people/simonpj/papers/verify/index.htm

哦,Agda现在确实有一个Web框架(至少是概念证明):http://www.reddit.com/r/haskell/comments/d8dck/lemmachine_a_web_framework_in_agda/

答案 4 :(得分:4)

你看过quickcheck吗?它可能会提供您需要的一些东西。

http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck

答案 5 :(得分:3)

你看似简单的例子,添加(a,b),实际上很难验证 - 浮点,溢出,下溢,中断,是编译器验证,是硬件验证等等。

Habit是Haskell的简化方言,允许证明程序属性。

Hume是一种包含5个级别的语言,每个级别都更有限,因此更容易验证:

Full Hume
  Full recursion
PR−Hume
  Primitive Recursive functions
Template−Hume
  Predefined higher−order functions
  Inductive data structures
  Inductive  Non−recursive first−order functions
FSM−Hume
  Non−recursive data structures
HW−Hume
  No functions
  Non−recursive data structures

当然,目前用于证明程序属性的最流行的方法是单元测试,它提供了强有力的定理,但这些定理过于具体。 "Types Considered Harmful", Pierce, slide 66

答案 6 :(得分:3)

看看Zeno。引用维基页面:

  

Zeno是Haskell程序属性的自动证明系统;由William Sonnex,Sophia Drossopoulou和Susan Eisenbach在伦敦帝国理工学院开发。它的目的是为任何输入值解决两个Haskell项之间相等的一般问题。

     

目前可用的许多程序验证工具都是模型检查的多样性;能够非常快速地遍历一个非常大但有限的搜索空间。这些非常适合具有大型描述的问题,但没有递归数据类型。另一方面,Zeno旨在通过无限搜索空间归纳地证明属性,但仅限于那些具有小而简单规范的属性。

答案 7 :(得分:2)

当然可以正式证明Haskell程序的某些属性。我必须在我的FP考试中这样做:给出两个表达式,证明它们表示相同的功能。由于Haskell是图灵完备的,所以通常不可能这样做,因此任何机械证明器都必须是证明助手(用户指导的半自动)或模型检查器。

有朝这个方向的尝试,例如, P-logic: property verification for Haskell programsProving the correctness of functional programs using Mizar。两者都是描述方法而不是实现的学术论文。

答案 8 :(得分:1)

答案 9 :(得分:1)

工具AProVE(至少)能够证明Haskell程序的终止,这是证明正确性的一部分。 有关详细信息,请参阅this papershorter version)。

除此之外,您可能对Dependent Types感兴趣。在这里,类型系统被扩展并用于使错误的程序无法实现。

答案 10 :(得分:1)

您可以使用工具hs-to-coq将Haskell主要自动转换为Coq,然后使用Coq证明助手的全部功能来验证您的Haskell代码。有关更多信息,请参阅论文https://arxiv.org/abs/1803.06960https://arxiv.org/abs/1711.09286