Curry-Howard同构引起的最有趣的等价是什么?


97

在我编程生涯的后期,我遇到了Curry-Howard同构,也许这让我完全被它迷住了。这意味着对于每个编程概念,形式逻辑中都有一个精确的类似物,反之亦然。这是此类比喻的“基本”清单,让我无所适从:

program/definition        | proof
type/declaration          | proposition
inhabited type            | theorem/lemma
function                  | implication
function argument         | hypothesis/antecedent
function result           | conclusion/consequent
function application      | modus ponens
recursion                 | induction
identity function         | tautology
non-terminating function  | absurdity/contradiction
tuple                     | conjunction (and)
disjoint union            | disjunction (or)          -- corrected by Antal S-Z
parametric polymorphism   | universal quantification

那么,我的问题是:同构的一些更有趣/模糊的含义是什么?我不是逻辑学家,所以我敢肯定,我只用这份清单打了水漂。

例如,以下是一些编程概念,我不了解它们的逻辑名称:

currying                  | "((a & b) => c) iff (a => (b => c))"
scope                     | "known theory + hypotheses"

这里是一些我在编程方面还没有完全确定的逻辑概念:

primitive type?           | axiom
set of valid programs?    | theory

编辑:

这是从响应中收集的更多等效项:

function composition      | syllogism                -- from Apocalisp
continuation-passing      | double negation          -- from camccann

封闭〜=公理集
Apocalisp 2010年

+1这个问题以及所有高质量的答案和评论使我在CHI上获得了比我可以从互联网上学到的更多的知识。
Alexandre C.

24
@Paul Nathan:goto | jumping to conclusions
Joey Adams 2010年

我认为所有有效程序的集合都将是一个模型
Daniil 2012年

1
fst / snd | 联合消除,左/右| 分断介绍
Tony Morris

Answers:


33

由于您明确要求最有趣和晦涩的内容:

您可以将CH扩展到许多有趣的逻辑和逻辑公式,以获得种类繁多的对应关系。在这里,我尝试着眼于一些更有趣的主题,而不是晦涩难懂的主题,再加上一些尚未出现的基本主题。

evaluation             | proof normalisation/cut-elimination
variable               | assumption
S K combinators        | axiomatic formulation of logic   
pattern matching       | left-sequent rules 
subtyping              | implicit entailment (not reflected in expressions)
intersection types     | implicit conjunction
union types            | implicit disjunction
open code              | temporal next
closed code            | necessity
effects                | possibility
reachable state        | possible world
monadic metalanguage   | lax logic
non-termination        | truth in an unobservable possible world
distributed programs   | modal logic S5/Hybrid logic
meta variables         | modal assumptions
explicit substitutions | contextual modal necessity
pi-calculus            | linear logic

编辑:我将向有兴趣了解CH扩展知识的任何人推荐参考:

“模态逻辑的判断性重构” http://www.cs.cmu.edu/~fp/papers/mscs00.pdf-这是一个很好的起点,因为它是从首要原理开始的,并且其中很多都旨在非逻辑学家/语言理论家可以访问的。(尽管我是第二作者,所以我有偏见。)


感谢您提供了一些比较简单的例子(这确实是原始问题的精神),尽管我承认其中有几个已经浮出水面了……“必要性”和“可能性”这两个术语是否在逻辑上被精确定义?它们如何转换为计算等效项?
汤姆·克罗基特

2
我可以针对每一种都指向已发表的论文,因此可以对它们进行精确定义。模态逻辑受到广泛研究(自亚里斯多德以来),并涉及不同的真理模式-“ A必定为真”表示“在每个可能的世界中A为真”,而“ A可能为真”表示“ A在一个可能的世界中为真” 。您可以证明诸如“((必要时(A-> B),可能还有A)->可能B”)之类的东西。模态推理规则像在CH中一样,直接产生表达式的构造,类型和归约规则。参见:en.wikipedia.org/wiki/Modal_logiccs.cmu.edu/~fp/papers/mscs00.pdf
RD1

2
@pelotom:您可能想阅读一些有关其他逻辑的知识。普通的经典逻辑在这种情况下通常没有用-我在回答中提到了直觉逻辑,但是模态线性逻辑甚至“更奇怪”,但也确实很棒。
CA McCann

1
感谢您的指点,听起来我需要做一些阅读工作!
汤姆·克罗基特

2
@ RD1:您认为这很糟糕,我在Haskell中花费了很多时间,以至于我必须先将谓词逻辑的公式转化为类型签名,然后再将它们有意义。:(且不说排中,并开始这样的法律似乎让人有些困惑,也许可疑。
CA麦肯

26

您正在使有关非终止的事情有些混乱。虚假性由无人居住的类型表示,根据定义,这种类型不能是非终止的,因为首先不需要评估该类型。

不终止代表矛盾 -矛盾的逻辑。逻辑不一致当然会允许您证明 任何事情,包括虚假事实。

忽略不一致的地方,类型系统通常对应于直觉逻辑,并且必然是构造主义者,这意味着某些经典逻辑片根本无法直接表达。另一方面,这很有用,因为如果类型是有效的构造证明,那么该类型的术语就是构造您已经证明存在的任何方法

建构主义风味的一个主要特征是双重否定不等于非否定。实际上,否定在类型系统中很少是原始的,因此我们可以将其表示为暗示虚假,例如not P变为P -> Falsity。因此,双重否定将是具有类型的函数(P -> Falsity) -> Falsity,这显然不等同于正义类型P

但是,这有一个有趣的转折!在具有参数多态性的语言中,类型变量的范围涵盖所有可能的类型,包括无人居住的类型,因此从∀a. a某种意义上来说,全多态类型在某种意义上几乎是错误的。那么,如果我们使用多态来写双倍几乎是负数呢?我们得到一个看起来像这样的类型:∀a. (P -> a) -> a。那等于类型的东西P吗?确实是,仅将其应用于身份功能。

但是有什么意义呢?为什么要写这样的类型?这对编程而言意味着什么吗?好吧,您可以将其视为一个已在P某处具有某种类型的函数的函数,并且需要您为其提供一个P作为参数的函数,而整个函数在最终结果类型中都是多态的。从某种意义上讲,它表示已暂停计算,正在等待其余的操作提供。从这个意义上讲,这些暂停的计算可以组合在一起,传递,调用等等。对于某些语言(例如Scheme或Ruby)的爱好者来说,这应该开始听起来很熟悉-因为这意味着双重否定对应于延续传递样式,实际上我在上面给出的类型恰好就是Haskell中的延续monad。


感谢您的更正,我删除了“虚假”作为非终止的同义词。+1表示否定<=> CPS!
汤姆·克罗基特

我不太理解将¬p表示为的直觉P -> Falsity。我知道为什么它能工作(¬p≡p→⊥),但是我没有得到代码版本。 P -> ⊥应该在什么时候P不应该有人居住,对吗?但是不应该总是有人居住吗?或实际上永远不可能,因为您无法返回的实例?我不太明白它的条件。这里的直觉是什么?
Antal Spector-Zabusky 2010年

1
@Antal SZ:直觉当然是直觉逻辑!但是,是的,实际上编写这样的函数很困难。我在您的个人资料中看到您了解Haskell,所以也许您在考虑代数数据类型和模式匹配?考虑到一个无人居住的类型必须没有构造函数,因此,任何模式都不能与之匹配。您必须编写没有主体的“函数”,这不是合法的Haskell。实际上,据我所知,如果不使用运行时异常或不终止,就无法在Haskell中编写取反类型的术语。
CA McCann 2010年

1
@Antal SZ:另一方面,如果等效逻辑是一致的,则所有功能必须是合计的,例如,所有模式匹配都必须是详尽的。因此,为了编写没有模式的函数,参数类型必须没有构造函数,例如,无人居住。因此,只有在无论据的情况下,这种功能才是合法的,因此也就属于其自身的类型。因此,功能P -> Falsity等同于P错误。
CA McCann 2010年

啊哈,我想我明白了。我一直在娱乐的版本类似于f x = x,可以在iff实例化P = ⊥,但是显然不够通用。因此,想法是要返回无值类型,则不需要任何主体。但是对于要定义的功能和总体功能,您不需要任何情况,因此,如果P无人居住,一切都会进行吗?有点古怪,但是我想我知道了。这似乎与我对Xor类型的定义产生了奇怪的相互作用……我必须考虑一下。谢谢!
Antal Spector-Zabusky 2010年

15

您的图表不太正确;在许多情况下,您将类型与术语混淆了。

function type              implication
function                   proof of implication
function argument          proof of hypothesis
function result            proof of conclusion
function application RULE  modus ponens
recursion                  n/a [1]
structural induction       fold (foldr for lists)
mathematical induction     fold for naturals (data N = Z | S N)
identity function          proof of A -> A, for all A
non-terminating function   n/a [2]
tuple                      normal proof of conjunction
sum                        disjunction
n/a [3]                    first-order universal quantification
parametric polymorphism    second-order universal quantification
currying                   (A,B) -> C -||- A -> (B -> C), for all A,B,C
primitive type             axiom
types of typeable terms    theory
function composition       syllogism
substitution               cut rule
value                      normal proof

[1]图灵完备的功能语言的逻辑是不一致的。递归在一致的理论中没有对应关系。在不一致的逻辑/不可靠的证明理论中,您可以称其为导致不一致/不健全的规则。

[2]同样,这是完整性的结果。如果逻辑是一致的,这将是反定理的证明-因此,它不存在。

[3]在函数式语言中并不存在,因为它们会忽略一阶逻辑特征:所有量化和参数化均通过公式完成。如果您具有一阶特征,则除了*,等之外,还有其他种类* -> *。话语领域的要素。例如,在Father(X,Y) :- Parent(X,Y), Male(X)XY范围在话语(称它为的域Dom),和Male :: Dom -> *


[1]-是的,我应该更具体一些。我的意思是“结构递归”,而不是无约束递归,我想它与“折叠”相同。[3]-它确实以依赖类型的语言存在
Tom Crockett 2010年

[1]事实是,如果递归函数调用(惯用方式)没有导致程序不终止,则赋予这些调用或环境的参数(假设)必须在这些调用之间不同。因此,递归只是多次应用相同的定理。如果有什么特别的地方,通常是增加/减少数字(归纳步骤)并检查一个存在的情况(基本情况),这对应于-数学归纳法。
Earth Engine

我非常喜欢这张图表,但是我不会说“ n / a”,因为一致的逻辑不是唯一的逻辑,就像终止程序不是唯一的程序一样。一个非终止函数将对应一个“循环参数”,并且很好地说明了Curry-Howard同构性:“跟随”一个循环参数会使您陷入无休止的循环。
乔伊·亚当斯


13

我真的很喜欢这个问题。我不了解很多,但是我确实有几件事(在Wikipedia文章的帮助下,该文章有一些整洁的表格,本身就是这样):

  1. 我认为求和类型/联合类型(例如 data Either a b = Left a | Right b)等同于包含式析取。而且,尽管我对Curry-Howard不太熟悉,但我认为这证明了这一点。考虑以下功能:

    andImpliesOr :: (a,b) -> Either a b
    andImpliesOr (a,_) = Left a
    

    如果我理解正确的事情,类型说(  ∧  b)→(  ★  b)和定义说,这是真的,哪里★或者是包容还是排斥,或取其Either代表。您具有Either排他或or;然而,(一个  ∧  b)↛(一个  ⊕  b)。例如,⊤but but but,但⊤⊕⊥⊥和⊤↛。换句话说,如果ab都为真,则假设为真,但结论为假,因此该含意必须为假。然而,很明显,(一个  ∧  b)→(一个  ∨ b),因为如果ab都为真,则至少一个为真。因此,如果有区别的工会是某种形式的分离,那么它们一定是包容性的多样性。我认为这可以作为证明,但是我很乐意不屑一顾。

  2. 同样,将重言式和荒谬性分别定义为身份函数和非终止函数的定义有些偏离。真正的公式由单位类型表示,单位类型是仅具有一个元素(data ⊤ = ⊤通常为拼写()和/或Unit在函数式编程语言中为;)的类型。这是有道理的:由于可以确保一定类型的人居住,并且因为只有一个可能的居民,所以它必须为真。身份函数只是表示a  →  a的特定重言式。

    您对非终止函数的评论取决于您的确切含义。Curry-Howard在类型系统上起作用,但未终止不在那里编码。根据Wikipedia的说法,处理非终止是一个问题,因为添加非终止会产生不一致的逻辑(例如,我可以wrong :: a -> b通过定义wrong x = wrong x,从而“证明” a  →  b对于任何ab)。如果这就是您所说的“荒谬”,那么您是正确的。相反,如果您的意思是错误的陈述,那么您想要的是任何无人居住的类型,例如data ⊥—也就是说,没有任何构造方法的数据类型。这确保了它根本没有任何值,因此必须是无人居住的,这等效于false。我认为您可能也可以使用a -> b,因为如果我们禁止使用非终止函数,那么这也是无人居住的,但我不确定100%。

  3. 维基百科说,根据您对Curry-Howard的解释方式,公理以两种不同的方式编码:在组合器中或在变量中。我认为组合器视图意味着默认情况下,给我们的原始函数对我们可以说的东西进行编码(类似于由于功能应用程序是原始的,所以方法是一种公理)。而且我认为变量视图实际上可能意味着相同的东西-毕竟组合器只是全局变量,它们是特定的函数。至于原始类型:如果我正确地考虑了这一点,那么我认为原始类型就是实体,即我们试图证明事物的原始对象。

  4. 按照我的逻辑和语义类,事实上,(  ∧  b)→  c ^  ≡   →(b  →  c ^)(也即b  →(  →  C ^))被称为出口等价定律,至少在自然演绎证明。当时我没有注意到它只是在发脾气-我希望我有,因为那太酷了!

  5. 虽然我们现在有一种表示包容性析取的方法,但是我们没有一种表示独占品种的方法。我们应该能够使用异或的定义来表示它:一个  ⊕  b  ≡(  ∨  b)∧¬(  ∧  b)。我不知道该怎么写否定,但我知道¬ p  ≡  p  →⊥,都蕴涵和谎言很容易。因此,我们应该能够通过以下方式代表排他性的析取关系:

    data ⊥
    data Xor a b = Xor (Either a b) ((a,b) -> ⊥)
    

    这定义为没有值的空类型,对应于虚假;Xor然后定义为包含两个(Either一个或一个b)和一个函数(蕴涵从)(A,B) )至底部类型()。 但是,我不知道这意味着什么。编辑1:现在,请看下一段!) 由于没有类型的值(a,b) -> ⊥(在那儿?),所以我无法理解程序中的含义。有谁知道考虑这个定义或另一个定义的更好的方法?编辑1:是,camccann。)

    编辑1:感谢camccann的回答(更具体地说,他留下的评论可以帮助我),我想我知道这里发生了什么。要构造type的值Xor a b,您需要提供两件事。首先,证明存在ab作为第一个论点的元素;即a Left a或a Right b。第二,一个证明,有没有这两种类型的元件ab-换句话说,即证明(a,b)无人居住-作为第二个参数。既然你只能将能写从功能(a,b) -> ⊥如果(a,b)无人居住,这是什么意思为要这样呢?这意味着类型对象的某些部分(a,b)无法建造;换句话说,至少有一个,也可能两者的ab无人居住的!在这种情况下,如果我们正在考虑模式匹配,那么就不可能在这样的元组上进行模式匹配:假设这b是无人居住的,那么我们写什么可以匹配该元组的第二部分?因此,我们无法对其进行模式匹配,这可能有助于您了解为什么使它无人居住。现在,拥有不带任何参数的总计函数的唯一方法(因为(a,b)无人值守,这是必须的),结果也必须是无人值守的类型-如果我们从模式匹配的角度考虑这一点,这意味着即使函数没有大小写,也没有可能的主体 它可能有一个,所以一切正常。

我想其中很多是(希望)即时进行大声/证明,但我希望它会有用。我真的推荐Wikipedia文章;我没有详细阅读它,但是它的表是一个非常不错的摘要,而且非常详尽。


1
+1指出“要么包含”,要么“包含”。请注意,(任一aa)是一个定理(对于所有a)。
Apocalisp 2010年

问题重新。2(b):唯一居住者为非终结者的函数类型与无居住者的函数类型之间有什么区别?例如,如果我声明一个没有构造函数的类型B,然后像这样定义一个函数A-> B:fun(a:A):B:= f(a)这将在很多语言中进行类型检查,即使它是不可能返回B。因此,该函数在某种意义上是“有人居住的”,但它的“居民”却是荒谬的……因此,它根本不是真正的有人居住的。希望这有意义:)
Tom Crockett 2010年

3
底部不是证明。“假设不可知和不确定的事物应该包含并确定,这是荒谬而不可能的。” -亚里士多德
Apocalisp

2
@Tom:只是为了让大家理解不终止的含义,如果逻辑一致,则所有程序都将终止。不终止仅发生在表示不一致逻辑的类型系统中,或等效地出现在图灵完备语言的类型系统中。
CA McCann 2010年

1
Apocalisp: Either a a不应该是一个定理:Either ⊥ ⊥仍然无人居住。 汤姆:正如坎肯所说,一致性意味着终止。因此,一致的类型系统不允许您表达f :: a -> b,因此该类型不会有人居住;一个不一致的类型系统有一个该类型的居民,但不会终止。 camccann:是否存在不一致的类型系统,这些系统不是图灵完备的,而是占据了层次结构中的某些中间点?还是最后一步(添加通用递归或其他方法)完全等同于不一致?
Antal Spector-Zabusky 2010年

12

这是一个有点晦涩的,令我惊讶的是没有提早提出:“经典”功能反应式编程对应于时间逻辑。

当然,除非您是哲学家,数学家或痴迷函数式程序员,否则可能会提出其他几个问题。

那么,首先,什么是函数式反应式编程?这是一种使用时变值的声明方式。这对于编写诸如用户界面之类的东西很有用,因为来自用户的输入是随时间变化的值。“经典” FRP具有两种基本数据类型:事件和行为。

事件表示仅在离散时间存在的值。击键就是一个很好的例子:您可以将键盘上的输入视为给定时间的字符。这样,每次按键都只是一对与按键的字符和按键时间对的按键。

行为是不断存在但可以不断变化的价值。鼠标位置就是一个很好的例子:它只是x,y坐标的行为。毕竟,鼠标始终具有位置,并且从概念上讲,此位置在移动鼠标时会不断变化。毕竟,移动鼠标只是一个长时间的动作,而不是一堆离散的步骤。

什么是时间逻辑?足够适当的是,这是一组逻辑规则,用于处理随时间推移量化的命题。本质上,它使用两个量词扩展了正常的一阶逻辑:□和◇。第一个意思是“总是”:将□φ读作“φ始终成立”。第二个是“最终”:◇φ表示“φ最终将保持”。这是一种特殊的模态逻辑。以下两个定律与量词相关:

□φ ⇔ ¬◇¬φ
◇φ ⇔ ¬□¬φ

因此,□和◇以与∀和same相同的方式彼此对偶。

这两个量词对应于FRP中的两种类型。特别地,□对应于行为,◇对应于事件。如果我们考虑如何居住这些类型,这应该是有道理的:在每个可能的时间都有一种行为,而一个事件只会发生一次。



4

虽然这不是一个简单的同构,但是关于构造性LEM的讨论是非常有趣的结果。特别是,在结论部分中,Oleg Kiselyov讨论了如何在构造逻辑中使用monad消除双重否定与从所有主张中区分出可计算的命题(对于LEM在构造条件下有效)相似。关于monad捕获计算效果的概念是一个古老的概念,但是Curry-Howard同构的这种情况有助于将其视为透视图,并有助于弄清双重否定的真正含义。



4
2-continuation           | Sheffer stoke
n-continuation language  | Existential graph
Recursion                | Mathematical Induction

重要但尚未研究的一件事是2连续(采用2个参数的连续)与Sheffer冲程的关系。在经典逻辑中,Sheffer笔划本身可以形成一个完整的逻辑系统(加上一些非运算符的概念)。这意味着大家熟悉的andornot可以仅使用谢弗行程或实施nand

这是其编程类型对应的重要事实,因为它提示可以使用单个类型组合器来形成所有其他类型。

2连续的类型签名为(a,b) -> Void。通过此实现,我们可以将1-continuation(正常延续)定义为(a,a)-> Void,乘积类型为((a,b)->Void,(a,b)->Void)->Void,总和类型为((a,a)->Void,(b,b)->Void)->Void。这使我们印象深刻。

如果进一步研究,我们会发现Piece的存在图等效于唯一数据类型为n-continuation的语言,但是我没有看到任何现有的语言都采用这种形式。因此,我认为发明一个可能会很有趣。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.