简体   繁体   English

有没有可证明的现实世界语言? (斯卡拉?)

[英]Are there any provable real-world languages? (scala?)

I was taught about formal systems at university, but I was disappointed how they didn't seem to be used in the real word. 我在大学里被教过关于正规系统的知识,但是我对如何在真实单词中似乎没有使用它们感到失望。

I like the idea of being able to know that some code (object, function, whatever) works, not by testing, but by proof . 我喜欢这样的想法:能够知道某些代码(对象,函数,任何东西)起作用,而不是通过测试,而是通过证明

I'm sure we're all familiar with the parallels that don't exist between physical engineering and software engineering (steel behaves predictably, software can do anything - who knows!), and I would love to know if there are any languages that can be use in the real word (is asking for a web framework too much to ask?) 我确信我们都熟悉物理工程和软件工程之间不存在的相似之处(钢铁的行为可预测,软件可以做任何事情-谁知道!),我很想知道是否有任何语言可以可以用真实的语言使用(要求太多的Web框架吗?)

I've heard interesting things about the testability of functional languages like scala. 我听说过有关诸如scala之类的功能语言的可测试性的有趣事情。

As software engineers what options do we have? 作为软件工程师 ,我们有哪些选择?

Yes, there are languages designed for writing provably correct software. 是的,有些语言旨在编写可证明正确的软件。 Some are even used in industry. 有些甚至用于工业。 Spark Ada is probably the most prominent example. Spark Ada可能是最突出的例子。 I've talked to a few people at Praxis Critical Systems Limited who used it for code running on Boings (for engine monitoring) and it seems quite nice. 我已经与Praxis Critical Systems Limited的一些人进行了交谈,他们将其用于在Boings上运行的代码(用于引擎监视),这看起来还不错。 (Here is a great summary / description of the language .) This language and accompanying proof system uses the second technique described below. (以下是该语言的精彩摘要/说明 。)此语言及其随附的证明系统使用下面描述的第二种技术。 It doesn't even support dynamic memory allocation! 它甚至不支持动态内存分配!


My impression and experience is that there are two techniques for writing correct software: 我的印象和经验是,有两种技术可以编写正确的软件:

  • Technique 1: Write the software in a language you're comfortable with (C, C++ or Java for instance). 技术1:用您喜欢的语言(例如C,C ++或Java)编写软件。 Take a formal specification of such language, and prove your program correct. 采取这种语言的正式规范,并证明您的程序正确。

    If your ambition is to be 100% correct (which is most often a requirement in automobile / aerospace industry) you'd be spending little time programming, and more time proving. 如果您的目标是100%正确(这在汽车/航空航天业通常是必需的),那么您将花费很少的时间进行编程,而花费更多的时间进行证明。

  • Technique 2: Write the software in a slightly more awkward language (some subset of Ada or tweaked version of OCaml for instance) and write the correctness proof along the way. 技术2:以一种稍显笨拙的语言(例如,Ada的某些子集或OCaml的调整版本)编写软件,并在编写过程中编写正确性证明。 Here programming and proving goes hand in hand. 在这里编程和验证是齐头并进的。 Programming in Coq even equates them completely! 在Coq中编程甚至完全等同于它们! (See the Curry-Howard correspondence ) (请参阅Curry-Howard通讯

    In these scenarios you'll always end up with a correct program. 在这些情况下,您总是会得到正确的程序。 (A bug will be guaranteed to be rooted in the specification.) You'll be likely to spend more time on programming but on the other hand you're proving it correct along the way. (一定会保证错误会根植于规范中。)您可能会花更多的时间在编程上,但另一方面,您会在此过程中证明它是正确的。

Note that both approaches hinges on the fact you have a formal specification at hand (how else would you tell what is correct / incorrect behavior), and a formally defined semantics of the language (how else would you be able to tell what the actual behavior of your program is). 请注意,这两种方法都取决于您手头有一个正式的规范(您将如何分辨正确/不正确的行为)以及该语言的形式化语义(您将如何分辨实际的行为)您的程序是)。

Here are a few more examples of formal approaches. 这是正式方法的更多示例。 If it's "real-world" or not, depends on who you ask :-) 是否是“真实世界”,取决于您问的人:-)

I know of only one "provably correct" web-application language : UR . 我只知道一种“证明正确的” Web应用程序语言UR A Ur-program that "goes through the compiler" is guaranteed not to: 确保“经过编译器”的Ur程序不会:

  • Suffer from any kinds of code-injection attacks 遭受任何形式的代码注入攻击
  • Return invalid HTML 返回无效的HTML
  • Contain dead intra-application links 包含无效的应用程序内链接
  • Have mismatches between HTML forms and the fields expected by their handlers HTML表单与其处理程序期望的字段之间不匹配
  • Include client-side code that makes incorrect assumptions about the "AJAX"-style services that the remote web server provides 包括客户端代码,这些代码对远程Web服务器提供的“ AJAX”样式的服务做出了错误的假设
  • Attempt invalid SQL queries 尝试无效的SQL查询
  • Use improper marshaling or unmarshaling in communication with SQL databases or between browsers and web servers 在与SQL数据库或浏览器与Web服务器之间的通信中使用不正确的封送或封送处理

In order to answer this question, you really need to define what you mean by "provable". 为了回答这个问题,您确实需要定义“可证明”的含义。 As Ricky pointed out, any language with a type system is a language with a built-in proof system which runs every time you compile your program. 正如Ricky所指出的那样,任何带有类型系统的语言都是带有内置证明系统的语言,该语言在每次编译程序时都会运行。 These proof systems are almost always sadly impotent — answering questions like String vs Int and avoiding questions like "is the list sorted?" 这些证明系统几乎总是可悲的无用-回答诸如String vs Int问题,避免诸如“列表是否已排序?”之类的问题。 — but they are proof systems none-the-less. -但是它们仍然是证明系统。

Unfortunately, the more sophisticated your proof goals, the harder it is to work with a system which can check your proofs. 不幸的是,您的证明目标越复杂,使用可以检查您的证明的系统就越难。 This escalates pretty quickly into undecidability when you consider the sheer size of the class of problems which are undecidable on Turing Machines. 考虑到图灵机无法确定的问题类别的绝对规模,这很快就会升级为不可确定性。 Sure, you can theoretically do basic things like proving the correctness of your sorting algorithm, but anything more than that is going to be treading on very thin ice. 当然,从理论上讲,您可以做一些基本的事情,例如证明排序算法的正确性,但除此之外,还有其他任何工作。

Even to prove something simple like the correctness of a sorting algorithm requires a comparatively sophisticated proof system. 即使要证明诸如排序算法的正确性之类的简单信息,也需要相对复杂的证明系统。 (note: since we have already established that type systems are a proof system built into the language, I'm going to talk about things in terms of type theory, rather than waving my hands still more vigorously) I'm fairly certain that a full correctness proof on list sorting would require some form of dependent types, otherwise you have no way of referencing relative values at the type level. (注意:由于我们已经确定类型系统是语言中内置的证明系统,因此,我将用类型理论来谈论事物,而不是更加用力地挥挥手))列表排序的完全正确性证明将需要某种形式的依赖类型,否则您将无法在类型级别上引用相对值。 This immediately starts breaking into realms of type theory which have been shown to be undecidable. 这立即开始闯入类型理论领域,这些领域已被证明是无法确定的。 So, while you may be able to prove correctness on your list sorting algorithm, the only way to do it would be to use a system which will also allow you to express proofs which it cannot verify. 因此,虽然您可以证明列表排序算法的正确性,但是唯一的方法是使用一个系统,该系统还可以让您表达无法验证的证据。 Personally, I find this very disconcerting. 我个人觉得这很令人不安。

There is also the ease-of-use aspect which I alluded to earlier. 我前面也提到了易用性。 The more sophisticated your type system, the less pleasant it is to use. 类型系统越复杂,使用起来就越不愉快。 That's not a hard and fast rule, but I think it holds true for the most part. 这不是一成不变的规则,但我认为这在大多数情况下都是正确的。 And as with any formal system, you will often find that expressing the proof is more work (and more error prone) than creating the implementation in the first place. 与任何正式系统一样,您通常会发现,表达证据比首先创建实现要花费更多的工作(并且更容易出错)。

With all that out of the way, it's worth noting that Scala's type system (like Haskell's) is Turing Complete, which means that you can theoretically use it to prove any decidable property about your code, provided that you have written your code in such a way that it is amenable to such proofs. 综上所述,值得注意的是,Scala的类型系统(如Haskell的系统)是Turing Complete,这意味着从理论上讲 ,只要您以这种方式编写代码,就可以使用它来证明有关代码的任何可确定的属性。这种证明适合的方式。 Haskell is almost certainly a better language for this than Java (since type-level programming in Haskell is similar to Prolog, while type-level programming in Scala is more similar to SML). Haskell几乎可以肯定是比Java更好的语言(因为Haskell中的类型级编程类似于Prolog,而Scala中的类型级编程更类似于SML)。 I don't advise that you use Scala's or Haskell's type systems in this way (formal proofs of algorithmic correctness), but the option is theoretically available. 我不建议您以这种方式使用Scala或Haskell的类型系统(算法正确性的形式证明),但是该选项理论上是可用的。

Altogether, I think the reason you haven't seen formal systems in the "real world" stems from the fact that formal proof systems have yielded to the merciless tyranny of pragmatism. 总的来说,我认为您没有在“现实世界”中看到正式系统的原因是因为正式证明系统已经屈服于实用主义的无情专制。 As I mentioned, there's so much effort involved in crafting your correctness proofs that it's almost never worthwhile. 正如我提到的那样,在制作正确性证明方面需要花费很多精力,几乎是不值得的。 The industry decided a long time ago that it was easier to create ad hoc tests than it was to go through any sort of analytical formal reasoning process. 业界早就决定,创建临时测试比进行任何形式的分析形式推理过程要容易得多。

Typed languages prove the absence of certain categories of fault. 类型化的语言证明不存在某些类别的错误。 The more advanced the type system, the more faults they can prove the absence of. 类型系统越先进,就可以证明没有更多的故障。

For proof that a whole program works, yes, you're stepping outside the boundaries of ordinary languages, where mathematics and programming meet each other, shake hands and then proceed to talk using Greek symbols about how programmers can't handle Greek symbols. 为证明整个程序有效,是的,您要走出普通语言的界限,数学和编程在此相遇,握手,然后使用希腊符号谈论程序员如何无法处理希腊符号。 That's about the Σ of it anyway. 无论如何,这就是它的Σ。

You're asking a question a lot of us have asked over the years. 您正在问一个问题,这些年来我们很多人都问过。 I don't know that I have a good answer, but here are some pieces: 我不知道我有一个很好的答案,但是这里有一些内容:

  • There are well-understood languages with the possibility of being proven in use today; 有一些易于理解的语言,有可能在今天被证明使用。 Lisp via ACL2 is one, and of course Scheme has a well-understood formal definition as well. 通过ACL2进行Lisp就是一个例子,Scheme当然也具有易于理解的正式定义。

  • a number of systems have tried to use pure functional languages, or nearly pure ones, like Haskell. 许多系统试图使用纯函数式语言,或者几乎是纯函数式语言,例如Haskell。 There's a fair bit of formal methods work in Haskell. Haskell中有相当多的形式方法可用。

  • Going back 20+ years, there was a short-lived thing for using hand-proof of a formal language which was then rigorously translated into a compiled language. 可以追溯到20多年以前,使用手工语言对正式语言进行校对是短暂的事情,然后将其严格地翻译成编译语言。 Some examples were IBM's Software Cleanroom, ACL, Gypsy, and Rose out of Computational Logic, John McHugh's and my work on trustworthy compilation of C, and my own work on hand-proof for C systems programming. 一些示例包括计算逻辑中的IBM的Software Cleanroom,ACL,Gypsy和Rose,John McHugh以及我从事可信赖的C语言编译的工作,以及我自己有关C系统编程的手防验证工作。 These all got some attention, but none of them made it much into practice. 这些都引起了一定的关注,但没有一个使它付诸实践。

An interesting question to ask, I think, is what would sufficient conditions be to get formal approaches into practice? 我认为,有一个有趣的问题要问,将正式方法付诸实践的充分条件是什么? I'd love to hear some suggestions. 我很想听听一些建议。

You can investigate purely functional languages like Haskell, which are used when one of your requirements is provability . 您可以研究像Haskell这样的纯函数式语言 ,当您的要求之一是可证明性时使用

This is a fun read if you're interested about functional programming languages and pure functional programming languages. 如果您对函数式编程语言和纯函数式编程语言感兴趣,那么是一本有趣的书。

real world uses of such provable languages would be incredibly difficult to write and understand afterwoods. 这种可证明的语言在现实世界中的使用将很难编写和理解。 the business world needs working software, fast. 商业世界需要快速运行的软件。

"provable" languages just dont scale for writing/reading a large project's code base and only seem to work in small and isolated use cases. “可证明的”语言无法扩展用于编写/读取大型项目的代码库,并且似乎仅在小型且孤立的用例中起作用。

Check out Omega . 退房欧米茄

This introduction contains a relatively painless implementation of AVL trees with included correctness proof. 简介包含相对正确的AVL树实现,并带有正确性证明。

I'm involved in two provable languages. 我涉及两种可证明的语言。 The first is the language supported by Perfect Developer, a system for specifying sotfware, refining it and generating code. 第一种是Perfect Developer支持的语言,Perfect Developer是一种用于指定软件,对其进行完善和生成代码的系统。 It's been used for some large systems, including PD itself, and it's taught in a number of universities. 它已用于某些大型系统,包括PD本身,并且在许多大学中都进行过讲授。 The second provable language I'm involved with is a provable subset of MISRA-C, see C/C++ Verification Blog for more. 我涉及的第二种可证明语言是MISRA-C的可证明子集,有关更多信息,请参见C / C ++验证博客

My (controversial) definition of "real-world" in the context of provably-correct code is: 我在可证明正确的代码中对“现实世界”的定义(有争议的)是:

  • It must involve some degree of automation , otherwise you're going to spend far too much time proving and dealing with messy little details, and it's going to be totally impractical (except maybe for spacecraft control software and that sort of thing, for which you might actually want to spend megabucks on meticulous checks). 它必须涉及某种程度的自动化 ,否则您将花费​​太多的时间来证明和处理混乱的小细节,而且这将是完全不切实际的(除了航天器控制软件和诸如此类的东西之外,可能实际上想花一百万美元进行细致的检查)。
  • It must support some degree of functional programming , which helps you write code that is very modular, reusable and easier to reason about. 它必须支持某种程度的功能编程 ,这可以帮助您编写非常模块化,可重用且易于推理的代码。 Obviously functional programming isn't needed for writing or proving Hello World, or a variety of simple programs, but at a certain point, functional programming does become very useful. 显然,编写或证明Hello World或各种简单程序不需要功能编程,但是在某些时候,功能编程确实变得非常有用。
  • While you don't necessarily have to be able to write your code in a mainstream programming language, as an alternative, you should at least be able to machine-translate your code into reasonably efficient code written in a mainstream programming language, in a reliable way. 尽管不必一定要用主流编程语言编写代码,但作为替代,您至少应该能够以可靠的方式将代码机器翻译成用主流编程语言编写的相当有效的代码。道路。

The above are relatively more universal requirements. 以上是比较普遍的要求。 Others, such as the ability to model imperative code, or the ability to prove higher-order functions correct, may be important or essential for some tasks, but not all. 其他功能,例如对命令性代码进行建模的能力或证明高阶函数正确的能力,对于某些任务(但不是全部)可能是重要或必不可少的。

In view of these points, many of the tools listed in this blog post of mine may be useful - although they are nearly all either new and experimental, or unfamiliar to the vast majority of industry programmers. 有鉴于此, 我的博客文章中列出的许多工具可能都是有用的-尽管它们几乎都是新的和试验性的,或者是绝大多数行业程序员都不熟悉的工具。 There are some very mature tools covered there though. 但是这里有一些非常成熟的工具。

Scala is meant to be "real world", so no effort has been made to make it provable. Scala旨在成为“现实世界”,因此未作任何努力使其可证明。 What you can do in Scala is to produce functional code. 您可以在Scala中做的是生成功能代码。 Functional code is much easier to test, which is IMHO a good compromise between "real world" and provability. 功能代码更容易测试,恕我直言,这是“真实世界”与可证明性之间的良好折衷。

EDIT ===== Removed my incorrect ideas about ML being "provable". 编辑=====删除了我关于ML被“证明”的错误想法。

How about Idris and Agda ? 伊德里斯阿格达怎么样? Real world enough? 真实世界够吗?

As a good real life example, there's a project that aims to provide a verified HTTP REST library written in Agda, called Lemmachine: https://github.com/larrytheliquid/Lemmachine 作为一个很好的现实示例,有一个项目旨在提供一个用Agda编写的经过验证的HTTP REST库,称为Lemmachine: https : //github.com/larrytheliquid/Lemmachine

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM