从Lambda微积分到汇编语言的一种认证类型保留编译器

从Lambda微积分到汇编语言的一种认证类型保留编译器

我介绍了一个经过认证的编译器,从简单类型的lambda演算到汇编语言。编译器得到了认证,因为它附带了一个机器检查的语义保存证明,由Coq证明助手执行。编译器及其几种中间语言的术语都被赋予了依赖类型,以保证只有类型良好的程序才是可表示的。因此,每个编译器传递的类型保留都没有任何常见类型的重要“证明”。语义保持是基于赋给中间语言的指称语义来证明的。我演示了如何使用类型保护编译器来实现类型导向的证明搜索,从而自动履行大部分证明义务。

软件/证明源代码和文档

我在Projet镓年INRIA Rocquencourt研讨会办公套件PDF格式格式。

我在试图跟进时发现了这个这个帖子.这里采用的依赖型AST和指称语义的方法,以及对其逻辑结论的观察,结果是类型化中间语言和汇编语言、校对代码等,这些都表明我与这项工作它似乎也为勒罗伊的共推式大步骤操作语义,也在Coq中完成。迷人的东西。

评论查看选项

选择您首选的方式显示评论,然后单击“保存设置”激活您的更改。

哇哦

我还没有读过这篇论文(但它现在肯定在我的阅读堆上),我读过幻灯片。非常令人印象深刻。这有一种非常优雅的感觉。

当然,这样的成功确实需要一个明显的结论:为什么我们没有编程支持Coq特性的语言允许所有这些“工作”?如果可以在Coq中使用依赖类型和泛型函数,为什么PL不能具有相同的特性?

但有一点需要注意:外部逻辑。特别是,使用了Coq的Ltac——而Ltac是一种非类型化语言!其他人难道不觉得这很奇怪吗?

<plug>如果你认为Ltac(和Template Haskell)没有键入真的很奇怪,那么你应该计划参加PLMMS工作坊(之前提到过)</插头>

我原则上同意,但。。。

当然,在静态类型的FP世界中,我们所有人一想到要使用像Ltac这样的动态类型语言来编写决策过程,都会退缩。然而,我发现,构造证明确实与构造程序有着根本的不同,而且更难。如果有人设法为战术设计一个允许所有重要内容的类型系统,我仍然不清楚成本效益权衡是否足够好。

我喜欢在Ltac中做一些离谱的事情(从ML程序员的角度来看!),比如在穷尽搜索中使用动态类型错误触发回溯-D类

打字等等

需要明确的是:我目前一直在使用三种语言——MetaOCaml、Haskell和Maple。

当我在做数学或疯狂的泛型编程时,Maple的自由是无与伦比的(动态打字和充分的内省,是的!)。当我认真对待编程时,哈斯克尔。当我在研究生成性编程(主要应用于数学算法)时,MetaOCaml,因为我到处都需要类型。

所以我知道动态类型语言所允许的所有疯狂的东西。在我的一些Maple代码中,我对一些非常疯狂的事情执行动态调度。但经过10年的发展,Haskell和MetaOCaml的类型都变得更好了。但随后我感到沮丧的是,我的代码中的不变量比类型系统允许我编码的不变量多得多。

我认为这是目前正在发展的东西:Ltac是为了证明在ML诞生前几年LISP对ML的影响。一旦人们弄清楚了他们通常是如何写校样的,就会有人想出给(大多数)这些校样一个类型系统的方法。你仍然想用那种疯狂的语言来探索边缘,但大多数时候,用打字机会更好。

优雅的编程语言

好吧,你不能在编程语言中使用它,因为在这种情况下,你无法进行证明!

注:我读过论文,看过研讨会,认识作者:)

从本质上讲,依赖类型的编程依赖于转换规则和依赖模式匹配,如果操作不当(即使用可能不终止的程序),就会导致无法确定的类型检查,这肯定不是您想要的(我不想)。

更糟糕的是,在某些情况下,他被迫使用eq_rec重写对象的类型,这意味着您必须有一个逻辑,可以在类型系统中操作等式等。
同样,你当然可以有一个逻辑和一些自动推论,并依赖它,但在有趣的情况下,你会很快面临不可判定性(如果你有完整的依赖类型),或者你在一个只用于证明这些等式的证明阻抗中工作(提示:Coq)。

所以对我来说,问题是为什么我们不在校对助手中使用与常规编程语言具有相同功能的认证编程语言?我正在攻读博士学位:)

顺便说一句,Ltac的非类型化并不是问题,唯一需要良好类型化和终止的是,所有这些都是战术产生的最终证据,而不是战术本身。

不确定性:真的这么糟糕吗?

…导致无法判定的类型检查,这肯定不是您想要的(我不想)

一、 首先,我不确定是否需要不可判定的类型检查。

我简单的人脑一般无法解决停顿问题,但这种限制从未影响我理解有价值的代码来解决现实世界中的问题的能力。对人类来说,判断绝大多数编写良好的代码的正确性很容易,尽管我们通常在良好文档的帮助下更快地得出正确性结论。因此,我假设机器可以自动生成绝大多数正确或意外错误程序的正确性证明,尽管结果会更快(或只有)得到好的提示。

如果我能说服另一个程序员某些代码是正确的还是错误的,难道我就不能说服一个足智多谋的编译器吗?这可能与通过图灵测试一样困难,但我认为现在排除最终创建这样一个类型检查器的可能性还为时过早。

如果它存在的话,我会很高兴有一个依赖型类型检查器,它使用启发式搜索为世界上最好的计算机科学家至少可以为尽可能多的程序创建打字证明或证明。

是的,这是你想要认证的时候。

我理解我们并没有完全排除这种可能性(Cayenne在推广方面做得很好),但我认为您被程序员的直觉误导了。你说“判断绝大多数写得好的代码的正确性对人类来说很容易”,但(即使我怀疑你的说法)我们在这里想要的只是计算机检查的正确性证明。现在,如果你想进行认证编程,并且允许一些程序不终止(这是类型检查不可判定性的一个主要来源),那么,你已经失败了!你很难使用它并将其出售给他人,因为认证人员想要明确的答案,是或否,而不是可能的答案(可能是_|_,也可能是,也可能不是……一旦你添加了证据搜索,类型检查可能会花费很长时间:)。
认证的关键是准确地知道程序将具有哪些行为,并以可组合的方式进行。如果您在其中抛出非终止函数,则会丢失这两者(请注意,您仍然可以使用Coq设置中的某些特定构造来拥有无限数据类型和无限生产函数)。

关于一般的不可判定性,我同意许多证明都可能通过启发式搜索完成,我认为这很好,但这里我看到了两个独立的问题:一个是检查程序/证明的正确性是否符合规范(也就是打字,必须是可判定的,例如为了安全地重新检查)另一种是通过构建这样的证明来解决正确性条件(使用大脑或计算机的资源,没有时间限制)。

现在,我的观点是,我们将不会有自动定理证明程序来进行我在很长一段时间之前所做的那种证明。不管怎样,正如你所说,如果你使用的理论是不可判定的或足够复杂的,你有时必须“暗示”证明程序/编译器,这是你自己做的部分证明,所以半自动系统对我来说似乎最有希望。

另一个答案

我将总结一下我认为马蒂厄答案中重要的部分。

首先,推理和检查之间有很大的区别。它是检查在Coq中可以判定的已经构造好的证明。我希望您同意,虽然我们希望在如何发现证据方面允许自由,但我们应该能够依靠任何人的能力在事后进行检查。如果进行不可判定的检查,这是不可能的。

确实,Coq证明/类型检查可以由一种算法来决定,这种算法很容易向人类解释,因为它可以检查各种各样的证明。我们只有一个带有一些扩展的依赖型lambda演算!需要的任何替代系统搜索对我来说,检查校样似乎根本不太可取。即使它成功地终止了对实践中出现的所有校样的检查,它也可能需要比只进行传统类型检查的检查器更长的时间。

可决定的检查

在这里我们同意。我当然想对证据进行可判定的检查。

但我也想要舞台表演(比如说,像欧米茄,但有更多的自由度)。事实上,更像AUTOMATH的“望远镜”。

我不想看到的是,我的类型级程序被构造强制终止。为什么我的程序可以分叉,但我的类型不能?虫子就是虫子,有时我想有把虫子放在我想要的地方的自由!但说真的,我更高兴的是,我被迫证明我的程序(无论在什么级别!)都是有意义的,而不是被直接夹在这样一个无法表达的系统中,以至于我甚至无法说出我所知道的是真的。

魔鬼代言人。。。

顺便说一句,Ltac的非类型化并不是问题,唯一需要良好类型化和终止的是,所有这些都是战术产生的最终证据,而不是战术本身。

好吧,让我们换一种说法,同样的观点也反对类型化宏和元编程:只有最后的程序需要良好的类型,而不是所有的宏,等等。

这个有几个问题:

  • 首先,战术最好是打字准确,否则无论你是否意识到,你都会遇到麻烦。。。但这是一种语义上的争论。
  • 你最终会想重用、组合或维护你的战术吗?
  • 调试你的策略怎么样?

我能理解这样的论点,即战术中使用非类型化语言是可以的目前为止,但除非我们确信没有人会用这种语言进行大规模或复杂的“真正”编程,否则开放思想可能是值得的。。。我的直觉是,适用于宏或其他小规模“脚本”语言的所有相同论点也可能在这里适用。

类型化战术

的确,你是对的,就语言工程而言,策略是一个可怕的野兽。我们不知道要检查它们,而且调试支持非常低(至少在Coq中)。

关于类型错误,正如亚当所说,它们有时甚至会有所帮助。我认为这只是因为我们使用战术的方式很糟糕;我们有时会“尝试”战术,因为我们深知大多数时候他们都会失败,但如果取得了进展,那就太好了。在这个意义上,我不认为战术的失败可以与程序的失败相比:这不是一种异常的、意料之外的行为。

在我看来,什么是策略的语义问题也同样重要,但实际上我的意思是目前为止甚至还有一句较弱的话:“这根本不会危及体系的连贯性”。

魔鬼统治!

如果你概述的立场是魔鬼的立场,那么我支持他。[是的,我知道这个表达的意思]。

当我决定不再忍受在Maple中进行元编程时,我四处寻找我的替代方案。C++似乎更糟糕。模板Haskell很酷,但只有1/2的类型。MetaOCaml似乎是唯一可行的选择。这很难开始,但凭借一些经验(以及Oleg的一些帮助和一些语法糖),情况并没有那么糟糕。

无论如何,对于元编程,我相信它是有回报的。而且我没有发现元编程和证明之间有任何显著差异。事实上,柯里·霍华德说。。。

很难做到

这很难开始,但凭借一些经验(以及Oleg的一些帮助和一些语法糖),情况并没有那么糟糕。

任何可以被描述为“令人惊讶地难以入门”的语言都需要Oleg级别的帮助,但要实际使用,这将是一个严重的问题!

请注意,OCaml的语法首先只有它的母亲才会喜欢,所以也许还有希望。。。

然而

然而,关键是,一旦(早期采用者)开发出了“知识体系”,后一种采用者的学习曲线就会大大缩短。我个人认为,大多数代码生成框架应该被少数人用来为大众构建(可维护!)库。

大多数编程语言(包括Java)背后的黑客平均比使用该语言进行应用程序的普通程序员聪明。Haskell和LISP似乎有点不同,因为语言黑客和用户之间的差距低于平均水平。有些语言被明确设计成有很大的差距!