跳到主要内容

注:这些页面广泛使用了最新的XHTML和CSS标准。在任何符合标准的现代浏览器中,它们都应该看起来很棒。不幸的是,它们在较旧的浏览器(如Netscape 4.x和IE 4.x)中可能看起来很糟糕。此外,许多帖子使用MathML,目前只有Mozilla支持。我最好的建议(你会的感谢当我在网上浏览越来越多使用新标准的网站时,我是要升级到最新版本的浏览器。如果这不可能,考虑转向标准兼容和开源Mozilla公司浏览器。

2021年2月20日

本土化理论(上)

John Baez发布

来宾发帖人克里斯汀·威廉姆斯

本土类型理论是我和Mike Stay写的一篇新论文。我们提出了一种统一的编程语言推理方法:将语言建模为理论,形成预升的范畴,并使用拓扑的内部语言。

语言Λ类别𝒫地形Φ类型系统\mathtt{language}\xrightarrow{\;\Lambda\;}\mathtt{category}\xrightarrow}\;\mathscr{P}\;}\mathtt{topos}\xrightarrow{\;\Phi\;}\mathtt{type\;system}

虽然这些步骤是已知的,但最初的方面只是复合及其在软件中的应用。如果实现得当,我们相信本机类型对虚拟世界非常有用。在这里,我想分享一些我们迄今为止学到的知识。

免费午餐

这篇论文最大的教训是相信约翰·贝兹所说的数学方面。两年来,Mike和我以及Greg Meredith一直在寻找为编程语言生成逻辑的方法;我们尝试了很多方法,但最终解决方案是最简单的。

范畴理论的两个事实免费提供了丰富的结构:

1.每一个类别都嵌入到其前置拓扑中。\文本{1。每个类别都嵌入到它的前置拓扑中。}

2.每个拓扑都有丰富的内部语言。\文本{2。每个拓扑都有丰富的内部语言。}

嵌入保留了极限和指数,因此我们可以将其应用于“高阶理论”。

现在我们来探讨拓扑的语言。有多个视图,并且通常未使用其全部功能。拓扑支持几何逻辑、谓词逻辑,而且相依型理论我们强调后者:依赖类型具有表达性和普遍性,但在数学中未得到充分利用。

拓朴人的语言

我的想法是由这样一个想法形成的:即使是基础也是明确的。实际上,任何语言都可以建模为结构化类别:我发现最全面的参考文献是范畴逻辑与类型理论作者:Bart Jacobs。

逻辑中研究最多的范畴结构可能是地形槽轮的拓扑,即将数据相干地赋给空间的函子,首先应用于代数几何。连续地图(f):X(X)Y(Y)f: X到Y产生反像(f):Sh公司(Y(Y))Sh公司(X(X))f: Sh(Y)至Sh(X)它是保持有限极限的左伴随。这给了几何态射地形,以及几何逻辑(\楔子\存在)作为的语言对地形进行分类.

尽管几何逻辑是通用性的一个重要层次,但拓扑语言更强大。在1965年加利福尼亚州的拉荷亚,萌芽中的范畴理论界承认格罗森迪克的滑轮范畴是基本的逻辑结构,它概括了集合论。基本地形是一个具有有限极限的笛卡尔闭范畴和一个子对象分类器,一个表示谓词和子对象对应关系的对象。

基本拓扑T的语言封装在一对结构中。

谓词fibrationΩT型T型谓词的原因,如子集;\text{谓词fibration}\;\Omega\text{T}\到\text{T}\;\文本{谓词的原因,如子集;}

共染色质纤维ΔT型T型依赖类型的原因,如索引集。\text{余域纤维化}\;\增量\text{T}\到\text{T}\;\text{依赖类型的原因,如索引集。}

谓词逻辑

在整个数学中,我们使用Set的内部谓词逻辑。这是拓扑的典型示例:谓词,如φ(x个)=(x个+5)\varphi(x)=(x+3\geq 5)是一个函数φ:X(X)2={t吨,(f)}\varphi:X\到2=\{t,f\},对应于其理解,真项的子对象{x个X(X)|φ(x个)=t吨}X(X)\{x\ in x\;|\;\varphi(x)=t\}\subseteq x.

任意集合上的谓词X(X)X(X)形成布尔代数P(P)(X(X))=[X(X),2]P(X)=[X,2],按暗示排序。每个功能(f):X(X)Y(Y)f: X到Y给出了一个反向图像 P(P)((f)):P(P)(Y(Y))P(P)(X(X))P(f):P(Y)至P(X)。这定义了一个函子P(P):设置 操作布尔P: 将^{op}\设置为Bool哪一个是第一订单超学说:每个P(P)((f))P(f)有伴随词 (f)P(P)((f)) (f)\存在_f\dashv P(f)\dashv\forall_f表示量化,满足Beck-Chevalley条件。

总之,这种结构形式化了经典的高阶谓词逻辑。大多数公式,例如

x个,:.z(z):.x个<z(z)z(z)<\对于所有x,y:\mathbb{Q}.\;\存在z:\mathbb{Q}。\;x\lt z\楔形z\lt y

(f):Y(Y) X(X).:Y(Y).x个:X(X).(f)(x个)=:X(X) Y(Y).:Y(Y).(f)(())=\对于所有f:Y^X;\所有y:y;\存在x:x\;f(x)=y\右箭头\存在g:x^y\;\所有y:y;f(g(y))=y

可以在Set的逻辑结构中建模。

这个想法相当有名;人们经常谈论拓扑的“米切尔-贝纳布语”。然而,该语言是谓词逻辑简单类型理论,这意味着唯一的类型形成规则是产品和功能。数学中的许多结构不适合这种语言,因为类型通常取决于术语:

国家(n个):={:|n个}\文本{Nat}(n):=\{m:\mathbb{n}\;|\;m\leq n \}

第页:=/x个z(z):.(x个)=z(z)第页\mathbb公司{Z} (p):=\mathbb{Z}/\langle x\sim y\equiv\存在Z:\mathbb{Z}。\;(x-y)=z/cdot p范围

这是通过使用依赖类型扩展谓词逻辑来实现的,将在下一节中进行描述。

因此,我们简要讨论了集合的结构如何允许日常数学中使用的谓词的显式构造。重要的是,这些可以被构建在任何地形中我们由此概括了逻辑的历史概念。

例如,在预处理拓扑中[C类 操作,设置][C^{op},\text{Set}]排除中间派的法则不成立,这是有充分理由的。a的否定筛子,筛子它必然比子集的否定更微妙,因为我们必须排除同态不在其中,而是“预合成”到筛子中的可能性。这将在应用程序帖子中进行更多探索。

依赖型理论

依赖性在数学中普遍存在。什么是幺半群?这是一套M(M)M(M)、和然后操作,e(电子)m、 e(电子)M(M)M(M)、和然后条件,e(电子)m、 e(电子)。大多数对象是在中构造的每一个都取决于以前的。类型理论通常被视为“幻想”,只有在复杂的情况下才有必要,类似于对范畴理论的误解;然而,依赖类型无处不在。

基本思想是使用前映像.依赖于另一类型的项的类型,x个:A类B类(x个):类型x: A\vdash B(x):类型,可以理解为索引集{B类(x个)} x个:A类\{B(x)\}_{x:A},这又表示为一个函数x个:A类.B类(x个)A类\连杆x:A;B(x)至A因此,“依赖于A类A类“是切片类别设置/A类/一个.

“的偏序集A类A类-谓词“位于类别内”A类A类-类型“:理解是注入{x个A类|φ(x个)}A类\{x\在A\;|\;\varphi(x)\}\到A。这是一种退化的依赖类型,其中预映像是真理值而不是集合。因此,我们正在扩展到一个更大的环境,它共享所有相同的结构。切片类别集/A类/A类是对P(P)(A类)P(甲):它的形态是交换三角形,被理解为A类A类-索引函数。

每个功能(f):A类B类f: A\至B给出函子(f) *:f^\ast:设置/B类/B\至设置/A类/A类拉回;这推广了前映像,可以表示为替换:给定第页:S公司B类p: S至B,我们可以形成A类A类-类型

x个:A类(f) *(S公司)(x个)=S公司((f)(x个)):类型.x: A\vdash f^\ast(S)(x)=S(f(x)):\text{Type}。

这个函子有伴随词Σ (f)(f) *Π (f)\Sigma_f\dashv f^\ast\dashv\Pi_f,已调用相依和从属产品:这些是构造依赖类型的强大工具。它们不仅推广了量化,而且还推广了乘积和hom:三重附加词在Set上诱导了伴随co/monad/B类/B类

Σ (f)(f) *=×(f)[(f),]=Π (f)(f) *.\Sigma_f\circ f^\ast=-\times f\dashv[f,-]=\Pi_f\ circ f ^\ast。

这些依赖的产品和功能类型的泛化非常有用。

索引和通过允许第二个坐标的类型取决于第一个坐标中的项来概括产品类型。例如:Σn个:.列表(n个)\西格玛n:\mathbb{n}。\文本{列表}(n)由依赖对组成n个,:列表(n个)\语言n,l:\text{List}(n)语言.

索引乘积通过允许共域的类型取决于域中的项来概括函数类型。例如:ΠS公司:设置.列表(S公司)\Pi S:\text{Set}。列表(S)由相关函数组成λS公司:设置.φ(S公司):列表(S公司)\lambda S:\text{Set}。\varphi(S):列表(S).

看看它们有多自然?我们一直在使用它们,往往没有意识到。简单地通过使用preimage进行索引,我们将产品和函数类型概括为“分支”版本,从而允许我们构建复杂的对象,例如

单体:=ΣM(M):设置.Σ:M(M) 2M(M).Σe(电子):1M(M)...\text{Monoid}:=\Sigma M:\text{Set}。\西格玛m:m^2到m.西格玛e:1到m。。。

...Π(,b条,c(c)):M(M) .((,b条),c(c))=(,(b条,c(c))).Π:M(M).(e(电子),)==(,e(电子)).…\Pi(a,b,c):M^3。m(m(a、b)、c)=m(a,m(b、c))。\Pia:M.M(e,a)=a=M(a,e)。

此丰富的语言位于任何地形。我认为我们几乎没有开始看到它在数学、计算和日常生活中的作用。

所有人一起

拓扑有两个系统,谓词逻辑和依赖类型理论。每个模型都由纤维化,拓扑的函子,其中的前像A类A类A类A类-谓词/A类A类-类型。域中的态射是对“在这些(依赖)类型的变量上下文中,该术语属于这种(依赖)型”形式的判断。

:A类,b条:B类(),,z(z):Z轴()t吨:T型a: a,b:b(a),\点,z:z(y)\灰t:t

通过将谓词转换为类型的理解和将类型转换为谓词的图像分解,这两个fibration被连接起来。这些说明谓词fibration是fibration类型的反射子类。

总之,这形成了全高阶相关型理论地形图。据我所知,这是一种值得称道的拓扑斯的“语言”。这种类型的理论用于证明助手,如Coq和Agda;最终,这种表达性逻辑+依赖类型将在许多编程语言中使用。

结论

本机类型理论为广泛的语言类提供了一个共享的推理框架。我们认为,如果集成到现有系统中,这可能会对软件和系统设计产生重大影响。

在下一篇文章中,我们将探讨为什么这种语言对拓扑如此有用理论上的预升。请让我知道对这篇文章,尤其是论文的任何想法或问题。谢谢您。

发布于2021年2月20日凌晨1:59 UTC

此条目的TrackBack URL:https://golem.ph.utexas.edu/cgi-bin/MT-3.0/dxy-tb.fcgi/3297

16条评论和1条回溯

回复:本土类型理论

嘿,很整洁。

当我试图为分类编程语言找出有意义的语法时,我最初也研究了topos的东西,但数学太难了。

我发现最有帮助的是

http://www.kurims.kyoto-u.ac.jp/~hassei/papers/ctcs95.html

将类型化lambda演算分解为两种分类编程语言

并使用无标签的最终风格。与反身物体的连接也很巧妙!

在伪Coq中

KappaZeta k类(k类):=lam:(k 1 a->k b c)->k b(a->c)应用程序:ka(b->c)->k1b->kac单位:k a 1

kappa:(k1a->kbc)->k(a*b)c升力:k(a*b)c->k 1 a->k b c

我一直知道关于参数化HOAS、索引和拓扑之类的东西有一些抽象的胡说八道,但我缺乏理解的背景知识。

发布人:莫莉,2021年2月20日下午2:03|永久链接|对此的答复

关于:本土类型理论

嗨,莫莉,谢谢你的评论。那篇论文很有趣。

将简单类型的lambda分解为这两个计算,一个用于产品,另一个用于指数——为什么这对于实现更实用?除了笛卡尔闭式之外,它主要是为了扩展我们用于编程的结构化类别吗?

虽然我对过去几十年中的实现领域知之甚少,但我想现在我们可以使用多种类别的内部语言,例如从单体到局部笛卡尔封闭。

无论如何,我同意没有足够的关于范畴逻辑的介绍材料,尤其是从属类型理论。原件是马丁·洛夫; LCCC中的解释是西利(Seely); 现代语义学的概述是Ahrens/Lumsdaine/Voevodsky公司.

我想尝试对范畴理论中的依赖类型做一些轻松的介绍。如果有人推荐了一位优秀的推荐人,请告诉我们。谢谢。

发布人:克里斯汀·威廉姆斯2021年2月22日凌晨3:01|永久链接|对此的答复

回复:本土类型理论

啊,奇怪,我以为我回答了这个。

您可能会对我在GitHub问题上发表的这篇评论感兴趣,因为它更详细地介绍了kappa演算的内容。

https://github.com/jameshaydon/lawvere/issues/9#问题评论-780744651

我认为我钻研这些东西的主要动机是因为它很有趣。但问题是,拥有一种明确的风格,提供了非常直接的对立结构。我还试图弄清楚标签/点的确切含义。共指类型非常奇怪,但可以模糊地认为是延续/异常。我认为它们可能会产生良好的效果,但它们与指数不一致,除非你有复杂的限制。

你可能会认为有一种简单易懂的方法可以在类别和内部语言之间来回切换,但我所指的是“编译到类别”这篇论文,它只涵盖了CCC。

此外,这还远远没有达到任何好的状态,但我试着了解一下我对Coq中的切片和内容的一些直觉。这很混乱,因为这是明确的,我还没有明白。

https://pastebin.com/1LiqT2aT网站

发布人:莫莉,2021年2月27日下午3:05|永久链接|对此的答复

关于:本土类型理论

我对这种东西的实际用途很感兴趣。假设我正在为嵌入式应用程序编写一些C。它如何帮助我从C的形式语义(例如K框架的形式语义)中获得依赖类型理论?

这种东西有用的一个基本先决条件不是某种东西的类型理论描述与实现有很大不同吗?使事物显著不同的一种方法是使其显著简单。因此,C及其所有派生语言(即现在使用的所有编程语言)的基本(非依赖)类型(无论是动态还是静态)都很有用,因为它非常简单,但仍然以一种有用的方式捕获错误。

类型理论描述与实现显著不同的另一种方式是,两者使用相同的语言。数学就是这样:陈述和证明都使用同一种语言。在这种情况下,描述充当摘要:可以选择“忽略细节”。

现在在C语言中,比如在我的嵌入式示例中,我可能实际上正在处理位和字节。也许我从硬件传感器中获取一些字节,进行一些处理,然后发送一些字节。我很难看到我正在做的事情的类型理论描述与实际编写程序有什么本质上的不同;这将是同一件事,只是用不同的语言。因此,我很可能会在类型论描述中引入一个bug(即描述不会表达我希望它表达的内容),就像在正常实现中一样。如果这种类型理论语言比通常用于实现的语言更难理解,为什么不直接使用后者呢?

同样的道理也适用于高级语言,只是这种平衡更微妙。假设我有一个标准的REST API类型。我获取一些输入,对其进行解析,进行一两次数据库调用,进行一些处理,然后将一些内容发送回来。到目前为止,我可能会发现让类型系统具有足够的表达能力,能够以本机方式处理顶级描述是很有用的。但解析和处理的细节是特定于域的:如果一个人表达了他们是什么,那么基本上就像C示例中一样,只是用不同的语言编写一个实现。

有人可能会认为,这种东西的一个更有前途的实际用途更有可能是下面的过程。假设我用普通的C语言编写程序,我在一些正式的机器上运行它,并用Java或Python或任何其他语言获得相同的程序。然而,这里的问题是,Java或Python中的程序将被低估。在C语言中使用数组的地方,我在Java中有很多选项可以选择使用哪种类型。也许我希望在Java应用程序中始终使用不可变结构;我的C算法可能不适合这种情况。在更高抽象级别上使用这些语言的全部目的是朝着相反的方向发展:更快或更安全地编写一些更高级别的代码,然后编译回C(或机器代码,或其他)。这种编译过程基本上是特定于语言的。

我认为数学家特别有罪的一件事是,他们经常完全误解现实世界编程的本质。如果你去Math Overflow或Zulip或其他任何地方,你不需要花很长时间在相关的讨论中,就可以看到有人说出“这样或那样的人或软件应该只使用像Haskell这样体面的语言”这样的断言,并且这会得到相互点头和赞赏。在现实世界的编程中,编程语言所具有的类型系统只是众多因素中的一个方面,通常(并且正确地)远不是最重要或决定性的因素。顺便说一句,这段话并不是对博客文章作者的挖苦,只是我认为这与理解人们在这种讨论中经常存在的文化偏见有关!

发布人:理查德·威廉姆森2021年2月20日11:59 PM|永久链接|对此的答复

关于:本土类型理论

你好,理查德,谢谢你的想法。正如论文中所述,我们的动机是切实可行的,但我们承认,目前应用的问题相当广泛,需要时间和社区参与来阐述。

在为应用程序开发想法时,我当然只有有限的实际编程经验可供借鉴,尽管Mike肯定有经验(希望他能加入讨论)。但是的,这就是为什么我感谢你的评论。

因此,您的主要问题似乎是,“本机”类型如何实际有用?如果类型只是由语言本身生成的,那么我们真正获得了什么?这是合理的。有几个不同的答案。

首先,可以想象我们已经有了足够的基础设施来支持大多数流行语言。当然,当我们从头开始时,本地类型看起来很有趣,因为起初它们就像原始语言一样。但是假设我们已经建立了一个复杂类型的C程序库,它描述了满足某些属性、约束、前置/后置条件等的算法类。然后可以使用这些来查询代码库,例如GitHub。人们可以比较一种算法的现有实现,选择一种并将其应用到您的系统中。

这有意义吗?我认为这取决于我们如何设计和实现本地类型的系统,这将决定它们在实践中的用处。当然,可能在语言的某些方面它不是很有用,或者在某些应用程序中它也没有太大帮助,因为它太特定于域。但这个想法非常广泛,似乎不可避免,我们会找到一些好的应用程序,并进行足够的头脑风暴。

你有机会看一下论文中的例子吗?我们使用并发语言,因为它允许我们为分布式计算提供类型。希望这些能帮助一些人理解我们目前的想法。你提出了一些有趣的例子,尤其是关于翻译的例子。一旦我们开发了语言之间的正式翻译库,原生类型构造的功能性将非常有用。也许我们可以在这方面进行更多的头脑风暴。

谢谢你的想法。数学家通常对真实世界的编程理解有限,这些对话很有帮助。我会告诉迈克阅读你的评论,他也会有更多的话要说。

发布人:克里斯汀·威廉姆斯2021年2月21日12:57 AM|永久链接|对此的答复

回复:本土类型理论

假设我正在为嵌入式应用程序编写一些C。它如何帮助我从C的形式语义(例如K框架的形式语义)中获得依赖类型理论?

脑海中浮现出各种各样的事情。首先是K Framework存在的原因:运行时验证是Rosu的公司,销售基于C的正式语义构建的软件,以检测嵌入式系统中的未定义行为。这些未定义的行为通常表示一个bug,如缓冲区溢出或use-after-free等。

在嵌入式场景中,您通常需要处理中断。这些是中断计算机正常流的异步事件。在80x86中,CPU完成当前指令,将代码段和指令指针推送到堆栈,然后在中断表中查找处理程序的新CS和IP。代码从此处继续。当处理程序完成时,它会从堆栈中弹出旧的CS和IP,并继续从它停止的地方继续。

考虑一个处理程序,它增加一个计数器,以跟踪中断触发的次数。如果处理程序读取值,加上一个值,然后将结果写回,那么它可能会大大低估中断的数量,特别是当中断以正确的间隔触发时:相同的中断可以在读取时间和写入时间之间触发。中断CS:IP的许多副本被推送到堆栈中,每个副本都读取了相同的值;然后当它们完成时,都写回相同的值。锁没有帮助,因为中断处理程序没有线程化;它们是同步的,所以系统会立即死锁。

表示即使在中断时代码也保持不变的属性是本机类型系统可以做到的。

定时攻击被利用来获取乐趣和利润。考虑一个在内存中存储密码的嵌入式系统,然后执行strcmp将您键入的内容与内存中的内容进行比较。当您猜错第一个字符时,它会立即失败,但如果您猜对了,它在测试第二个字符时会运行更长的时间。这将查找密码的复杂性从指数时间降低到线性时间。对RSA的类似定时攻击可能会泄漏解密的密文位,进而可以利用这些密文获取私钥位。

表示代码在与输入无关的恒定时间内运行的属性是本机类型系统可以做到的。

另一个用法是表达橙色书籍风格信息的安全属性,或检查对象功能是否泄漏。

在这种情况下,描述充当摘要:可以选择“忽略细节”。

是的,我们确实需要两个独立的程序员意图表达式,以便编译器相互检查,而将类型系统作为一个简单的摘要是一种合理的方法。

对于本机类型系统,您可以自由选择要忽略的部分,而对于C的内置系统,您必须忽略所有行为信息和大量有关值的信息。

我很可能会在类型理论描述[…]中引入一个bug,就像在普通实现中一样。

本机类型系统如您所愿复杂。您可以编写非常简单的类型或非常有表现力的类型。编译器会找到类型与代码不匹配的地方。

作为用于捕获C++代码中错误的依赖类型的示例,请参见这个整数溢出/下溢错误在原型船长。为了修复这个错误,Kenton Varda使用模板元编程编写了一个类,对非负整数的允许范围进行编码,然后更新了他的代码,在所有地方使用该类。然后,编译器对范围进行静态验证。他写道:

在这个过程中,我发现:

  • 应用程序调用具有无效参数的方法可能会触发多个溢出,但远程攻击者不会触发这些溢出,因为远程攻击者提供了无效的消息数据。我们将在将来更改代码以检查这些问题,但它们不是关键的安全问题。

  • Ben已经报告的溢出(2015-03-02-0)。在我的分析过程中,我故意把这个问题放在一边,以验证Guarded是否会抓住它。

  • 另一个未发现的整数下溢(2015-03-02-1)。

基于这些结果,我得出结论,Guarded实际上可以有效地发现溢出错误,谢天谢地,这些错误在Cap’n Proto的代码中并没有流行。

为什么编程语言不这样做?

任何可以在C++模板中实现的东西显然都可以由编译器直接实现。那么,为什么这么多语言都适合使用模运算或慢任意精度整数呢?

语言甚至可以做我的模板做不到的事情:允许我声明变量之间的关系。例如,我希望能够声明一个其值小于某个数组大小的整数。然后我知道整数是数组的安全索引,无需任何运行时检查。

显然,我不是第一个想到这一点的人。“依赖类型”已经研究了几十年,但我们还没有看到支持它们的实用语言。显然,这些规则有些复杂,尽管从我的角度来看,规则看起来应该足够简单。

[肯顿的引语结束。理查德再次说道:]

假设我有一个标准的REST API类型。

假设您这样做了,并且您的部分请求被转换为SQL查询。通过将后端服务器的操作语义与数据库的语义相结合,可以表示以下属性小鲍比桌子名字不会引起麻烦。

车牌阅读器上的SQL注入攻击

在现实世界的编程中,编程语言所具有的类型系统只是众多因素中的一个方面,通常(并且正确地)远不是最重要或决定性的因素。

当然!

发布人:Mike 2021年2月21日凌晨2:36|永久链接|对此的答复

关于:本土类型理论

显然,[依赖类型]的某些方面很复杂

(-:

发布人:迈克·舒尔曼2021年2月21日上午5:27|永久链接|对此的答复

关于:本土类型理论

一个写得特别好的用例,值得在某处发布,以便于书签和参考。

发布人:jay gray,2021年2月21日上午11:30|永久链接|对此的答复

关于:本土类型理论

谢谢你们的回复!为了保持讨论的重点,我将回答(至少现在)防止类型溢出的问题。

考虑一下下面的例子。

int some_array[100];静态void fill_with_ones(const int entries_to_fill){for(int i=0;i<entries_to_fill;i++){some_array[i]=1;}}int main(int number_of_arguments,char**参数){用ones填充(atoi(参数[1]));}

换句话说:取一些整数x个x个指定为命令行参数,并用填充数组some_arrayx个x个个。如果x个>100x\gt 100.

我没有立即看到基于形式语义/本机类型理论的编译器如何能够在上述代码as-is上运行并检测溢出的可能性。我可以看出,一个人可能需要保证条目到填充100\列克100,编译器可能能够检测到没有给出这样的保证。但如果我们改为:

int main(int number_of_arguments,char**arguments){const int entries_to_fill=atoi(参数[1]);if(条目to_fill>100){系统退出(1);} 用ones填充(atoi(参数[1]));}

也许你说这里的编译器能够理解,保证x个100x\leq 100已给出。但我发现总的来说很难相信。如果不只是使用x个x个直接说,我们先在上面运行了一些复杂的函数?如果这个复杂的函数涉及硬件:假设一段算术或快速傅里叶变换是在我的MCU芯片中执行的,而不是在软件中执行的?至少,您需要在类型理论中手动定义硬件操作。我想,一般来说,用手写会很糟糕;再次,它回到了这样一个观点,即拥有与编写程序本质上相同的类型论描述没有任何好处。

我认为人们可以想出其他类似的场景。例如,如果我输入条目填充为当前年份减去1921,其中当前年份是从系统调用或其他内容中获取的。我的代码今年可以工作,但明年不行。编译器怎么可能决定呢?因为这不仅仅是一个系统调用没有在类型理论中表达的问题:例如,如果我的程序在接下来的100000年中运行,而不是在接下来的100001年中运行的话,编译器阻止我的程序编译是完全不合理的。唯一的解决方法是程序员必须以某种类型理论的方式指定100000年是可以的。

换言之,我认为不可避免的是,不能简单地在现有C代码上运行基于形式语义的编译器。其中一种需要人工干预。这可能就是为什么一个人可以从中做生意;我可以想象,对于一个非平凡的程序来说,能够在其上有效地运行一个正式的编译器仍然是一个耗时(因而成本高昂)的过程。然后,我们回到了当今存在的关于证明检查的基本问题(同伦类型理论在这方面没有取得真正的进展,尽管这是Voevodsky最初的动机之一):这对于普通的程序员/数学家/任何人来说都是不实际的,像以前一样处理问题,并在出现问题时处理问题,这样效率更高(在大多数情况下,显然不可能是在任务关键型的情况下)。

发布人:理查德·威廉姆森2021年3月1日凌晨1:09|永久链接|对此的答复

关于:本土类型理论

我没有立即看到基于形式语义/本机类型理论的编译器如何能够在上述代码as-is上运行并检测溢出的可能性。

尝试将代码与未定义的行为类型统一起来。C规范中有一组有限的地方未定义行为,因此进行案例分析。其中一种情况涉及在数组末尾之后进行写入。这个案例出现在这里。必须满足条件0≤i<100,因此0≤entries_to_fill<101,因此atoi必须返回该范围内的数字,因此参数[1]必须位于该范围的前映像中。

也许你会说,这里的编译器能够理解,已经给出了一个保证,即≤100。但我发现总的来说很难相信。如果我们不是直接使用,而是先在上面运行一些复杂的函数呢?

我们并没有说所有这些类型都可以有效地进行计算,甚至可以判定。语言语义和您试图表达的类型越复杂,编译器就越难证明代码与类型匹配。基本上,操作语义将为Coq生成一系列定义,程序将提供更多定义,然后类型就是您试图证明的关于这些定义的定理。有时它能自动为你证明东西,有时你不得不用它作为证明助手来自己证明。这种体验很像Agda中的编程。

如果这个复杂的功能涉及硬件,比如说,如果一段算术或快速傅里叶变换是在我的MCU芯片中执行的,而不是在软件中执行的呢?至少,您需要在类型理论中手动定义硬件操作。

硬件的语义必须包含在Lawvere理论中。一旦它出现,由此产生的本地类型理论就可以对此进行推理。

我认为人们可以想出其他类似的场景。例如,如果我将entries_to_fill设置为当前年份减去1921,其中当前年份是从系统调用或其他内容中获取的,该怎么办。我的代码今年可以工作,但明年不行。编译器怎么可能决定呢?

像以前一样传播约束,但不是传播到atoi(),而是传播到time()。time_t类型编码1970到2038之间的年份,因此time()必须返回1970到2021之间的年份。由于它可能返回一个大于该值的值,编译器会标记该调用。

据我所知,你的问题归结为“(1)它如何推理语义以外的东西?(2)它如何决定复杂的问题?”

对(1)的回答是,必须有人将其添加到语义中,但它不必完全准确才能发挥作用。例如,为了检查上面的代码,我们不需要知道time()在2038年之前总是增加,我们只需要它的值范围。将其添加到语义中要比建模时钟容易得多。

对于(2),正如我上面所说,我们并不是说所有这些都是自动的。我们的意思是,使用工具将K框架操作语义导入到Coq中,供程序员进行推理,这将非常酷而且有用。

换言之,我认为不可避免的是,不能简单地在现有C代码上运行基于形式语义的编译器。其中一种需要人工干预。这可能就是为什么一个人可以从中做生意;我可以想象,对于一个非平凡的程序来说,能够在其上有效地运行一个正式的编译器仍然是一个耗时(因而成本高昂)的过程。然后,我们回到了当今存在的关于证明检查的基本问题(同伦类型理论在这方面没有取得真正的进展,尽管这是Voevodsky最初的动机之一):这对于普通的程序员/数学家/任何人来说都是不实际的,像以前一样处理问题,并在出现问题时处理问题,这样效率更高(在大多数情况下,显然不可能是在任务关键型的情况下)。

在很大程度上,我同意。现有的编程语言具有如此复杂的语义,因此很难对其进行任何自动操作。然而,由于形式验证在区块链上是一件大事,许多新语言正在被提出,它们的形式语义非常清晰和简单;我认为这是像NTT这样的东西真正闪耀的地方。

另一方面,我认为没有人部署过像比特币矿工这样规模的定理证明器。我可以想象,随着智能合约变得越来越复杂,人们将使用大量GPU进行理论证明和暴力证明。

发布人:Mike 2021年3月2日下午3:00|永久链接|对此的答复

关于:本土类型理论

量子编程语言有什么应用吗?

发布人:马特,2021年2月21日上午12:17|永久链接|对此的答复

关于:本土类型理论

当然。一切都以同样的方式进行;计算机状态的大小是指数级的,重写是单一的。

发布人:Mike 2021年2月21日下午5:03|永久链接|对此的答复

关于:本土类型理论

这就是说,我正在与格雷格·梅雷迪斯(Greg Meredith)合作,将这种结构推广到非拓扑的V富集前置类别,而是使用某种形式的线性逻辑。这种方法可能会有更多类似量子的类型。

发布人:Mike 2021年2月21日下午5:17|永久链接|对此的答复

关于:本土类型理论

在分类理论Zulip聊天中,Morgan Rogers建议我可以从阅读本文的依赖型理论部分中受益(大概还有论文,但我在打开标签一周多之后才读完这篇博客文章……)。我在类型理论中使用的符号方面仍然有点薄弱,所以我希望你不介意回答一些非常基本的问题。

在解释索引和和和和索引乘积之后,你写了一个反问句,“看看它们有多自然?”不幸的是,我还不能用“是”来回答这个问题。List()做什么?依赖类型并没有在使用它的示例之前定义,我无法直观地理解它。因此,示例仍然是不透明的。另一方面,我已经知道什么是monoid,所以我可以从两端来阅读monoid的构建(在解释成更熟悉的术语后),如下所示:

“将一个幺半群作为一个集M,它具有乘法的二进制运算和单位的nullary运算(即一个特定元素)……对于M的任何三元组,乘法都是相联的;对于M的任意元素a,两边的单位元素相乘都会返回该元素a。”

对于您在博客文章中提供的“简单”示例,是否可以提供类似的翻译?

顺便说一句,我对Monoid类型的翻译似乎表明,空的Monoid(M=ö)被排除在外,因为nullary操作需要M的至少一个元素。这也是我翻译之前你写的MonoidType的情况吗,还是我的翻译在这方面不忠实?

发布人:Jason Erbele于2021年3月2日晚上10:00|永久链接|对此的答复

关于:本土类型理论

嗨,杰森,很抱歉,回复晚了。我在这里对相依和和乘积的解释非常有限——我在第2部分.

每当我们构建对象时,我们都会说“首先给我一个X,然后然后根据X给我一些东西”。

所以Σn个:.列表(n个)\西格玛n:\mathbb{n}。列表(n)意思是“首先给我一个号码”n个n个、和然后给我一份长度表n个n个.”(用于制作列表)因此元素是一对,其中第二个坐标依赖于第一个坐标。

类似地ΠS公司:设置.列表(S公司)\Pi S:\mathrm{集合}。列表(S)这意味着“首先给我一套,然后然后给我一个元素列表S公司S公司因此,元素是一个函数,其中的余域取决于参数。

希望这能有所帮助。

发布人:克里斯汀·威廉姆斯2021年3月24日12:55 AM|永久链接|对此的答复

关于:本土类型理论

类似地ΠS公司:设置.列表(S公司)\Pi S:\mathrm{集合}。列表(S),这意味着“首先给我一个集合,然后给我一列元素S公司S公司.”

不会的Π\Pi公司更像是“每当我给予一个集合,给我一个元素列表S公司S公司”?

发布人:迈克·舒尔曼2021年3月24日下午4:12|永久链接|对此的答复
阅读帖子本土化理论(三)
网络日志:n类咖啡馆
摘录:克里斯汀·威廉姆斯的《本土类型理论》第三集。
已跟踪:2021年3月29日5:15 AM

发布新评论