我在编程生涯中相对较晚地遇到Curry-Howard Isomorphism,也许这有助于我对它完全着迷。这意味着对于每个编程概念,在形式逻辑中存在精确的模拟,反之亦然。这是这种类比的“基本”列表,在我的头顶:
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
答案 0 :(得分:32)
由于您明确要求提供最有趣和最模糊的内容:
您可以将C-H扩展到许多有趣的逻辑和逻辑公式,以获得各种各样的对应关系。在这里,我试着把注意力集中在一些比较有趣的事情而不是模糊不清的事情上,再加上一些尚未出现的基本事件。
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
编辑:我建议任何有兴趣了解C-H扩展的人参考:
“模态逻辑的审判重建”http://www.cs.cmu.edu/~fp/papers/mscs00.pdf - 这是一个很好的起点,因为它从第一原则开始,其中大部分旨在让非逻辑学家/语言理论家可以获得。 (我是第二作者,所以我有偏见。)
答案 1 :(得分:25)
你对于不确定的事情有点混乱。虚假性由无人居住的类型表示,根据定义,它不能是非终止的,因为首先不需要评估该类型。
非终止代表矛盾 - 一种不一致的逻辑。然而,不一致的逻辑当然会allow you to prove anything,包括虚假。
忽略不一致性,类型系统通常对应于intuitionistic logic,并且必然是constructivist,这意味着某些经典逻辑片段无法直接表达(如果有的话)。另一方面,这很有用,因为如果一个类型是一个有效的建设性证明,那么这个类型的术语就是构造你已经证明存在的任何东西的方法。
建构主义风格的一个主要特征是双重否定不等同于非否定。事实上,否定在类型系统中很少是原始的,因此我们可以将其表示为暗示错误,例如,not P
变为P -> Falsity
。因此,双重否定将是类型为(P -> Falsity) -> Falsity
的函数,它显然不等同于P
类型的函数。
然而,这有一个有趣的转折!在具有参数多态性的语言中,类型变量的范围涵盖所有可能的类型,包括无人类型,因此在某种意义上,完全多态类型(如∀a. a
)几乎是假的。那么如果我们通过使用多态来编写双重几乎否定呢?我们得到一个如下所示的类型:∀a. (P -> a) -> a
。这相当于P
类型的东西吗? 确实,只是将其应用于身份功能。
但重点是什么?为什么写这样的类型?在编程术语中是否是什么意思?好吧,你可以把它想象成一个已经有某种类型P
的函数,并且需要你给它一个以P
作为参数的函数,整个事物是多态的最终结果类型。从某种意义上说,它代表暂停计算,等待其余的提供。从这个意义上说,这些暂停的计算可以组合在一起,传递,调用,等等。对于一些语言的粉丝来说,这应该开始听起来很熟悉,比如Scheme或Ruby - 因为它意味着双重否定对应于continuation-passing style ,实际上我在上面给出的类型正是哈斯克尔的延续单子。
答案 2 :(得分: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)
,X
和Y
范围内的话语领域(称之为Dom
)和Male :: Dom -> *
。
答案 3 :(得分:14)
function composition | syllogism
答案 4 :(得分:13)
答案 5 :(得分:12)
这是一个有点模糊的,我很惊讶没有提到:“经典”功能反应式编程对应于时态逻辑。
当然,除非你是一位哲学家,数学家或强迫性的函数式程序员,否则这可能会带来更多问题。
所以,首先:什么是功能反应式编程?这是使用时变值的声明性方法。这对于编写用户界面之类的东西很有用,因为来自用户的输入是随时间变化的值。 “经典”FRP有两种基本数据类型:事件和行为。
事件表示仅在离散时间存在的值。击键是一个很好的例子:您可以将键盘输入视为给定时间的角色。然后每个按键只是一对按键的字符和按下的时间。
行为是不断存在但可以不断变化的价值观。鼠标位置就是一个很好的例子:它只是x,y坐标的行为。毕竟,鼠标总是有一个位置,从概念上讲,当你移动鼠标时,这个位置会不断地连续。毕竟,移动鼠标是一个单一的延长动作,而不是一堆不连续的步骤。
什么是时间逻辑?恰当地说,它是一套用于处理随时间量化的命题的逻辑规则。从本质上讲,它通过两个量词扩展了正常的一阶逻辑:□和◇。第一个意思是“总是”:读□φ为“φ始终保持”。第二个是“最终”:◇φ表示“φ最终会保持”。这是一种特殊的modal logic。以下两个定律涉及量词:
□φ ⇔ ¬◇¬φ
◇φ ⇔ ¬□¬φ
因此□和◇以与∀和∃相同的方式彼此双重。
这两个量词对应于FRP中的两种类型。特别是,□对应于行为,◇对应于事件。如果我们考虑这些类型是如何居住的,这应该是有意义的:行为在每个可能的时间居住,而事件只发生一次。
答案 6 :(得分:8)
与延续和双重否定之间的关系相关,呼叫/ cc的类型是Peirce定律http://en.wikipedia.org/wiki/Call-with-current-continuation
C-H通常被称为直觉主义逻辑和程序之间的对应关系。但是,如果我们添加call-with-current-continuation(callCC)运算符(其类型对应于Peirce定律),我们将得到经典逻辑与具有callCC的程序之间的对应关系。
答案 7 :(得分:4)
虽然它不是一个简单的同构,但this discussion of constructive LEM是一个非常有趣的结果。特别是,在结论部分,Oleg Kiselyov讨论了如何使用monad在建构逻辑中得到双重否定消除,类似于从所有命题中区分计算上可判定的命题(LEM在建设性环境中有效)。 monads捕获计算效果的概念是一个古老的概念,但Curry - Howard同构的这个例子有助于将其置于透视中,并有助于得出真正“意味着”的双重否定。
答案 8 :(得分:4)
一流的延续支持允许你表达$ P \ lor \ neg P $。 诀窍是基于这样一个事实,即不调用continuation并使用某个表达式退出等同于使用相同的表达式调用continuation。
有关详细信息,请参阅:http://www.cs.cmu.edu/~rwh/courses/logic/www-old/handouts/callcc.pdf
答案 9 :(得分:4)
2-continuation | Sheffer stoke
n-continuation language | Existential graph
Recursion | Mathematical Induction
有一点很重要,但还没有被调查的是2续(持续2个参数)和Sheffer stroke的关系。在经典逻辑中,Sheffer笔划本身可以形成一个完整的逻辑系统(加上一些非运算符概念)。这意味着熟悉的and
,or
,not
只能使用Sheffer中途或nand
来实现。
这是编程类型对应的一个重要事实,因为它提示可以使用单一类型组合器来形成所有其他类型。
2连续的类型签名是(a,b) -> Void
。通过这种实现,我们可以将1-连续(正常连续)定义为(a,a)
- >无效,产品类型为((a,b)->Void,(a,b)->Void)->Void
,总和类型为((a,a)->Void,(b,b)->Void)->Void
。这给了我们令人印象深刻的表现力。
如果我们进一步挖掘,我们会发现Piece的existential graph等同于一种语言,唯一的数据类型是n-continuation,但我没有看到任何现有的语言都是这种形式。因此,我认为发明一个可能很有趣。