Algorithm 为算法编写证明

Algorithm 为算法编写证明,algorithm,proof,proof-of-correctness,Algorithm,Proof,Proof Of Correctness,我试图比较两种算法。我想我可以试着为他们写一个证明。(我的数学糟透了,所以问题就来了。) 通常在去年的数学课上,我们会被问到这样一个问题:你不会给出太多细节,但有一个数学家社区(数学知识管理MKM),他们开发了支持数学计算机证明的工具。例如,见: 以及最近的会议 我在大学的数学课上(模糊地)记得证明Prims和Kruskals算法——你不会用数学形式来攻击它。取而代之的是,你将已证明的理论用于图表,并将它们结合起来,例如,构建证明 如果你想证明它的复杂性,那么简单地通过算法的工作,它就是O(n

我试图比较两种算法。我想我可以试着为他们写一个证明。(我的数学糟透了,所以问题就来了。)


通常在去年的数学课上,我们会被问到这样一个问题:你不会给出太多细节,但有一个数学家社区(数学知识管理MKM),他们开发了支持数学计算机证明的工具。例如,见:

以及最近的会议


我在大学的数学课上(模糊地)记得证明Prims和Kruskals算法——你不会用数学形式来攻击它。取而代之的是,你将已证明的理论用于图表,并将它们结合起来,例如,构建证明

如果你想证明它的复杂性,那么简单地通过算法的工作,它就是O(n^2)。对于图稀疏的特殊情况有一些优化,可以将其减少到O(nlogn)

我陷入困境的地方是证明prims和Kruskals——我怎样才能把这些算法变成上面的数学形式,这样我才能继续证明


我不认为你能直接做到。相反,证明两者都生成一个MST,然后证明任意两个MST相等(或等效,因为对于某些图,可以有多个MST)。如果两种算法生成的MST显示为等效,则两种算法是等效的

为了证明算法的正确性,您通常必须证明(a)它终止了,(b)它的输出满足您尝试执行的操作的规范。这两个证明与你在问题中提到的代数证明有很大不同。您需要的关键概念是。(这是用来证明的。)

让我们举个例子

为了证明快速排序总是终止,您首先要证明它在输入长度为1时终止。(这是非常正确的。)然后显示,如果它终止于长度为n的输入,那么它将终止于长度为n+1的输入。多亏了归纳法,这足以证明算法对所有输入都终止


为了证明快速排序是正确的,您必须将比较排序规范转换为精确的数学语言。我们希望输出是输入的一部分,这样如果≤ j那么ai≤ aj。证明快速排序的输出是输入的排列是很容易的,因为它从输入开始,只交换元素。证明第二个属性有点棘手,但同样可以使用归纳法。

大多数情况下,证明取决于你手上的问题简单的论证有时就足够了,有时你可能需要严格的证明。我曾经用已经证明的定理的推论和证明来证明我的算法是正确的。但这是一个大学项目。

也许你想尝试一种半自动的证明方法。只是为了追求不同的东西;)例如,如果您有Prim和Kruskal算法的Java规范,最佳地构建在相同的图模型上,您可以使用来证明算法的等价性

关键部分是在动态逻辑中形式化您的证明义务(这是一阶逻辑的扩展,具有Java程序符号执行的类型和方式)。要证明的公式可以匹配以下(粗略)模式:

\forall Graph g\存在树t。
(resultVar1=t)(resultVar2=t)
这表示对于所有图,两个算法都终止,结果是相同的树

若你们很幸运,并且你们的公式(和算法实现)是正确的,那个么KeY可以自动为你们证明这一点。如果没有,您可能需要实例化一些量化的变量,这使得有必要检查前面的证明树

在用KeY证明了这一点之后,您可以高兴地学习到一些东西,或者尝试从KeY证明中重新构造一个手动证明——这可能是一项乏味的任务,因为KeY知道许多特定于Java的规则,这些规则不容易理解。然而,也许你可以做一些事情,比如从KeY用来在证明序列右侧实例化存在量词的术语中提取一个Herbrand析取


嗯,我认为KeY是一个有趣的工具,更多的人应该习惯于使用这样的工具来证明关键的Java代码;)

试试mathoverflow.com。我想你在那里会更幸运。我不认为mathoverflow.com就是为了这个问题。我投票结束这个问题,因为它今天属于。如果你已经证明了Prim或Kruskal的关键算法,我想看看它!我只是不相信任何证据助理都适合做这样的事情。谢谢你分享这个Jason Orendorff(+1)。
\forall Graph g. \exists Tree t.
    (<{KRUSKAL_CODE_HERE}>resultVar1=t) <-> (<{PRIM_CODE_HERE}>resultVar2=t)