[英]Coq: Is it possible to prove that, if two records are different, then one of their fields is different?
Say you have a record: 说你有一个记录:
Record Example := {
fieldA : nat;
fieldB : nat
}.
Can we prove: 我们可以证明:
Lemma record_difference : forall (e1 e2 : Example),
e1 <> e2 ->
(fieldA e1 <> fieldA e2)
\/
(fieldB e1 <> fieldB e2).
If so, how? 如果是这样,怎么样?
On the one hand, it looks true, since Record
s are absolutely defined by their fields. 一方面,它看起来是真的,因为
Record
s绝对是由它们的字段定义的。 On the other, without knowing what made e1
different from e2
in the first place, how are we supposed to decide which side of the disjunction to prove? 另一方面,我们不知道
e1
首先与e2
什么不同,我们应该如何决定分离的哪一方要证明?
As a comparison, note that if there is only one field in the record, we are able to prove the respective lemma: 作为比较,请注意,如果记录中只有一个字段,我们可以证明相应的引理:
Record SmallExample := {
field : nat
}.
Lemma record_dif_small : forall (e1 e2 : SmallExample),
e1 <> e2 -> field e1 <> field e2.
Proof.
unfold not; intros; apply H.
destruct e1; destruct e2; simpl in H0.
f_equal; auto.
Qed.
On the other, without knowing what made
e1
different frome2
in the first place, how are we supposed to decide which side of the disjunction to prove?另一方面,我们不知道
e1
首先与e2
什么不同,我们应该如何决定分离的哪一方要证明?
That is precisely the point: we need to figure out what makes both records different. 这正是重点:我们需要弄清楚两种记录的不同之处。 We can do this by testing whether
fieldA e1 = fieldA e2
. 我们可以通过测试
fieldA e1 = fieldA e2
来做到这一点。
Require Import Coq.Arith.PeanoNat.
Record Example := {
fieldA : nat;
fieldB : nat
}.
Lemma record_difference : forall (e1 e2 : Example),
e1 <> e2 ->
(fieldA e1 <> fieldA e2)
\/
(fieldB e1 <> fieldB e2).
Proof.
intros [n1 m1] [n2 m2] He1e2; simpl.
destruct (Nat.eq_dec n1 n2) as [en|nen]; try now left.
right. intros em. congruence.
Qed.
Here, Nat.eq_dec
is a function from the standard library that allows us to check whether two natural numbers are equal: 这里,
Nat.eq_dec
是标准库中的一个函数,它允许我们检查两个自然数是否相等:
Nat.eq_dec : forall n m, {n = m} + {n <> m}.
The {P} + {~ P}
notation denotes a special kind of boolean that gives you a proof of P
or ~ P
when destructed, depending on which side it lies on. {P} + {~ P}
表示法表示一种特殊的布尔值,它在破坏时为您提供P
或~ P
的证明,具体取决于它所在的一侧。
It is worth stepping through this proof to see what is going on. 值得通过这个证据来看看发生了什么。 On the third line of the proof, for instance, executing
intros em
leads to the following goal. 例如,在证明的第三行,执行
intros em
会导致以下目标。
n1, m1, n2, m2 : nat
He1e2 : {| fieldA := n1; fieldB := m1 |} <> {| fieldA := n2; fieldB := m2 |}
en : n1 = n2
em : m1 = m2
============================
False
If en
and em
hold, then the two records must be equal, contradicting He1e2
. 如果
en
和em
成立,则两个记录必须相等,与He1e2
相矛盾。 The congruence
tactic simply instructs Coq to try to figure this out by itself. congruence
策略只是指示Coq试图自己解决这个问题。
It is interesting to see how far one can get without decidable equality. 有趣的是,如果没有可判定的平等,我们可以获得多远。 The following similar statement can be proved trivially:
以下类似的陈述可以简单地证明:
forall (A B : Type) (p1 p2 : A * B),
p1 = p2 <-> fst p1 = fst p2 /\ snd p1 = snd p2.
By contraposition, we get 通过对立,我们得到了
forall (A B : Type) (p1 p2 : A * B),
p1 <> p2 <-> ~ (fst p1 = fst p2 /\ snd p1 = snd p2).
It is here that we get stuck without a decidability assumption. 正是在这里,我们陷入了没有可判定性假设的困境。 De Morgan's laws would allow us to convert the right-hand side to a statement of the form
~ P \\/ ~ Q
; De Morgan的定律允许我们将右侧转换为形式
~ P \\/ ~ Q
的陈述; however, their proof appeals to decidability, which is not generally available in Coq's constructive logic. 然而,他们的证据对可判定性有吸引力,这在Coq的建设性逻辑中通常是不可用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.