Boolean 为什么逻辑连接词和布尔词在Coq中是分开的?

Boolean 为什么逻辑连接词和布尔词在Coq中是分开的?,boolean,logic,coq,Boolean,Logic,Coq,我来自JavaScript/Ruby编程背景,并习惯于这是真/假的工作原理(在JS中): 然后您可以将这些真/假值与&一起使用,如 var a = true, b = false; a && !b; So和not(以及其他逻辑/布尔运算符)是单个系统的一部分;看起来“逻辑”系统和“布尔”系统是同一个系统 然而,在Coq中,逻辑和布尔是两个独立的东西。为什么会这样?下面的引用/链接演示了如何使用定理将它们联系起来 我们已经看到在Coq的计算(类型)和逻辑(属性)世界中可以找到类似

我来自JavaScript/Ruby编程背景,并习惯于这是真/假的工作原理(在JS中):

然后您可以将这些真/假值与
&
一起使用,如

var a = true, b = false;
a && !b;
So和not(以及其他逻辑/布尔运算符)是单个系统的一部分;看起来“逻辑”系统和“布尔”系统是同一个系统

然而,在Coq中,逻辑和布尔是两个独立的东西。为什么会这样?下面的引用/链接演示了如何使用定理将它们联系起来

我们已经看到在Coq的计算(类型)和逻辑(属性)世界中可以找到类似结构的几个地方。这里还有一个:布尔运算符和B和orb显然类似于逻辑连接词∧ 及∨. 通过以下定理可以更精确地进行类比,这些定理展示了如何将关于andb和orb在某些输入上的行为的知识转化为关于这些输入的命题事实

Theorem andb_prop : ∀b c,
  andb b c = true → b = true ∧ c = true.

本质上,Coq两者都有,因为它们对不同的事物有用:布尔值对应于可以机械检查的事实(即,使用算法),而命题可以表达更多的概念

严格地说,逻辑世界和布尔世界在Coq中是不分开的:布尔世界是逻辑世界的子集。换句话说,每一个可以表述为布尔运算的语句都可以被视为一个逻辑命题(即
Prop
类型的东西):如果
b:bool
表示一个语句,我们可以通过说
b=true
来断言该语句是真的,这是
Prop
类型的

Coq中的逻辑不仅仅是布尔运算,其原因在于前面语句的相反部分并不成立:并非所有逻辑事实都可以被视为布尔运算。换一种方式来说,Ruby和JavaScript等普通编程语言中的布尔值并不是同时包含Coq中的
bool
Prop
,因为
Prop
s可以表达这些语言中布尔值无法表达的东西

为了说明这一点,考虑下面的COQ谓词:

Definition commutative {T} (op : T -> T -> T) : Prop :=
  forall x y, op x y = op y x.
顾名思义,这个谓词断言操作符
op
是可交换的。编程语言中的许多运算符是可交换的:例如,以整数上的乘法和加法为例。事实上,在Coq中,我们可以证明以下陈述(我相信这些是《软件基础》一书中的例子):

现在,试着想想如何用一种更传统的语言来翻译像
交换的
这样的谓词。如果这看起来很困难,那不是偶然的:我们可以证明,我们不能用这些语言编写一个返回布尔值的程序来测试一个操作是否是可交换的。您当然可以编写单元测试来检查这一事实是否适用于特定输入,例如:

2 + 3 == 3 + 2
4 * 5 == 5 * 4
但是,如果您的操作符使用无限多的输入,那么这些单元测试只能覆盖所有可能情况的一小部分。因此,测试总是比完整的形式证明更弱

如果
Prop
s可以表达布尔人所能表达的一切,你可能会想,为什么我们要在Coq中加入布尔人呢。原因是Coq是一种建设性的逻辑,这正是Vinz在评论中所暗示的。这一事实最广为人知的后果是,在Coq中,我们无法证明以下直观原理:

Definition excluded_middle :=
  forall P : Prop, P \/ ~ P.
本质上说,每个命题不是真就是假。“这怎么可能失败?”你可能会问自己。粗略地说,在构造逻辑(特别是Coq)中,每个证明都对应于我们可以执行的算法。特别是,当您在构造性逻辑中证明形式为
a\/B
的语句时,您可以从该证明中提取一个(总是终止的)算法,以回答
a
B
是否成立。因此,如果我们能够证明上述原理,我们就会有一个算法,在给定某个命题的情况下,告诉我们该命题是否有效。然而,可计算性理论表明,由于不可判定性,这在一般情况下是不可能的:如果我们把
P
理解为“程序
P
在输入时停止
x
”,被排除的中间将产生一个不可能存在的决策者

现在,Coq中布尔的有趣之处在于,通过构造它们允许使用排除的中间,因为它们确实对应于我们可以运行的算法。具体而言,我们可以证明以下几点:

Lemma excluded_middle_bool :
  forall b : bool, b = true \/ negb b = true.
Proof. intros b; destruct b; simpl; auto. Qed.
[P>因此,在COQ中,把布尔代数看作命题的一个特例是有用的,因为它们允许其他命题不成立的推理形式,即实例分析。
当然,你可以认为要求每个证明都对应于一个算法是愚蠢的,事实上大多数逻辑都允许排除中间的原则。默认情况下遵循此方法的证明助手示例包括和系统。在这些系统中,我们不必区分布尔值和命题,它们被视为同一事物。例如,伊莎贝尔只有
bool
,没有
Prop
。Coq还允许您通过假设公理来模糊布尔值和命题之间的区别,公理允许您对一般命题进行案例分析。另一方面,在这样的设置中,当您编写一个返回布尔值的函数时,您可能无法获得可以作为算法执行的内容,而在Coq中默认情况下总是这样。

简短回答:并不是所有您可以在Coq中声明的内容都是可证明的(例如,以halt问题为例。您能证明它(正确)或反驳它吗(错)或者你需要一个“灰色”状态来解释这个吗?。这只是解释的一小部分,但它会让你的思想活跃起来:)很有趣,谢谢你的解释
Definition excluded_middle :=
  forall P : Prop, P \/ ~ P.
Lemma excluded_middle_bool :
  forall b : bool, b = true \/ negb b = true.
Proof. intros b; destruct b; simpl; auto. Qed.