简体   繁体   English

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

[英]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 from e2 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 . 如果enem成立,则两个记录必须相等,与He1e2相矛盾。 The congruence tactic simply instructs Coq to try to figure this out by itself. congruence策略只是指示Coq试图自己解决这个问题。

Edit 编辑

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.

相关问题 如何在一条记录中获取不同记录的两个字段 Mysql - How get two fields of different records in one record Mysql Elm 将两个不同的记录合并为一个大的 - Elm merge two different records into one large one 如何在ms访问中将不同记录合并到同一记录中 - How do I amalgamate different records into the same one in ms access 具有相同字段的两个记录上的模式匹配 - Pattern matching on two records with the same fields 在 oracle 中显示来自两个不同函数的两条记录,而不是在一行中 - Displaying two records from two different functions in oracle instead of in a single row 两个记录中的两个字段在OCaml中具有相同的标签 - Two fields of two records have same label in OCaml haskell具有不同字段名称的记录变体 - haskell variant of records with different field names 如何获取每个类别具有不同限制的类别明智的rendom记录 - how to get category wise rendom records with different limit for every category 可以连接两个使用不同输入记录分隔符的 Perl 脚本吗? - Can one concatenate two Perl scripts which use different input record separators? Algolia:如果将具有不同属性的记录导入索引,会发生什么情况? - Algolia: What happens if I import records, that have different properties, into an index?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM