Coq:是否有可能证明,如果两个记录不同,那么他们的一个字段是不同的?

时间:2017-10-10 18:05:36

标签: record coq

说你有记录:

Lemma record_difference : forall (e1 e2 : Example),
  e1 <> e2 ->
    (fieldA e1 <> fieldA e2)
    \/
    (fieldB e1 <> fieldB e2).

我们可以证明:

Record

若然,怎么样?

一方面,它看起来是真的,因为e1是由它们的字段绝对定义的。另一方面,我们不知道首先使e2Record 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. 不同的是什么,我们应该如何决定要分离哪一方?

作为比较,请注意,如果记录中只有一个字段,我们可以证明相应的引理:

{{1}}

1 个答案:

答案 0 :(得分:4)

  

另一方面,在不知道首先使e1e2不同的是什么的情况下,我们应该如何决定要分析哪一方?

这正是重点:我们需要弄清楚是什么让两种记录都不同。我们可以通过测试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.

这里,Nat.eq_dec是标准库中的一个函数,它允许我们检查两个自然数是否相等:

Nat.eq_dec : forall n m, {n = m} + {n <> m}.

{P} + {~ P}符号表示一种特殊的布尔值,可以在破坏时为您提供P~ P的证明,具体取决于它所在的一侧。

值得通过这个证据来看看发生了什么。例如,在证明的第三行,执行intros em会导致以下目标。

n1, m1, n2, m2 : nat
He1e2 : {| fieldA := n1; fieldB := m1 |} <> {| fieldA := n2; fieldB := m2 |}
en : n1 = n2
em : m1 = m2
============================
False

如果enem成立,则两条记录必须相等,与He1e2相矛盾。 congruence策略只是指示Coq试图自己解决这个问题。

修改

有趣的是,如果没有可判定的平等,我们可以获得多远。以下类似的陈述可以简单地证明:

forall (A B : Type) (p1 p2 : A * B),
  p1 = p2 <-> fst p1 = fst p2 /\ snd p1 = snd p2.

通过对立,我们得到了

forall (A B : Type) (p1 p2 : A * B),
  p1 <> p2 <-> ~ (fst p1 = fst p2 /\ snd p1 = snd p2).

在这里,我们在没有可判定性假设的情况下陷入困境。 De Morgan的法律允许我们将右侧转换为~ P \/ ~ Q形式的陈述;然而,他们的证据对可判定性有吸引力,这在Coq的建设性逻辑中通常是不可用的。