为什么程序不能被certificate?

为什么计算机程序不能像math声明那样被certificate? mathcertificate是build立在其他certificate上的,这些certificate是由更多的certificate和公理构成的 – 那些真理我们认为是真实的真理。

计算机程序似乎没有这样的结构。 如果你写一个计算机程序,你怎么可以采取以前certificate的作品,并用它们来显示你的程序的真相? 你不能存在。 此外,编程的公理是什么? 该领域的primefaces真理?

上面我没有很好的答案。 但似乎软件不能被certificate,因为它是艺术而不是科学。 你如何certificate毕加索?

certificate是程序。

程序的正式validation是一个巨大的研究领域。 (例如,参见卡内基梅隆的小组 )。

许多复杂的程序已经被validation; 例如,看看这个在Haskell中编写的内核 。

程序绝对可以被certificate是正确的。 糟糕的程序很难certificate。 为了做到这一点,你必须发展这个计划,并携手进行certificate。

由于暂停问题,您无法自动进行certificate。 但是,您可以手动certificate任何陈述或陈述序列的后置条件和先决条件。

您必须阅读Dijsktra的编程学科 。

然后,你必须阅读格里斯的“ 编程科学” 。

那么你就知道如何certificate程序是正确的。

对那些提出不完整的人只是一个小小的评论 – 所有的公理系统都不是这样,只有足够强大的系统。

换句话说,哥德尔certificate了一个足以描述自身的公理系统必然是不完整的。 然而,这并不意味着它是无用的,而且正如其他人所说的那样,在程序certificate上做了各种尝试。

双重的问题(编写程序来检查certificate)也是非常有趣的。

暂停问题仅表明有程序无法validation。 一个更有趣更实际的问题是什么类的程序可以正式validation。 也许每个人关心的程序都可以(理论上)被validation。 实际上,到目前为止,只有非常小的程序被certificate是正确的。

事实上,你可以编写可certificate正确的程序。 例如,微软创build了名为Spec#的C#语言的扩展,其中包括一个自动定理certificate器。 对于java,有ESC / java 。 我敢肯定还有更多的例子。

编辑 :显然spec#不再被开发,但合同工具将成为.NET 4.0的一部分 )

我看到一些海报手摇晃动停止问题或不完整性定理 ,这些定理会阻止程序的自动validation。 这当然是不正确的。 这些问题仅仅告诉我们, 编写不能被certificate是正确或不正确的程序可能的 。 这并不妨碍我们构buildcertificate正确的程序。

如果您对这个话题非常感兴趣,那么首先让我推荐David Gries的“编程科学”,这是一个关于这个话题的经典介绍性工作。

实际上有可能在某种程度上certificate程序是正确的。 你可以写前置条件和后置条件,然后certificate给定一个满足前提条件的状态,执行后的状态将满足后置条件。

然而,棘手的地方在于循环。 对于这些,你还需要find一个循环不variables,并显示正确的终止,你需要find每个循环后剩余的最大迭代次数上限函数。 你也必须能够certificate这个循环每次迭代之后至less会减less一次。

一旦你完成了一个程序,certificate是机械的。 但不幸的是,没有办法自动派生循环的不variables和约束函数。 人类的直觉足以处理小循环的微不足道的情况,但实际上,复杂的程序很快变得难以处理。

首先,你为什么说“程序不能被certificate”?

无论如何,“程序”是什么意思?

如果通过程序你意味着algorithm你不知道克鲁斯卡尔? Dijkstra的? MST? 普里姆的? 二进制search? 归并? DP? 所有这些东西都有math模型来描述他们的行为。

描述。 math并没有解释为什么它只是画出了一幅图画。 我不能向你certificate太阳明天会在东方升起,但是我可以把数据显示在过去一直在做的事情上。

你说:“如果你写一个计算机程序,你怎么能拿出以前已经certificate过的作品,用它来展示你的程序的真实性?你不可能存在”

等待? 你不能? http://en.wikipedia.org/wiki/Algorithm#Algorithmic_analysis

我不能向你展示“真相”我是一个程序,尽pipe我不能告诉你语言上的“真相”。 两者都是我们对世界经验的理解的表征。 不是“真相”。 把所有乱七八糟的东西放在一边,我可以用math的方式向你展示一个合并sortingalgorithm将用O(nlogn)性能对列表中的元素进行sorting,Dijkstra将在加权图上find最短path,或者Euclidalgorithm会find最大两个数字之间的公约数。 最后一个例子中的“我的程序中的真相”也许我会find你两个数字之间最大的约数,你不觉得吗?

通过一个递推方程,我可以向你描述你的斐波那契scheme是如何工作的。

现在,计算机编程是一门艺术吗? 我当然认为这是。 和math一样多。

我不是来自math背景,所以请原谅我的无知,但是“certificate一个程序”是什么意思? 你在certificate什么? 正确性? 正确性是程序必须validation为“正确”的规范。 但是这个规范是由一个人决定的,你如何validation这个规范是正确的呢?

在我看来,程序存在缺陷,因为人们难以expression他们真正想要的东西。 替代文字http://www.processdevelopers.comhttp://img.dovov.comPM_Build_Swing.gif

那么你在certificate什么? 缺less引起的错误?

此外,编程的公理是什么? 该领域的primefaces真理?

我已经开设了一门名为“合同编程”的课程(课程主页: http ://www.daimi.au.dk/KBP2/)。 在这里,我可以推断从课程(和我已经采取的其他课程)

你必须正式(math)定义你的语言的语义。 我们来看一个简单的编程语言; 一个只有全局variables,ints,int数组,算术,if-then-else,while,assign和do-nothing [你可以使用任何主stream语言的一个子集作为这个的“实现”]。

一个执行状态将是一个对列表(variables名称,variables值)。 将“{Q1} S1 {Q2}”读为“执行语句S1将您从执行状态Q1带到状态Q2”。

"if both {Q1} S1 {Q2} and {Q2} S2 {Q3}, then {Q1} S1; S2 {Q3}" 。 也就是说,如果语句S1从状态Q1到Q2,语句S2从Q2到Q3,那么“S1; S2”(S1跟在S2之后)将把你从状态Q1带到状态Q3。

另一个公理是"if {Q1 && e != 0} S1 {Q2} and {Q1 && e == 0} S2 {Q2}, then {Q1} if e then S1 else S2 {Q2}"

现在,稍微改进一点:{}中的Qn实际上是关于状态的陈述,而不是状态自己。

假设M(out,A1,A2)是对两个sorting数组进行合并并将结果存储在外的语句,并且我在下一个示例中使用的所有单词都被正式表示(math)。 然后"{sorted(A1) && sorted(A2)} A := M(A1, A2) {sorted(A) && permutationOf(A, A1 concatened with A2)}"是M正确实现合并algorithm的声明。

可以试着用上面的公理来certificate这一点(可能需要一些其他的公理,你可能需要一个循环)。

我希望这说明了一些certificate程序正确的可能。 相信我:即使看似简单的algorithm,也需要很多工作来certificate它们是正确的。 我知道,我读了很多尝试;-)

[如果你读到这个: 你的介入是好的,这是所有其他的导致我头痛的;-)]

当然他们可以像其他人一样发布。

certificate一个非常小的子程序是正确的,这是一个很好的练习,恕我直言,每一个程序相关学位课程的本科生都应该被要求做。 它使您深入了解如何使您的代码清晰易读,易于维护。

但是,在现实世界中,它的实际使用是有限的。

首先,就像程序有缺陷一样,mathcertificate也是如此。 如何certificatemathcertificate是正确的,没有任何错误? 你不能。 举个反例来说,任何数量的已发表的mathcertificate都有错误发现,有时候几年后。

其次,如果没有事先确定程序应该做什么的明确定义,就不能certificate程序是正确的。 但是程序应该做什么的明确定义是一个程序。 (虽然它可能是某种规范语言的程序,但是你没有编译器)因此,在你能certificate程序是正确的之前,你必须首先有另外一个相当于预先知道的程序是正确的。 所以QED整个事情是徒劳的。

我会推荐追踪Brooks的经典“ No Silver Bullet ”文章。

在这方面有很多研究,正如其他人所说的那样,程序语言中的构造是复杂的,而且在试图validation或certificate任何给定的input时,情况只会变得更糟。

然而,许多语言允许规范,什么input是可接受的(先决条件),并且还允许指定最终结果(后置条件)。

这些语言包括:B,事件B,Ada,Fortran。

当然,还有很多工具可以帮助我们certificate程序的某些特性。 例如,为了certificate死锁的自由,可以通过SPIN来破解他们的程序。

也有很多工具可以帮助我们检测逻辑错误。 这可以通过静态分析(goanna,satabs)或代码的实际执行(gnu valgrind?)来完成。

然而,从开始(规范),实施和部署,没有一个工具真的能够certificate整个程序。 B方法接近,但其实施检查非常薄弱。 (它假定人类在将特殊词翻译成实施方面是不可行的)。


作为一个侧面说明,当使用B方法时,你会经常发现自己从较小的公理构build复杂的certificate。 (其他的穷举定理certificate也是如此)。

他们能。 我花了很多很多时间做一个大学新生做程序正确性certificate。

macros观上不切实际的原因是编写程序的certificate往往比写程序困难得多。 另外,今天的程序员倾向于构build系统,而不是编写函数或程序。

在微观层面上,我有时候会为了个人的function而做精神病,并且倾向于组织我的代码,以便于validation。

有一篇关于航天飞机软件的着名文章。 他们做certificate,或者等价的东西。 这是非常昂贵和耗时的。 validation水平对他们来说可能是必要的,但对于任何types的消费者或商业软件公司来说,用最新的技术,你将会得到一个竞争对手吃的午餐,他们以1%的成本提供99.9%的解决scheme。 没有人会支付5000美元的微软办公室稍微更稳定。

如果你正在寻找信心,那么certificate程序的另一种方法是testing它们。 这是更容易理解,可以自动化。 如上所述,它也允许certificate在math上不可能的那类程序。

最重要的是,没有证据可以代替通过验收testing:*

  • 只是因为一个程序确实做了它所做的事情,并不意味着它做了用户想要的事情。

    • 除非你能certificate它所做的是用户说他们想要的。

      • 然后你必须certificate的是他们真正想要的 ,因为作为一个用户,他们几乎肯定不知道他们想要什么。 等Reductio广告荒唐。

*更不用说单位,覆盖范围,function,集成和所有其他types的testing。

希望这可以帮助你在你的道路上。

这里没有提到的是B – 方法 ,它是一个基于forms方法的系统。 它被用来开发巴黎地下的安全系统。 有一些工具可以支持B和事件B的开发,特别是罗丹 。

你不仅可以certificate程序,你可以让你的计算机构造程序的certificate。 见Coq 。 所以你甚至不必担心在实施过程中犯了错误的可能性。

尽pipe有哥德尔定理 ,那么重要的是什么呢? 你想certificate什么简单的“真理”? 你想从这些真相中得到什么? 虽然我可以吃这些话……实用性在哪里?

程序可以被certificate。 如果用新泽西州的标准ML(SML / NJ)这样的语言来编写它们,这很容易。

你的陈述很广泛,所以它捕捉了很多鱼。

底线是:有些程序绝对可以certificate是正确的。 所有的程序都不能被certificate是正确的。

这里有一个简单的例子,请记住,这个例子与当天销毁集合论的certificate完全相同:编写一个能够确定自身是否正确的程序,如果发现它正确的,则给出一个不正确的答案。

这是哥德尔定理,简单明了。

但是这并不是什么问题,因为我们可以certificate很多scheme。

让我们假设一个纯函数式语言(即Haskell)。 在这样的语言中可以相当干净地考虑副作用。

certificate程序产生正确的结果需要你指定:

  1. 数据types和math集之间的对应关系
  2. Haskell函数和math函数之间的对应关系
  3. 一套公理,规定你可以从别人身上build立什么function,以及math方面的相应build构。

这套规范被称为指称语义 。 他们让你用math来certificate程序的原因。

好消息是,“程序结构”(上面第3点)和“math集结构”是非常相似的(stream行语是topos ,或笛卡尔封闭类 ),所以1 /你在math方面做的certificate将很容易转移到程序化结构2 /您所编写的程序很容易显示在math上是正确的。

阅读暂停问题 (关于certificate程序完成与否的简单程度)。 这个问题从根本上与哥德尔的不完备性定理有关。

一些程序的部分可以被certificate。 例如,静态validation并保证types安全的C#编译器,如果编译成功。 但我怀疑你的问题的核心是要certificate一个程序正确执行。 很多(我不敢说最多的)algorithm可以被certificate是正确的,但是整个程序可能不能被静态certificate,这是由于以下原因:

  • validation要求遍历所有可能的分支(调用,ifs和interupts),这在高级程序代码中具有超立方时间复杂度(因此在合理时间内永远不会完成)。
  • 一些编程技术,无论是通过构build组件还是使用reflection,都无法静态预测代码的执行(即,你不知道另一个程序员将​​如何使用你的库,而且编译器很难预测消费者如何reflection调用function。

而这些只是一些…

如果程序有一个明确的目标和初始假设(忽略哥德尔…)可以certificate。 find所有的素数,x,对于6 <= x <= 10,你的答案是7,可以certificate。 我写了一个播放NIM (我写过的第一个Python程序)的程序,理论上计算机总是在游戏进入电脑可以赢的状态之后获胜。 我没有能够certificate它是真实的,但它是真实的(math上的数字二进制certificate)我相信,除非我在代码中犯了一个错误。 我是否犯了一个错误,不认真,有人可以告诉我这个程序是否可以打败?

有一些math定理已经被计算机代码“certificate”,如四色定理 。 但是有人反对,因为像你说的那样,你能certificate这个计划吗?

此外,编程的公理是什么? 该领域的primefaces真理?

操作码是“primefaces真理”吗? 例如看到…

 mov ax,1 

…程序员可能不是一个公理的断言,除了硬件问题,执行这个语句之后,CPU的ax寄存器现在将包含1

如果你写一个计算机程序,你怎么可以采取以前certificate的作品,并用它们来显示你的程序的真相?

那么“以前的工作”可能就是新程序运行的运行环境。

新scheme可以certificate:除了forms上的certificate,可以通过“检验”和各种forms的“检验”(包括“验收检验”)来certificate。

你如何certificate毕加索?

如果软件更像工业devise或工程而不是艺术,那么更好的问题可能是“你如何certificate一座桥梁或一架飞机?

certificate程序正确只能根据程序的规范来完成; 这是可能的,但昂贵/耗时

一些CASE系统生成的程序比其他程序更适合certificate – 但是,这又依赖于规范的正式语义。

…那么你如何certificate规范是正确的? 对! 随着更多的规格!

我读了一下这个,但是有两个问题。

首先,你不能certificate一些抽象的东西,正确性。 如果事情适当,你可以certificate两个正式的系统是等价的。 你可以certificate一个程序实现了一套规范,通过并行构造certificate和程序是最简单的。 因此,规范必须足够详细,以提供certificate, 因此规范是有效的程序 。 编写一个程序来满足一个目的的问题变成了编写一个程序的正式的详细说明以满足一个目的的问题,而这不一定是一个前进的步骤。

其次,节目很复杂。 那么正确性的certificate也是如此。 如果你写错了一个程序,你肯定可以做一个certificate。 Dijkstra和Gries本质上告诉我,如果我是一个完美的math家,我可以成为一名优秀的程序员。 这里的价值在于certificate和编程是两个有点不同的思维过程,至less在我的经验中我犯了不同的错误。

根据我的经验,certificate程序并不是无用的。 当我正在尝试做某些事情时,我可以正式描述,certificate实现的正确性消除了很多难以发现的错误,主要是把那些愚蠢的错误留下,我可以很容易地在testing中发现错误。 在一个必须生成非常无错代码的项目上,它可以成为一个有用的辅助工具。 它并不适合所有的应用程序,它当然不是银弹。

正如其他人指出的,(一些)scheme确实可以被certificate。

然而,实践中的一个问题是,你首先需要你想要certificate的东西 (即一个假设或定理)。 所以要certificate某个程序的某些东西,首先需要对它应该做什么(例如事前和事后条件)进行正式描述。

换句话说,你需要一个正式的程序规范。 但是,即使是合理的(更不严格的forms)规范已经是软件开发中最难的事情之一。 因此,certificate(真实世界)程序的有趣的事情通常是非常困难的。

然而,有些东西可以(而且已经)更容易forms化(并被certificate)。 如果你至less可以certificate你的程序不会崩溃,那已经是事实了:-)。

顺便说一句,一些编译器警告/错误本质上是一个程序的(简单)certificate。 例如,Java编译器将certificate你永远不会在你的代码中访问一个未初始化的variables(否则会给你一个编译器错误)。

我没有阅读所有的答案,但是我看到的方式,certificate程序是毫无意义的,这就是为什么没有人这样做。

如果你有一个相对较小/中等的项目(比如10K行代码),那么certificate可能也是10K行,如果不是更长的话。

想想看,如果程序可能有bug,certificate也可能有“bug”。 也许你需要一个certificatecertificate!

另外要考虑的是,程序非常非常正式和精确。 你不能得到更严格和正式的,因为程序代码必须由一个非常愚蠢的机器执行。

虽然证据将被人类阅读,所以他们往往不如实际的代码严谨。

你要certificate的唯一的东西是在特定的数据结构上运行的低级algorithm(例如,快速sorting,插入二叉树等)。

这些事情有点复杂,为什么他们工作和/或他们是否会一直工作并不是很明显。 它们也是所有其他软件的基本构build模块。

大多数答案都是关于练习,这没关系:实际上你不关心正式的打样。 但是理论上呢?

程序可以像math声明一样被certificate。 但不是你的意思! 在任何足够强大的框架下,都有math表述(和程序),这是无法certificate的! 看到这里

这里有这么多的噪音,但无论如何我要在风中大喊大叫。

“certificate正确”在不同的语境中有不同的含义。 在正式系统中 ,“certificate正确”意味着一个公式可以从其他已certificate的(或公理的)公式中推导出来。 编程中的“certificate正确”只是显示代码等同于正式的规范。 但是,你如何certificateforms规范正确? 可悲的是,除了通过testing以外,没有办法显示一个规范是没有缺陷的,或者是解决现实世界中的任何问题的方法。

只是我的2美分,增加了有趣的东西已经在那里。

在所有无法certificate的程序中,最常见的是那些执行IO(与世界或用户有不可预知的交互)的程序。 即使是自动化的certificate,有时候也会忘记“已经证实”的程序“在某些物理硬件上运行,而不是模型所描述的理想程序。

另一方面,mathcertificate并不关心世界的大部分。 math的一个反复出现的问题是,如果它描述了什么是真实的。 它每次都会发生像虚数或非欧几里德空间这样的新事物。 那么这个问题就被遗忘了,因为这些新的理论是很好的工具。 就像一个很好的程序一样,它只是工作。